aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/proguard.flags8
-rw-r--r--java/res/anim/alt_code_key_while_typing_fadein.xml3
-rw-r--r--java/res/anim/alt_code_key_while_typing_fadeout.xml3
-rw-r--r--java/res/anim/language_on_spacebar_fadeout.xml5
-rw-r--r--java/res/values-fr/donottranslate-config.xml23
-rw-r--r--java/res/values-land/dimens.xml6
-rw-r--r--java/res/values-land/keyboard-heights.xml34
-rw-r--r--java/res/values-sw600dp-land/dimens.xml7
-rw-r--r--java/res/values-sw600dp-land/keyboard-heights.xml28
-rw-r--r--java/res/values-sw600dp/dimens.xml7
-rw-r--r--java/res/values-sw600dp/keyboard-heights.xml28
-rw-r--r--java/res/values-sw768dp-land/dimens.xml6
-rw-r--r--java/res/values-sw768dp-land/keyboard-heights.xml28
-rw-r--r--java/res/values-sw768dp/dimens.xml6
-rw-r--r--java/res/values-sw768dp/keyboard-heights.xml28
-rw-r--r--java/res/values/attrs.xml6
-rw-r--r--java/res/values/config.xml1
-rw-r--r--java/res/values/dimens.xml6
-rw-r--r--java/res/values/donottranslate-config.xml1
-rw-r--r--java/res/values/keyboard-heights.xml34
-rw-r--r--java/res/values/styles.xml2
-rw-r--r--java/res/xml-sw600dp-land/kbd_thai.xml28
-rw-r--r--java/res/xml-sw600dp/kbd_thai.xml28
-rw-r--r--java/res/xml-sw600dp/rowkeys_thai1.xml97
-rw-r--r--java/res/xml-sw600dp/rowkeys_thai2.xml108
-rw-r--r--java/res/xml-sw600dp/rowkeys_thai3.xml97
-rw-r--r--java/res/xml-sw600dp/rowkeys_thai4.xml89
-rw-r--r--java/res/xml-sw600dp/rows_thai.xml67
-rw-r--r--java/res/xml-sw768dp-land/kbd_thai.xml28
-rw-r--r--java/res/xml-sw768dp-land/kbd_thai_symbols.xml28
-rw-r--r--java/res/xml-sw768dp-land/kbd_thai_symbols_shift.xml28
-rw-r--r--java/res/xml-sw768dp/kbd_thai.xml28
-rw-r--r--java/res/xml-sw768dp/kbd_thai_symbols.xml28
-rw-r--r--java/res/xml-sw768dp/kbd_thai_symbols_shift.xml28
-rw-r--r--java/res/xml-sw768dp/rowkeys_thai_digits.xml54
-rw-r--r--java/res/xml-sw768dp/rows_thai.xml72
-rw-r--r--java/res/xml-sw768dp/rows_thai_symbols.xml78
-rw-r--r--java/res/xml-sw768dp/rows_thai_symbols_shift.xml78
-rw-r--r--java/res/xml-th/keyboard_set.xml42
-rw-r--r--java/res/xml/kbd_thai.xml26
-rw-r--r--java/res/xml/kbd_thai_symbols.xml26
-rw-r--r--java/res/xml/kbd_thai_symbols_shift.xml26
-rw-r--r--java/res/xml/method.xml7
-rw-r--r--java/res/xml/rowkeys_georgian1.xml2
-rw-r--r--java/res/xml/rowkeys_georgian2.xml2
-rw-r--r--java/res/xml/rowkeys_georgian3.xml2
-rw-r--r--java/res/xml/rowkeys_hindi1.xml2
-rw-r--r--java/res/xml/rowkeys_hindi2.xml2
-rw-r--r--java/res/xml/rowkeys_hindi3.xml2
-rw-r--r--java/res/xml/rowkeys_thai1.xml144
-rw-r--r--java/res/xml/rowkeys_thai2.xml105
-rw-r--r--java/res/xml/rowkeys_thai3.xml83
-rw-r--r--java/res/xml/rows_thai.xml55
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java21
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java56
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java113
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java8
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java2
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java49
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java13
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Word.java23
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java6
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java44
-rw-r--r--native/src/defines.h2
-rw-r--r--native/src/proximity_info.cpp95
-rw-r--r--native/src/proximity_info.h6
-rw-r--r--native/src/unigram_dictionary.cpp47
-rw-r--r--native/src/unigram_dictionary.h5
-rw-r--r--tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java102
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java59
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicTests.java453
-rw-r--r--tests/src/com/android/inputmethod/latin/InputTestsBase.java235
-rw-r--r--tests/src/com/android/inputmethod/latin/PunctuationTests.java151
75 files changed, 2554 insertions, 713 deletions
diff --git a/java/proguard.flags b/java/proguard.flags
index a5a667987..701786a84 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -35,6 +35,14 @@
*;
}
+-keep class com.android.inputmethod.keyboard.LatinKeyboardView {
+ # Keep getter/setter methods for ObjectAnimator
+ int getLanguageOnSpacebarAnimAlpha();
+ void setLanguageOnSpacebarAnimAlpha(int);
+ int getAltCodeKeyWhileTypingAnimAlhpa();
+ void setAltCodeKeyWhileTypingAnimAlpha(int);
+}
+
-keep class com.android.inputmethod.keyboard.MoreKeysKeyboard$Builder$MoreKeysKeyboardParams {
<init>(...);
}
diff --git a/java/res/anim/alt_code_key_while_typing_fadein.xml b/java/res/anim/alt_code_key_while_typing_fadein.xml
index 3f5fd5d48..f8caca313 100644
--- a/java/res/anim/alt_code_key_while_typing_fadein.xml
+++ b/java/res/anim/alt_code_key_while_typing_fadein.xml
@@ -18,8 +18,9 @@
*/
-->
-<animator
+<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="altCodeKeyWhileTypingAnimAlpha"
android:valueType="intType"
android:duration="100"
android:valueFrom="128"
diff --git a/java/res/anim/alt_code_key_while_typing_fadeout.xml b/java/res/anim/alt_code_key_while_typing_fadeout.xml
index ed4a6f298..bad1e7465 100644
--- a/java/res/anim/alt_code_key_while_typing_fadeout.xml
+++ b/java/res/anim/alt_code_key_while_typing_fadeout.xml
@@ -18,8 +18,9 @@
*/
-->
-<animator
+<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="altCodeKeyWhileTypingAnimAlpha"
android:valueType="intType"
android:duration="70"
android:valueFrom="255"
diff --git a/java/res/anim/language_on_spacebar_fadeout.xml b/java/res/anim/language_on_spacebar_fadeout.xml
index f66e1627b..531f440cc 100644
--- a/java/res/anim/language_on_spacebar_fadeout.xml
+++ b/java/res/anim/language_on_spacebar_fadeout.xml
@@ -18,10 +18,11 @@
*/
-->
-<animator
+<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="languageOnSpacebarAnimAlpha"
android:valueType="intType"
android:startOffset="1200"
android:duration="200"
android:valueFrom="255"
- android:valueTo="128" />
+ android:valueTo="@integer/config_language_on_spacebar_final_alpha" />
diff --git a/java/res/values-fr/donottranslate-config.xml b/java/res/values-fr/donottranslate-config.xml
new file mode 100644
index 000000000..1f446d584
--- /dev/null
+++ b/java/res/values-fr/donottranslate-config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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>
+ <bool name="config_require_ligatures_processing">true</bool>
+</resources>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index 6cdcf891c..550d29f76 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -19,8 +19,9 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.260in -->
- <dimen name="keyboardHeight">1.100in</dimen>
+ <!-- Preferable keyboard height in absolute scale: 1.100in -->
+ <!-- This keyboardHeight value should match with keyboard-heights.xml -->
+ <dimen name="keyboardHeight">176.0dp</dimen>
<fraction name="minKeyboardHeight">45%p</fraction>
<!-- key_height + key_bottom_gap = popup_key_height -->
<!-- <dimen name="key_height">0.260in</dimen>-->
@@ -31,7 +32,6 @@
<fraction name="key_bottom_gap">4.330%p</fraction>
<fraction name="key_horizontal_gap">0.405%p</fraction>
- <dimen name="keyboardHeight_stone">0.984in</dimen>
<fraction name="key_bottom_gap_stone">5.010%p</fraction>
<fraction name="key_horizontal_gap_stone">1.159%p</fraction>
diff --git a/java/res/values-land/keyboard-heights.xml b/java/res/values-land/keyboard-heights.xml
new file mode 100644
index 000000000..12c3e3951
--- /dev/null
+++ b/java/res/values-land/keyboard-heights.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Preferable keyboard height in absolute scale: 1.100in -->
+<resources>
+ <!-- Build.HARDWARE,keyboard_height_in_dp -->
+ <string-array name="keyboard_heights" translatable="false">
+ <!-- Droid -->
+ <item>sholes,194.3333</item>
+ <!-- Nexus One -->
+ <item>mahimahi,186.2667</item>
+ <!-- Nexus S -->
+ <item>herring,171.9385</item>
+ <!-- Galaxy Nexus -->
+ <item>tuna,173.4207</item>
+ </string-array>
+</resources>
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 5dce47ee3..c6c6f2b3b 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -19,8 +19,9 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
- <dimen name="keyboardHeight">45.0mm</dimen>
+ <!-- Preferable keyboard height in absolute scale: 45.0mm -->
+ <!-- This keyboardHeight value should match with keyboard-heights.xml -->
+ <dimen name="keyboardHeight">283.5dp</dimen>
<fraction name="minKeyboardHeight">45%p</fraction>
<fraction name="keyboard_top_padding">2.444%p</fraction>
@@ -28,13 +29,13 @@
<fraction name="key_bottom_gap">4.911%p</fraction>
<fraction name="key_horizontal_gap">1.284%p</fraction>
- <dimen name="keyboardHeight_stone">45.0mm</dimen>
<fraction name="key_bottom_gap_stone">4.355%p</fraction>
<fraction name="key_horizontal_gap_stone">1.505%p</fraction>
<fraction name="key_bottom_gap_gb">5.200%p</fraction>
<fraction name="key_horizontal_gap_gb">1.447%p</fraction>
+ <fraction name="key_bottom_gap_ics">4.0%p</fraction>
<fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
<dimen name="popup_key_height">13.0mm</dimen>
diff --git a/java/res/values-sw600dp-land/keyboard-heights.xml b/java/res/values-sw600dp-land/keyboard-heights.xml
new file mode 100644
index 000000000..93f9824d1
--- /dev/null
+++ b/java/res/values-sw600dp-land/keyboard-heights.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Preferable keyboard height in absolute scale: 45.0mm -->
+<resources>
+ <!-- Build.HARDWARE,keyboard_height_in_dp -->
+ <string-array name="keyboard_heights" translatable="false">
+ <!-- Xoom -->
+ <item>stingray,265.4378</item>
+ </string-array>
+</resources>
diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml
index 0f256a302..ebe388263 100644
--- a/java/res/values-sw600dp/dimens.xml
+++ b/java/res/values-sw600dp/dimens.xml
@@ -19,8 +19,9 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
- <dimen name="keyboardHeight">48.0mm</dimen>
+ <!-- Preferable keyboard height in absolute scale: 48.0mm -->
+ <!-- This keyboardHeight value should match with keyboard-heights.xml -->
+ <dimen name="keyboardHeight">302.4dp</dimen>
<fraction name="maxKeyboardHeight">50%p</fraction>
<fraction name="minKeyboardHeight">-35.0%p</fraction>
@@ -31,13 +32,13 @@
<fraction name="key_bottom_gap">3.750%p</fraction>
<fraction name="key_horizontal_gap">1.857%p</fraction>
- <dimen name="keyboardHeight_stone">48.0mm</dimen>
<fraction name="key_bottom_gap_stone">3.75%p</fraction>
<fraction name="key_horizontal_gap_stone">1.602%p</fraction>
<fraction name="key_bottom_gap_gb">4.625%p</fraction>
<fraction name="key_horizontal_gap_gb">2.113%p</fraction>
+ <fraction name="key_bottom_gap_ics">4.0%p</fraction>
<fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
<dimen name="more_keys_keyboard_key_horizontal_padding">6dp</dimen>
diff --git a/java/res/values-sw600dp/keyboard-heights.xml b/java/res/values-sw600dp/keyboard-heights.xml
new file mode 100644
index 000000000..77e52be2f
--- /dev/null
+++ b/java/res/values-sw600dp/keyboard-heights.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Preferable keyboard height in absolute scale: 48.0mm -->
+<resources>
+ <!-- Build.HARDWARE,keyboard_height_in_dp -->
+ <string-array name="keyboard_heights" translatable="false">
+ <!-- Xoom -->
+ <item>stingray,283.1337</item>
+ </string-array>
+</resources>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index 535c62308..597ed5102 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -19,8 +19,9 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=14.5mm -->
- <dimen name="keyboardHeight">58.0mm</dimen>
+ <!-- Preferable keyboard height in absolute scale: 58.0mm -->
+ <!-- This keyboardHeight value should match with keyboard-heights.xml -->
+ <dimen name="keyboardHeight">365.4dp</dimen>
<fraction name="minKeyboardHeight">45%p</fraction>
<fraction name="keyboard_top_padding">1.896%p</fraction>
@@ -29,7 +30,6 @@
<fraction name="key_bottom_gap">4.103%p</fraction>
<fraction name="key_horizontal_gap">1.034%p</fraction>
- <dimen name="keyboardHeight_stone">58.0mm</dimen>
<fraction name="key_bottom_gap_stone">3.379%p</fraction>
<fraction name="key_horizontal_gap_stone">1.062%p</fraction>
diff --git a/java/res/values-sw768dp-land/keyboard-heights.xml b/java/res/values-sw768dp-land/keyboard-heights.xml
new file mode 100644
index 000000000..692c5a0fb
--- /dev/null
+++ b/java/res/values-sw768dp-land/keyboard-heights.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Preferable keyboard height in absolute scale: 58.0mm -->
+<resources>
+ <!-- Build.HARDWARE,keyboard_height_in_dp -->
+ <string-array name="keyboard_heights" translatable="false">
+ <!-- Xoom -->
+ <item>stingray,342.1198</item>
+ </string-array>
+</resources>
diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml
index 7aefa26af..a9f0c00aa 100644
--- a/java/res/values-sw768dp/dimens.xml
+++ b/java/res/values-sw768dp/dimens.xml
@@ -19,8 +19,9 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=12mm -->
- <dimen name="keyboardHeight">48.0mm</dimen>
+ <!-- Preferable keyboard height in absolute scale: 48.0mm -->
+ <!-- This keyboardHeight value should match with keyboard-heights.xml -->
+ <dimen name="keyboardHeight">302.4dp</dimen>
<fraction name="maxKeyboardHeight">50%p</fraction>
<fraction name="minKeyboardHeight">-35.0%p</fraction>
@@ -30,7 +31,6 @@
<fraction name="key_bottom_gap">4.270%p</fraction>
<fraction name="key_horizontal_gap">1.551%p</fraction>
- <dimen name="keyboardHeight_stone">48.0mm</dimen>
<fraction name="key_bottom_gap_stone">3.75%p</fraction>
<fraction name="key_horizontal_gap_stone">1.059%p</fraction>
diff --git a/java/res/values-sw768dp/keyboard-heights.xml b/java/res/values-sw768dp/keyboard-heights.xml
new file mode 100644
index 000000000..77e52be2f
--- /dev/null
+++ b/java/res/values-sw768dp/keyboard-heights.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Preferable keyboard height in absolute scale: 48.0mm -->
+<resources>
+ <!-- Build.HARDWARE,keyboard_height_in_dp -->
+ <string-array name="keyboard_heights" translatable="false">
+ <!-- Xoom -->
+ <item>stingray,283.1337</item>
+ </string-array>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e619ad0a8..e33f0ba8a 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -133,6 +133,7 @@
<attr name="spacebarTextColor" format="color" />
<attr name="spacebarTextShadowColor" format="color" />
<!-- Fadeout animator for spacebar language label. -->
+ <attr name="languageOnSpacebarFinalAlpha" format="integer" />
<attr name="languageOnSpacebarFadeoutAnimator" format="reference" />
<!-- Fadeout and fadein animator for altCodeWhileTyping keys. -->
<attr name="altCodeKeyWhileTypingFadeoutAnimator" format="reference" />
@@ -201,9 +202,10 @@
<!-- Default height of a row (key height + vertical gap), in pixels or percentage of
keyboard height. -->
<attr name="rowHeight" format="dimension|fraction" />
- <!-- Default horizontal gap between keys. -->
+ <!-- Default horizontal gap between keys, in pixels or percentage of keyboard width. -->
<attr name="horizontalGap" format="dimension|fraction" />
- <!-- Default vertical gap between rows of keys. -->
+ <!-- Default vertical gap between rows of keys, in pixels or percentage of keyboard
+ height. -->
<attr name="verticalGap" format="dimension|fraction" />
<!-- More keys keyboard layout template -->
<attr name="moreKeysTemplate" format="reference" />
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index cccec635e..1aa0dffc9 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -38,6 +38,7 @@
<integer name="config_delay_update_suggestions">100</integer>
<integer name="config_delay_update_old_suggestions">300</integer>
<integer name="config_delay_update_shift_state">100</integer>
+ <integer name="config_language_on_spacebar_final_alpha">128</integer>
<integer name="config_more_keys_keyboard_fadein_anim_time">0</integer>
<integer name="config_more_keys_keyboard_fadeout_anim_time">100</integer>
<integer name="config_keyboard_grid_width">32</integer>
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 5f74fa746..9d64a618a 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -19,8 +19,9 @@
-->
<resources>
- <!-- keyboardHeight = row_height*4 + key_bottom_gap*3 -->
- <dimen name="keyboardHeight">1.285in</dimen>
+ <!-- Preferable keyboard height in absolute scale: 1.285in -->
+ <!-- This keyboardHeight value should match with keyboard-heights.xml -->
+ <dimen name="keyboardHeight">205.6dp</dimen>
<fraction name="maxKeyboardHeight">50%p</fraction>
<fraction name="minKeyboardHeight">-61.8%p</fraction>
@@ -35,7 +36,6 @@
<fraction name="key_bottom_gap">6.250%p</fraction>
<fraction name="key_horizontal_gap">1.352%p</fraction>
- <dimen name="keyboardHeight_stone">1.317in</dimen>
<fraction name="keyboard_top_padding_stone">1.556%p</fraction>
<fraction name="keyboard_bottom_padding_stone">0.778%p</fraction>
<fraction name="key_bottom_gap_stone">7.506%p</fraction>
diff --git a/java/res/values/donottranslate-config.xml b/java/res/values/donottranslate-config.xml
index 9b94272e2..ba1cecb6c 100644
--- a/java/res/values/donottranslate-config.xml
+++ b/java/res/values/donottranslate-config.xml
@@ -20,4 +20,5 @@
<resources>
<bool name="config_require_umlaut_processing">false</bool>
+ <bool name="config_require_ligatures_processing">false</bool>
</resources>
diff --git a/java/res/values/keyboard-heights.xml b/java/res/values/keyboard-heights.xml
new file mode 100644
index 000000000..7d5b58372
--- /dev/null
+++ b/java/res/values/keyboard-heights.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Preferable keyboard height in absolute scale: 1.285in -->
+<resources>
+ <!-- Build.HARDWARE,keyboard_height_in_dp -->
+ <string-array name="keyboard_heights" translatable="false">
+ <!-- Droid -->
+ <item>sholes,227.0167</item>
+ <!-- Nexus One -->
+ <item>mahimahi,217.5932</item>
+ <!-- Nexus S -->
+ <item>herring,200.8554</item>
+ <!-- Galaxy Nexus -->
+ <item>tuna,202.5869</item>
+ </string-array>
+</resources>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 5628f271c..b08ff3b90 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -78,6 +78,7 @@
<item name="longPressSpaceKeyTimeout">@integer/config_long_press_space_key_timeout</item>
<item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
<item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
+ <item name="languageOnSpacebarFinalAlpha">@integer/config_language_on_spacebar_final_alpha</item>
<item name="languageOnSpacebarFadeoutAnimator">@anim/language_on_spacebar_fadeout</item>
<item name="altCodeKeyWhileTypingFadeoutAnimator">@anim/alt_code_key_while_typing_fadeout</item>
<item name="altCodeKeyWhileTypingFadeinAnimator">@anim/alt_code_key_while_typing_fadein</item>
@@ -172,7 +173,6 @@
>
<!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
<item name="themeId">6</item>
- <item name="keyboardHeight">@dimen/keyboardHeight_stone</item>
<item name="keyboardTopPadding">@fraction/keyboard_top_padding_stone</item>
<item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_stone</item>
<item name="horizontalGap">@fraction/key_horizontal_gap_stone</item>
diff --git a/java/res/xml-sw600dp-land/kbd_thai.xml b/java/res/xml-sw600dp-land/kbd_thai.xml
new file mode 100644
index 000000000..ac36ea5ff
--- /dev/null
+++ b/java/res/xml-sw600dp-land/kbd_thai.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="3.20%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai" />
+</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_thai.xml b/java/res/xml-sw600dp/kbd_thai.xml
new file mode 100644
index 000000000..ac36ea5ff
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_thai.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="3.20%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai" />
+</Keyboard>
diff --git a/java/res/xml-sw600dp/rowkeys_thai1.xml b/java/res/xml-sw600dp/rowkeys_thai1.xml
new file mode 100644
index 000000000..e49cb2b47
--- /dev/null
+++ b/java/res/xml-sw600dp/rowkeys_thai1.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0E51: "๑" THAI DIGIT ONE -->
+ <Key
+ latin:keyLabel="&#x0E51;" />
+ <!-- U+0E52: "๒" THAI DIGIT TWO -->
+ <Key
+ latin:keyLabel="&#x0E52;" />
+ <!-- U+0E53: "๓" THAI DIGIT THREE -->
+ <Key
+ latin:keyLabel="&#x0E53;" />
+ <!-- U+0E54: "๔" THAI DIGIT FOUR -->
+ <Key
+ latin:keyLabel="&#x0E54;" />
+ <!-- U+0E39: " ู" THAI CHARACTER SARA UU -->
+ <Key
+ latin:keyLabel="&#x0E39;" />
+ <!-- U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT -->
+ <Key
+ latin:keyLabel="&#x0E3F;" />
+ <!-- U+0E55: "๕" THAI DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0E55;" />
+ <!-- U+0E56: "๖" THAI DIGIT SIX -->
+ <Key
+ latin:keyLabel="&#x0E56;" />
+ <!-- U+0E57: "๗" THAI DIGIT SEVEN -->
+ <Key
+ latin:keyLabel="&#x0E57;" />
+ <!-- U+0E58: "๘" THAI DIGIT EIGHT -->
+ <Key
+ latin:keyLabel="&#x0E58;" />
+ <!-- U+0E59: "๙" THAI DIGIT NINE -->
+ <Key
+ latin:keyLabel="&#x0E59;" />
+ </case>
+ <default>
+ <!-- U+0E45: "ๅ" THAI CHARACTER LAKKHANGYAO -->
+ <Key
+ latin:keyLabel="&#x0E45;" />
+ <Key
+ latin:keyLabel="/" />
+ <!-- U+0E20: "ภ" THAI CHARACTER PHO SAMPHAO -->
+ <Key
+ latin:keyLabel="&#x0E20;" />
+ <!-- U+0E16: "ถ" THAI CHARACTER THO THUNG -->
+ <Key
+ latin:keyLabel="&#x0E16;" />
+ <!-- U+0E38: " ุ" THAI CHARACTER SARA U -->
+ <Key
+ latin:keyLabel="&#x0E38;" />
+ <!-- U+0E36: " ึ" THAI CHARACTER SARA UE -->
+ <Key
+ latin:keyLabel="&#x0E36;" />
+ <!-- U+0E04: "ค" THAI CHARACTER KHO KHWAI -->
+ <Key
+ latin:keyLabel="&#x0E04;" />
+ <!-- U+0E15: "ต" THAI CHARACTER TO TAO -->
+ <Key
+ latin:keyLabel="&#x0E15;" />
+ <!-- U+0E08: "จ" THAI CHARACTER CHO CHAN -->
+ <Key
+ latin:keyLabel="&#x0E08;" />
+ <!-- U+0E02: "ข" THAI CHARACTER KHO KHAI -->
+ <Key
+ latin:keyLabel="&#x0E02;" />
+ <!-- U+0E0A: "ช" THAI CHARACTER CHO CHANG -->
+ <Key
+ latin:keyLabel="&#x0E0A;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_thai2.xml b/java/res/xml-sw600dp/rowkeys_thai2.xml
new file mode 100644
index 000000000..0edae1c73
--- /dev/null
+++ b/java/res/xml-sw600dp/rowkeys_thai2.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0E50: "๐" THAI DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x0E50;" />
+ <Key
+ latin:keyLabel="&quot;" />
+ <!-- U+0E0E: "ฎ" THAI CHARACTER DO CHADA -->
+ <Key
+ latin:keyLabel="&#x0E0E;" />
+ <!-- U+0E11: "ฑ" THAI CHARACTER THO NANGMONTHO -->
+ <Key
+ latin:keyLabel="&#x0E11;" />
+ <!-- U+0E18: "ธ" THAI CHARACTER THO THONG -->
+ <Key
+ latin:keyLabel="&#x0E18;" />
+ <!-- U+0E4D: "กํ" THAI CHARACTER THANTHAKHAT -->
+ <Key
+ latin:keyLabel="&#x0E4D;" />
+ <!-- U+0E4A: "ก๊" THAI CHARACTER MAI TRI -->
+ <Key
+ latin:keyLabel="&#x0E4A;" />
+ <!-- U+0E13: "ณ" THAI CHARACTER NO NEN -->
+ <Key
+ latin:keyLabel="&#x0E13;" />
+ <!-- U+0E2F: "ฯ" THAI CHARACTER PAIYANNOI -->
+ <Key
+ latin:keyLabel="&#x0E2F;" />
+ <!-- U+0E0D: "ญ" THAI CHARACTER YO YING -->
+ <Key
+ latin:keyLabel="&#x0E0D;" />
+ <!-- U+0E10: "ฐ" THAI CHARACTER THO THAN -->
+ <Key
+ latin:keyLabel="&#x0E10;" />
+ <Key
+ latin:keyLabel="," />
+ <!-- U+0E05: "ฅ" THAI CHARACTER KHO KHON -->
+ <Key
+ latin:keyLabel="&#x0E05;" />
+ </case>
+ <default>
+ <!-- U+0E46: "ๆ" THAI CHARACTER MAIYAMOK -->
+ <Key
+ latin:keyLabel="&#x0E46;" />
+ <!-- U+0E44: "ไ" THAI CHARACTER SARA AI MAIMALAI -->
+ <Key
+ latin:keyLabel="&#x0E44;" />
+ <!-- U+0E33: "ำ" THAI CHARACTER SARA AM -->
+ <Key
+ latin:keyLabel="&#x0E33;" />
+ <!-- U+0E1E: "พ" THAI CHARACTER PHO PHAN -->
+ <Key
+ latin:keyLabel="&#x0E1E;" />
+ <!-- U+0E30: "ะ" THAI CHARACTER SARA A -->
+ <Key
+ latin:keyLabel="&#x0E30;" />
+ <!-- U+0E31: "กั" THAI CHARACTER MAI HAN-AKAT -->
+ <Key
+ latin:keyLabel="&#x0E31;" />
+ <!-- U+0E35: "กี" HAI CHARACTER SARA II -->
+ <Key
+ latin:keyLabel="&#x0E35;" />
+ <!-- U+0E23: "ร" THAI CHARACTER RO RUA -->
+ <Key
+ latin:keyLabel="&#x0E23;" />
+ <!-- U+0E19: "น" THAI CHARACTER NO NU -->
+ <Key
+ latin:keyLabel="&#x0E19;" />
+ <!-- U+0E22: "ย" THAI CHARACTER YO YAK -->
+ <Key
+ latin:keyLabel="&#x0E22;" />
+ <!-- U+0E1A: "บ" THAI CHARACTER BO BAIMAI -->
+ <Key
+ latin:keyLabel="&#x0E1A;" />
+ <!-- U+0E25: "ล" THAI CHARACTER LO LING -->
+ <Key
+ latin:keyLabel="&#x0E25;" />
+ <!-- U+0E03: "ฃ" THAI CHARACTER KHO KHUAT -->
+ <Key
+ latin:keyLabel="&#x0E03;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_thai3.xml b/java/res/xml-sw600dp/rowkeys_thai3.xml
new file mode 100644
index 000000000..529d7bff0
--- /dev/null
+++ b/java/res/xml-sw600dp/rowkeys_thai3.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0E24: "ฤ" THAI CHARACTER RU -->
+ <Key
+ latin:keyLabel="&#x0E24;" />
+ <!-- U+0E06: "ฆ" THAI CHARACTER KHO RAKHANG -->
+ <Key
+ latin:keyLabel="&#x0E06;" />
+ <!-- U+0E0F: "ฏ" THAI CHARACTER TO PATAK -->
+ <Key
+ latin:keyLabel="&#x0E0F;" />
+ <!-- U+0E42: "โ" THAI CHARACTER SARA O -->
+ <Key
+ latin:keyLabel="&#x0E42;" />
+ <!-- U+0E0C: "ฌ" THAI CHARACTER CHO CHOE -->
+ <Key
+ latin:keyLabel="&#x0E0C;" />
+ <!-- U+0E47: " ็" THAI CHARACTER MAITAIKHU -->
+ <Key
+ latin:keyLabel="&#x0E47;" />
+ <!-- U+0E4B: " ๋" THAI CHARACTER MAI CHATTAWA -->
+ <Key
+ latin:keyLabel="&#x0E4B;" />
+ <!-- U+0E29: "ษ" THAI CHARACTER SO RUSI -->
+ <Key
+ latin:keyLabel="&#x0E29;" />
+ <!-- U+0E28: "ศ" THAI CHARACTER SO SALA -->
+ <Key
+ latin:keyLabel="&#x0E28;" />
+ <!-- U+0E0B: "ซ" THAI CHARACTER SO SO -->
+ <Key
+ latin:keyLabel="&#x0E0B;" />
+ <Key
+ latin:keyLabel="." />
+ </case>
+ <default>
+ <!-- U+0E1F: "ฟ" THAI CHARACTER FO FAN -->
+ <Key
+ latin:keyLabel="&#x0E1F;" />
+ <!-- U+0E2B: "ห" THAI CHARACTER HO HIP -->
+ <Key
+ latin:keyLabel="&#x0E2B;" />
+ <!-- U+0E01: "ก" THAI CHARACTER KO KAI -->
+ <Key
+ latin:keyLabel="&#x0E01;" />
+ <!-- U+0E14: "ด" THAI CHARACTER DO DEK -->
+ <Key
+ latin:keyLabel="&#x0E14;" />
+ <!-- U+0E40: "เ" THAI CHARACTER SARA E -->
+ <Key
+ latin:keyLabel="&#x0E40;" />
+ <!-- U+0E49: " ้" THAI CHARACTER MAI THO -->
+ <Key
+ latin:keyLabel="&#x0E49;" />
+ <!-- U+0E48: " ฺ" THAI CHARACTER MAI EK -->
+ <Key
+ latin:keyLabel="&#x0E48;" />
+ <!-- U+0E32: "า" THAI CHARACTER SARA AA -->
+ <Key
+ latin:keyLabel="&#x0E46;" />
+ <!-- U+0E2A: "ส" THAI CHARACTER SO SUA -->
+ <Key
+ latin:keyLabel="&#x0E46;" />
+ <!-- U+0E27: "ว" THAI CHARACTER WO WAEN -->
+ <Key
+ latin:keyLabel="&#x0E2F;" />
+ <!-- U+0E07: "ง" THAI CHARACTER NGO NGU -->
+ <Key
+ latin:keyLabel="&#x0E07;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_thai4.xml b/java/res/xml-sw600dp/rowkeys_thai4.xml
new file mode 100644
index 000000000..cec34a63b
--- /dev/null
+++ b/java/res/xml-sw600dp/rowkeys_thai4.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Key
+ latin:keyLabel="(" />
+ <Key
+ latin:keyLabel=")" />
+ <!-- U+0E09: "ฉ" THAI CHARACTER CHO CHING -->
+ <Key
+ latin:keyLabel="&#x0E09;" />
+ <!-- U+0E2E: "ฮ" THAI CHARACTER HO NOKHUK -->
+ <Key
+ latin:keyLabel="&#x0E2E;" />
+ <!-- U+0E3A: " ฺ" THAI CHARACTER PHINTHU -->
+ <Key
+ latin:keyLabel="&#x0E3A;" />
+ <!-- U+0E4C: " ์" THAI CHARACTER THANTHAKHAT -->
+ <Key
+ latin:keyLabel="&#x0E4C;" />
+ <Key
+ latin:keyLabel="\?" />
+ <!-- U+0E12: "ฒ" THAI CHARACTER THO PHUTHAO -->
+ <Key
+ latin:keyLabel="&#x0E12;" />
+ <!-- U+0E2C: "ฬ" THAI CHARACTER LO CHULA -->
+ <Key
+ latin:keyLabel="&#x0E2C;" />
+ <!-- U+0E26: "ฦ" THAI CHARACTER LU -->
+ <Key
+ latin:keyLabel="&#x0E26;" />
+ </case>
+ <default>
+ <!-- U+0E1C: "ผ" THAI CHARACTER PHO PHUNG -->
+ <Key
+ latin:keyLabel="&#x0E1C;" />
+ <!-- U+0E1B: "ป" THAI CHARACTER PO PLA -->
+ <Key
+ latin:keyLabel="&#x0E1B;" />
+ <!-- U+0E41: "แ" THAI CHARACTER SARA AE -->
+ <Key
+ latin:keyLabel="&#x0E41;" />
+ <!-- U+0E2D: "อ" THAI CHARACTER O ANG -->
+ <Key
+ latin:keyLabel="&#x0E2D;" />
+ <!-- U+0E34: " ิ" THAI CHARACTER SARA I -->
+ <Key
+ latin:keyLabel="&#x0E34;" />
+ <!-- U+0E37: " ื" THAI CHARACTER SARA UEE -->
+ <Key
+ latin:keyLabel="&#x0E37;" />
+ <!-- U+0E17: "ท" THAI CHARACTER THO THAHAN -->
+ <Key
+ latin:keyLabel="&#x0E17;" />
+ <!-- U+0E21: "ม" THAI CHARACTER MO MA -->
+ <Key
+ latin:keyLabel="&#x0E21;" />
+ <!-- U+0E43: "ใ" THAI CHARACTER SARA AI MAIMUAN -->
+ <Key
+ latin:keyLabel="&#x0E43;" />
+ <!-- U+0E1D: "ฝ" THAI CHARACTER FO FA -->
+ <Key
+ latin:keyLabel="&#x0E1D;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/rows_thai.xml b/java/res/xml-sw600dp/rows_thai.xml
new file mode 100644
index 000000000..d4eaa10bb
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_thai.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="7.800%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai1"
+ latin:keyXPos="4.0%p" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="7.692%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai2" />
+ </Row>
+ <Row
+ latin:keyWidth="7.692%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai3"
+ latin:keyXPos="4.5%p" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="7.692%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.0%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai4" />
+ <include
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-9.0%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw768dp-land/kbd_thai.xml b/java/res/xml-sw768dp-land/kbd_thai.xml
new file mode 100644
index 000000000..4bfc9cb48
--- /dev/null
+++ b/java/res/xml-sw768dp-land/kbd_thai.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="2.65%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp-land/kbd_thai_symbols.xml b/java/res/xml-sw768dp-land/kbd_thai_symbols.xml
new file mode 100644
index 000000000..a3feeaae3
--- /dev/null
+++ b/java/res/xml-sw768dp-land/kbd_thai_symbols.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="2.65%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai_symbols" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp-land/kbd_thai_symbols_shift.xml b/java/res/xml-sw768dp-land/kbd_thai_symbols_shift.xml
new file mode 100644
index 000000000..8b4a8ea5b
--- /dev/null
+++ b/java/res/xml-sw768dp-land/kbd_thai_symbols_shift.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="2.65%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai_symbols_shift" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_thai.xml b/java/res/xml-sw768dp/kbd_thai.xml
new file mode 100644
index 000000000..dd0ac36a6
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_thai.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="2.95%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_thai_symbols.xml b/java/res/xml-sw768dp/kbd_thai_symbols.xml
new file mode 100644
index 000000000..91cf8084f
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_thai_symbols.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="2.95%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai_symbols" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_thai_symbols_shift.xml b/java/res/xml-sw768dp/kbd_thai_symbols_shift.xml
new file mode 100644
index 000000000..85745ac3d
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_thai_symbols_shift.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="2.95%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai_symbols_shift" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp/rowkeys_thai_digits.xml b/java/res/xml-sw768dp/rowkeys_thai_digits.xml
new file mode 100644
index 000000000..512283096
--- /dev/null
+++ b/java/res/xml-sw768dp/rowkeys_thai_digits.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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"
+>
+ <!-- U+0E51: "๑" THAI DIGIT ONE -->
+ <Key
+ latin:keyLabel="&#x0E51;" />
+ <!-- U+0E52: "๒" THAI DIGIT TWO -->
+ <Key
+ latin:keyLabel="&#x0E52;" />
+ <!-- U+0E53: "๓" THAI DIGIT THREE -->
+ <Key
+ latin:keyLabel="&#x0E53;" />
+ <!-- U+0E54: "๔" THAI DIGIT FOUR -->
+ <Key
+ latin:keyLabel="&#x0E54;" />
+ <!-- U+0E55: "๕" THAI DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0E55;" />
+ <!-- U+0E56: "๖" THAI DIGIT SIX -->
+ <Key
+ latin:keyLabel="&#x0E56;" />
+ <!-- U+0E57: "๗" THAI DIGIT SEVEN -->
+ <Key
+ latin:keyLabel="&#x0E57;" />
+ <!-- U+0E58: "๘" THAI DIGIT EIGHT -->
+ <Key
+ latin:keyLabel="&#x0E58;" />
+ <!-- U+0E59: "๙" THAI DIGIT NINE -->
+ <Key
+ latin:keyLabel="&#x0E59;" />
+ <!-- U+0E50: "๐" THAI DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x0E50;" />
+</merge>
diff --git a/java/res/xml-sw768dp/rows_thai.xml b/java/res/xml-sw768dp/rows_thai.xml
new file mode 100644
index 000000000..cc77f8bc5
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_thai.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="7.079%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai1"
+ latin:keyXPos="11.508%p"/>
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillBoth"/>
+ </Row>
+ <Row
+ latin:keyWidth="7.079%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="7.969%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai2" />
+ </Row>
+ <Row
+ latin:keyWidth="7.125%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="11.172%p"/>
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai3" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="7.181%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="13.829%p"/>
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai4" />
+ <include
+ latin:keyboardLayout="@xml/keys_comma_period" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw768dp/rows_thai_symbols.xml b/java/res/xml-sw768dp/rows_thai_symbols.xml
new file mode 100644
index 000000000..4a251b770
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_thai_symbols.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_currency" />
+ <Row
+ latin:keyWidth="8.282%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai_digits"
+ latin:keyXPos="7.969%p" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-9.219%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="8.282%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="7.969%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_symbols1" />
+ </Row>
+ <Row
+ latin:keyWidth="8.125%p"
+ >
+ <Key
+ latin:keyStyle="toAlphaKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="11.172%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_symbols2" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-15.704%p"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="8.047%p"
+ >
+ <Key
+ latin:keyStyle="toMoreSymbolKeyStyle"
+ latin:keyWidth="13.829%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_symbols3" />
+ <Key
+ latin:keyStyle="toMoreSymbolKeyStyle"
+ latin:keyXPos="-13.750%p"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/rows_symbols4" />
+</merge>
diff --git a/java/res/xml-sw768dp/rows_thai_symbols_shift.xml b/java/res/xml-sw768dp/rows_thai_symbols_shift.xml
new file mode 100644
index 000000000..21002c6c8
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_thai_symbols_shift.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_currency" />
+ <Row
+ latin:keyWidth="8.282%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai_digits"
+ latin:keyXPos="7.969%p" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-9.219%p"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="8.282%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="7.969%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_symbols_shift1" />
+ </Row>
+ <Row
+ latin:keyWidth="8.125%p"
+ >
+ <Key
+ latin:keyStyle="toAlphaKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="11.172%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_symbols_shift2" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-15.704%p"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="8.047%p"
+ >
+ <Key
+ latin:keyStyle="backFromMoreSymbolKeyStyle"
+ latin:keyWidth="13.829%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_symbols_shift3" />
+ <Key
+ latin:keyStyle="backFromMoreSymbolKeyStyle"
+ latin:keyXPos="-13.750%p"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/rows_symbols_shift4" />
+</merge>
diff --git a/java/res/xml-th/keyboard_set.xml b/java/res/xml-th/keyboard_set.xml
new file mode 100644
index 000000000..99d75fe80
--- /dev/null
+++ b/java/res/xml-th/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="th">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_thai" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_thai_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_thai_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml/kbd_thai.xml b/java/res/xml/kbd_thai.xml
new file mode 100644
index 000000000..058ca16a3
--- /dev/null
+++ b/java/res/xml/kbd_thai.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_thai" />
+</Keyboard>
diff --git a/java/res/xml/kbd_thai_symbols.xml b/java/res/xml/kbd_thai_symbols.xml
new file mode 100644
index 000000000..7e075df48
--- /dev/null
+++ b/java/res/xml/kbd_thai_symbols.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_symbols" />
+</Keyboard>
diff --git a/java/res/xml/kbd_thai_symbols_shift.xml b/java/res/xml/kbd_thai_symbols_shift.xml
new file mode 100644
index 000000000..25db3c84d
--- /dev/null
+++ b/java/res/xml/kbd_thai_symbols_shift.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_symbols_shift" />
+</Keyboard>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 077574f34..544f3fd64 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -58,6 +58,7 @@
sl: Slovenian/qwerty
sr: Serbian/south_slavic
sv: Swedish/nordic
+ th: Thai/thai
tr: Turkish/qwerty
uk: Ukrainian/east_slavic
vi: Vietnamese/qwerty
@@ -299,6 +300,12 @@
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="th"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue=""
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
android:imeSubtypeLocale="uk"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
diff --git a/java/res/xml/rowkeys_georgian1.xml b/java/res/xml/rowkeys_georgian1.xml
index b644cdfdd..6b24c29fe 100644
--- a/java/res/xml/rowkeys_georgian1.xml
+++ b/java/res/xml/rowkeys_georgian1.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
>
<Key
latin:keyLabel="Q"
diff --git a/java/res/xml/rowkeys_georgian2.xml b/java/res/xml/rowkeys_georgian2.xml
index ddd375afa..f50e3d64b 100644
--- a/java/res/xml/rowkeys_georgian2.xml
+++ b/java/res/xml/rowkeys_georgian2.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
>
<Key
latin:keyLabel="A"
diff --git a/java/res/xml/rowkeys_georgian3.xml b/java/res/xml/rowkeys_georgian3.xml
index ae8443a31..f908673af 100644
--- a/java/res/xml/rowkeys_georgian3.xml
+++ b/java/res/xml/rowkeys_georgian3.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
>
<!-- U+10EB: "ძ" GEORGIAN LETTER JIL -->
<Key
diff --git a/java/res/xml/rowkeys_hindi1.xml b/java/res/xml/rowkeys_hindi1.xml
index 4f7a4148c..fe54d9ea9 100644
--- a/java/res/xml/rowkeys_hindi1.xml
+++ b/java/res/xml/rowkeys_hindi1.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
>
<!-- U+0914: "औ" DEVANAGARI LETTER AU
U+0912/U+0902: "ऒं" DEVANAGARI LETTER SHORT O//DEVANAGARI SIGN ANUSVARA
diff --git a/java/res/xml/rowkeys_hindi2.xml b/java/res/xml/rowkeys_hindi2.xml
index 1bf6fd4df..95f488102 100644
--- a/java/res/xml/rowkeys_hindi2.xml
+++ b/java/res/xml/rowkeys_hindi2.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
>
<!-- U+0913: "ओ" DEVANAGARI LETTER O
U+0913/U+0902: "ओं" DEVANAGARI LETTER O/DEVANAGARI SIGN ANUSVARA
diff --git a/java/res/xml/rowkeys_hindi3.xml b/java/res/xml/rowkeys_hindi3.xml
index e6b430f1b..7d43d57c7 100644
--- a/java/res/xml/rowkeys_hindi3.xml
+++ b/java/res/xml/rowkeys_hindi3.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
>
<!-- U+0911: "ऑ" DEVANAGARI LETTER CANDRA O -->
<Key
diff --git a/java/res/xml/rowkeys_thai1.xml b/java/res/xml/rowkeys_thai1.xml
new file mode 100644
index 000000000..54ec327b0
--- /dev/null
+++ b/java/res/xml/rowkeys_thai1.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0E0E: "ฎ" THAI CHARACTER DO CHADA -->
+ <Key
+ latin:keyLabel="&#x0E0E;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1" />
+ <!-- U+0E11: "ฑ" THAI CHARACTER THO NANGMONTHO -->
+ <Key
+ latin:keyLabel="&#x0E11;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2" />
+ <!-- U+0E18: "ธ" THAI CHARACTER THO THONG -->
+ <Key
+ latin:keyLabel="&#x0E18;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3" />
+ <!-- U+0E13: "ณ" THAI CHARACTER NO NEN -->
+ <Key
+ latin:keyLabel="&#x0E13;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4" />
+ <!-- U+0E0D: "ญ" THAI CHARACTER YO YING -->
+ <Key
+ latin:keyLabel="&#x0E0D;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5" />
+ <!-- U+0E10: "ฐ" THAI CHARACTER THO THAN -->
+ <Key
+ latin:keyLabel="&#x0E10;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6" />
+ <!-- U+0E03: "ฃ" THAI CHARACTER KHO KHUAT -->
+ <Key
+ latin:keyLabel="&#x0E03;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7" />
+ <!-- U+0E05: "ฅ" THAI CHARACTER KHO KHON -->
+ <Key
+ latin:keyLabel="&#x0E05;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8" />
+ <!-- U+0E51: "๑" THAI DIGIT ONE
+ U+0E52: "๒" THAI DIGIT TWO
+ U+0E53: "๓" THAI DIGIT THREE
+ U+0E54: "๔" THAI DIGIT FOUR
+ U+0E55: "๕" THAI DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0E51;"
+ latin:moreKeys="&#x0E52;,&#x0E53;,&#x0E54;,&#x0E55;,%"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9" />
+ <!-- U+0E56: "๖" THAI DIGIT SIX
+ U+0E57: "๗" THAI DIGIT SEVEN
+ U+0E58: "๘" THAI DIGIT EIGHT
+ U+0E59: "๙" THAI DIGIT NINE
+ U+0E50: "๐" THAI DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x0E56;"
+ latin:moreKeys="&#x0E57;,&#x0E58;,&#x0E59;,&#x0E50;,%"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0" />
+ </case>
+ <default>
+ <!-- U+0E20: "ภ" THAI CHARACTER PHO SAMPHAO -->
+ <Key
+ latin:keyLabel="&#x0E20;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1,&#x0E51;" />
+ <!-- U+0E16: "ถ" THAI CHARACTER THO THUNG -->
+ <Key
+ latin:keyLabel="&#x0E16;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2,&#x0E52;" />
+ <!-- U+0E04: "ค" THAI CHARACTER KHO KHWAI -->
+ <Key
+ latin:keyLabel="&#x0E04;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3,&#x0E53;" />
+ <!-- U+0E15: "ต" THAI CHARACTER TO TAO -->
+ <Key
+ latin:keyLabel="&#x0E15;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4,&#x0E54;" />
+ <!-- U+0E08: "จ" THAI CHARACTER CHO CHAN -->
+ <Key
+ latin:keyLabel="&#x0E08;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5,&#x0E55;" />
+ <!-- U+0E02: "ข" THAI CHARACTER KHO KHAI -->
+ <Key
+ latin:keyLabel="&#x0E02;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6,&#x0E56;" />
+ <!-- U+0E0A: "ช" THAI CHARACTER CHO CHANG -->
+ <Key
+ latin:keyLabel="&#x0E0A;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7,&#x0E57;" />
+ <!-- U+0E23: "ร" THAI CHARACTER RO RUA
+ U+0E25: "ล" THAI CHARACTER LO LING -->
+ <Key
+ latin:keyLabel="&#x0E23;"
+ latin:moreKeys="&#x0E25;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8,&#x0E58;" />
+ <!-- U+0E19: "น" THAI CHARACTER NO NU -->
+ <Key
+ latin:keyLabel="&#x0E19;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9,&#x0E59;" />
+ <!-- U+0E22: "ย" THAI CHARACTER YO YAK -->
+ <Key
+ latin:keyLabel="&#x0E22;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0,&#x0E50;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_thai2.xml b/java/res/xml/rowkeys_thai2.xml
new file mode 100644
index 000000000..a5db66519
--- /dev/null
+++ b/java/res/xml/rowkeys_thai2.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0E24: "ฤ" THAI CHARACTER RU -->
+ <Key
+ latin:keyLabel="&#x0E24;" />
+ <!-- U+0E06: "ฆ" THAI CHARACTER KHO RAKHANG -->
+ <Key
+ latin:keyLabel="&#x0E06;" />
+ <!-- U+0E0F: "ฏ" THAI CHARACTER TO PATAK -->
+ <Key
+ latin:keyLabel="&#x0E0F;" />
+ <!-- U+0E0C: "ฌ" THAI CHARACTER CHO CHOE -->
+ <Key
+ latin:keyLabel="&#x0E0C;" />
+ <!-- U+0E29: "ษ" THAI CHARACTER SO RUSI -->
+ <Key
+ latin:keyLabel="&#x0E29;" />
+ <!-- U+0E28: "ศ" THAI CHARACTER SO SALA -->
+ <Key
+ latin:keyLabel="&#x0E28;" />
+ <!-- U+0E0B: "ซ" THAI CHARACTER SO SO -->
+ <Key
+ latin:keyLabel="&#x0E0B;" />
+ <!-- U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT -->
+ <Key
+ latin:keyLabel="&#x0E3F;" />
+ <!-- U+0E46: "ๆ" THAI CHARACTER MAIYAMOK
+ U+0E2F: "ฯ" THAI CHARACTER PAIYANNOI -->
+ <Key
+ latin:keyLabel="&#x0E46;"
+ latin:moreKeys="&#x0E2F;" />
+ </case>
+ <default>
+ <!-- U+0E1F: "ฟ" THAI CHARACTER FO FAN
+ U+0E1E: "พ" THAI CHARACTER PHO PHAN -->
+ <Key
+ latin:keyLabel="&#x0E1F;"
+ latin:moreKeys="&#x0E1E;" />
+ <!-- U+0E2B: "ห" THAI CHARACTER HO HIP -->
+ <Key
+ latin:keyLabel="&#x0E2B;" />
+ <!-- U+0E01: "ก" THAI CHARACTER KO KAI -->
+ <Key
+ latin:keyLabel="&#x0E01;" />
+ <!-- U+0E14: "ด" THAI CHARACTER DO DEK -->
+ <Key
+ latin:keyLabel="&#x0E14;" />
+ <!-- U+0E2A: "ส" THAI CHARACTER SO SUA -->
+ <Key
+ latin:keyLabel="&#x0E2A;" />
+ <!-- U+0E27: "ว" THAI CHARACTER WO WAEN -->
+ <Key
+ latin:keyLabel="&#x0E27;" />
+ <!-- U+0E07: "ง" THAI CHARACTER NGO NGU -->
+ <Key
+ latin:keyLabel="&#x0E07;" />
+ <!-- U+0E30: "ะ" THAI CHARACTER SARA A
+ U+0E32: "า" THAI CHARACTER SARA AA
+ U+0E33: " ำ" THAI CHARACTER SARA AM
+ U+0E40: "เ" THAI CHARACTER SARA E
+ U+0E41: "แ" THAI CHARACTER SARA AE
+ U+0E43: "ใ" THAI CHARACTER SARA AI MAIMUAN
+ U+0E44: "ไ" THAI CHARACTER SARA AI MAIMALAI
+ U+0E42: "โ" THAI CHARACTER SARA O -->
+ <Key
+ latin:keyLabel="&#x0E30;"
+ latin:moreKeys="&#x0E32;,&#x0E33;,&#x0E40;,&#x0E41;,&#x0E43;,&#x0E44;,&#x0E42;" />
+ <!-- U+0E31: " ั" THAI CHARACTER MAI HAN-AKAT
+ U+0E34: " ิ" THAI CHARACTER SARA I
+ U+0E35: " ี" THAI CHARACTER SARA II
+ U+0E36: " ึ" THAI CHARACTER SARA UE
+ U+0E37: " ื" THAI CHARACTER SARA UEE
+ U+0E38: " ุ" THAI CHARACTER SARA U
+ U+0E39: " ู" THAI CHARACTER SARA UU -->
+ <Key
+ latin:keyLabel="&#x0E31;"
+ latin:moreKeys="&#x0E34;,&#x0E35;,&#x0E36;,&#x0E37;,&#x0E38;,&#x0E39;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_thai3.xml b/java/res/xml/rowkeys_thai3.xml
new file mode 100644
index 000000000..72c0deffe
--- /dev/null
+++ b/java/res/xml/rowkeys_thai3.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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:keyboardSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0E09: "ฉ" THAI CHARACTER CHO CHING -->
+ <Key
+ latin:keyLabel="&#x0E09;" />
+ <!-- U+0E2E: "ฮ" THAI CHARACTER HO NOKHUK -->
+ <Key
+ latin:keyLabel="&#x0E2E;" />
+ <!-- U+0E12: "ฒ" THAI CHARACTER THO PHUTHAO -->
+ <Key
+ latin:keyLabel="&#x0E12;" />
+ <!-- U+0E2C: "ฬ" THAI CHARACTER LO CHULA -->
+ <Key
+ latin:keyLabel="&#x0E2C;" />
+ <!-- U+0E26: "ฦ" THAI CHARACTER LU -->
+ <Key
+ latin:keyLabel="&#x0E26;" />
+ <!-- U+0E4C: " ์" THAI CHARACTER THANTHAKHAT
+ U+0E4D: " ํ" THAI CHARACTER NIKHAHIT
+ U+0E3A: " ฺ" THAI CHARACTER PHINTHU -->
+ <Key
+ latin:keyLabel="&#x0E4C;"
+ latin:moreKeys="&#x0E4D;,&#x0E3A;" />
+ <!-- U+0E47: " ็" THAI CHARACTER MAITAIKHU -->
+ <Key
+ latin:keyLabel="&#x0E47;" />
+ </case>
+ <default>
+ <!-- U+0E1C: "ผ" THAI CHARACTER PHO PHUNG -->
+ <Key
+ latin:keyLabel="&#x0E1C;" />
+ <!-- U+0E1B: "ป" THAI CHARACTER PO PLA
+ U+0E1A: "บ" THAI CHARACTER BO BAIMAI -->
+ <Key
+ latin:keyLabel="&#x0E1B;"
+ latin:moreKeys="&#x0E1A;" />
+ <!-- U+0E2D: "อ" THAI CHARACTER O ANG -->
+ <Key
+ latin:keyLabel="&#x0E2D;" />
+ <!-- U+0E17: "ท" THAI CHARACTER THO THAHAN -->
+ <Key
+ latin:keyLabel="&#x0E17;" />
+ <!-- U+0E21: "ม" THAI CHARACTER MO MA -->
+ <Key
+ latin:keyLabel="&#x0E21;" />
+ <!-- U+0E1D: "ฝ" THAI CHARACTER FO FA -->
+ <Key
+ latin:keyLabel="&#x0E1D;" />
+ <!-- U+0E48: " ่" THAI CHARACTER MAI EK
+ U+0E49: " ้" THAI CHARACTER MAI THO
+ U+0E4A: " ๊" THAI CHARACTER MAI TRI
+ U+0E4B: " ๋" THAI CHARACTER MAI CHATTAWA -->
+ <Key
+ latin:keyLabel="&#x0E48;"
+ latin:moreKeys="&#x0E49;,&#x0E4A;,&#x0E4B;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rows_thai.xml b/java/res/xml/rows_thai.xml
new file mode 100644
index 000000000..6b80df640
--- /dev/null
+++ b/java/res/xml/rows_thai.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai1" />
+ </Row>
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai2"
+ latin:keyXPos="5%p" />
+ </Row>
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_thai3" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:visualInsetsLeft="1%p" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index b09a27540..0a2b010b6 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -180,7 +180,7 @@ public class Key {
mY = y;
mHitBox.set(x, y, x + width + 1, y + height);
- mHashCode = hashCode(this);
+ mHashCode = computeHashCode(this);
}
/**
@@ -334,7 +334,7 @@ public class Key {
mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr,
R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase,
params.mId);
- mHashCode = hashCode(this);
+ mHashCode = computeHashCode(this);
keyAttr.recycle();
@@ -366,7 +366,7 @@ public class Key {
}
}
- private static int hashCode(Key key) {
+ private static int computeHashCode(Key key) {
return Arrays.hashCode(new Object[] {
key.mX,
key.mY,
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 2b1cc43cd..07b9c1e8c 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -31,6 +31,7 @@ import com.android.inputmethod.keyboard.internal.KeyStyles;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.XmlParseUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -715,22 +716,30 @@ public class Keyboard {
R.styleable.Keyboard_Key);
try {
final int displayHeight = mDisplayMetrics.heightPixels;
- final int keyboardHeight = (int)keyboardAttr.getDimension(
- R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
- final int maxKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ final String keyboardHeightString = Utils.getDeviceOverrideValue(
+ mResources, R.array.keyboard_heights, null);
+ final float keyboardHeight;
+ if (keyboardHeightString != null) {
+ keyboardHeight = Float.parseFloat(keyboardHeightString)
+ * mDisplayMetrics.density;
+ } else {
+ keyboardHeight = keyboardAttr.getDimension(
+ R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
+ }
+ final float maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- int minKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ float minKeyboardHeight = getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
if (minKeyboardHeight < 0) {
// Specified fraction was negative, so it should be calculated against display
// width.
- minKeyboardHeight = -(int)getDimensionOrFraction(keyboardAttr,
+ minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
}
final Params params = mParams;
// Keyboard height will not exceed maxKeyboardHeight and will not be less than
// minKeyboardHeight.
- params.mOccupiedHeight = Math.max(
+ params.mOccupiedHeight = (int)Math.max(
Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
params.mOccupiedWidth = params.mId.mWidth;
params.mTopPadding = (int)getDimensionOrFraction(keyboardAttr,
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 6703b9301..3b2b11e4e 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -70,23 +70,23 @@ public class KeyboardId {
public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
- this.mLocale = locale;
- this.mOrientation = orientation;
- this.mWidth = width;
- this.mMode = mode;
- this.mElementId = elementId;
- this.mEditorInfo = editorInfo;
- this.mClobberSettingsKey = clobberSettingsKey;
- this.mShortcutKeyEnabled = shortcutKeyEnabled;
- this.mHasShortcutKey = hasShortcutKey;
- this.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
- this.mCustomActionLabel = (editorInfo.actionLabel != null)
+ mLocale = locale;
+ mOrientation = orientation;
+ mWidth = width;
+ mMode = mode;
+ mElementId = elementId;
+ mEditorInfo = editorInfo;
+ mClobberSettingsKey = clobberSettingsKey;
+ mShortcutKeyEnabled = shortcutKeyEnabled;
+ mHasShortcutKey = hasShortcutKey;
+ mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
+ mCustomActionLabel = (editorInfo.actionLabel != null)
? editorInfo.actionLabel.toString() : null;
- this.mHashCode = hashCode(this);
+ mHashCode = computeHashCode(this);
}
- private static int hashCode(KeyboardId id) {
+ private static int computeHashCode(KeyboardId id) {
return Arrays.hashCode(new Object[] {
id.mOrientation,
id.mElementId,
@@ -109,21 +109,21 @@ public class KeyboardId {
private boolean equals(KeyboardId other) {
if (other == this)
return true;
- return other.mOrientation == this.mOrientation
- && other.mElementId == this.mElementId
- && other.mMode == this.mMode
- && other.mWidth == this.mWidth
- && other.passwordInput() == this.passwordInput()
- && other.mClobberSettingsKey == this.mClobberSettingsKey
- && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
- && other.mHasShortcutKey == this.mHasShortcutKey
- && other.mLanguageSwitchKeyEnabled == this.mLanguageSwitchKeyEnabled
- && other.isMultiLine() == this.isMultiLine()
- && other.imeAction() == this.imeAction()
- && TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
- && other.navigateNext() == this.navigateNext()
- && other.navigatePrevious() == this.navigatePrevious()
- && other.mLocale.equals(this.mLocale);
+ return other.mOrientation == mOrientation
+ && other.mElementId == mElementId
+ && other.mMode == mMode
+ && other.mWidth == mWidth
+ && other.passwordInput() == passwordInput()
+ && other.mClobberSettingsKey == mClobberSettingsKey
+ && other.mShortcutKeyEnabled == mShortcutKeyEnabled
+ && other.mHasShortcutKey == mHasShortcutKey
+ && other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled
+ && other.isMultiLine() == isMultiLine()
+ && other.imeAction() == imeAction()
+ && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel)
+ && other.navigateNext() == navigateNext()
+ && other.navigatePrevious() == navigatePrevious()
+ && other.mLocale.equals(mLocale);
}
public boolean isAlphabetKeyboard() {
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index dca15decd..b66d1661d 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -16,11 +16,8 @@
package com.android.inputmethod.keyboard;
-import android.animation.Animator;
import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
@@ -76,12 +73,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private Key mSpaceKey;
private Drawable mSpaceIcon;
// Stuff to draw language name on spacebar.
- private ValueAnimator mLanguageOnSpacebarFadeoutAnimator;
- private int mFinalAlphaOfLanguageOnSpacebar;
+ private final int mLanguageOnSpacebarFinalAlpha;
+ private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator;
private static final int ALPHA_OPAQUE = 255;
private boolean mNeedsToDisplayLanguage;
private Locale mSpacebarLocale;
- private int mSpacebarTextAlpha = ALPHA_OPAQUE;
+ private int mLanguageOnSpacebarAnimAlpha = ALPHA_OPAQUE;
private final float mSpacebarTextRatio;
private float mSpacebarTextSize;
private final int mSpacebarTextColor;
@@ -96,8 +93,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private static final int SPACE_LED_LENGTH_PERCENT = 80;
// Stuff to draw altCodeWhileTyping keys.
- private ValueAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
- private ValueAnimator mAltCodeKeyWhileTypingFadeinAnimator;
+ private ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
+ private ObjectAnimator mAltCodeKeyWhileTypingFadeinAnimator;
private int mAltCodeKeyWhileTypingAnimAlpha = ALPHA_OPAQUE;
// More keys keyboard
@@ -227,8 +224,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
removeMessages(MSG_LONGPRESS_KEY);
}
- private static void cancelAndStartAnimators(ValueAnimator animatorToCancel,
- ValueAnimator animatorToStart) {
+ public static void cancelAndStartAnimators(ObjectAnimator animatorToCancel,
+ ObjectAnimator animatorToStart) {
if (animatorToCancel != null && animatorToCancel.isStarted()) {
animatorToCancel.cancel();
}
@@ -362,6 +359,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboardView_spacebarTextColor, 0);
mSpacebarTextShadowColor = a.getColor(
R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0);
+ mLanguageOnSpacebarFinalAlpha = a.getInt(
+ R.styleable.LatinKeyboardView_languageOnSpacebarFinalAlpha, ALPHA_OPAQUE);
final int languageOnSpacebarFadeoutAnimatorResId = a.getResourceId(
R.styleable.LatinKeyboardView_languageOnSpacebarFadeoutAnimator, 0);
final int altCodeKeyWhileTypingFadeoutAnimatorResId = a.getResourceId(
@@ -383,55 +382,41 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
PointerTracker.setParameters(mPointerTrackerParams);
- final ValueAnimator animator = loadValueAnimator(languageOnSpacebarFadeoutAnimatorResId);
+ mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator(
+ languageOnSpacebarFadeoutAnimatorResId, this);
+ mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator(
+ altCodeKeyWhileTypingFadeoutAnimatorResId, this);
+ mAltCodeKeyWhileTypingFadeinAnimator = loadObjectAnimator(
+ altCodeKeyWhileTypingFadeinAnimatorResId, this);
+ }
+
+ private ObjectAnimator loadObjectAnimator(int resId, Object target) {
+ if (resId == 0) return null;
+ final ObjectAnimator animator = (ObjectAnimator)AnimatorInflater.loadAnimator(
+ getContext(), resId);
if (animator != null) {
- animator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mSpacebarTextAlpha = (Integer)animation.getAnimatedValue();
- invalidateKey(mSpaceKey);
- }
- });
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator a) {
- final ValueAnimator valueAnimator = (ValueAnimator)a;
- mFinalAlphaOfLanguageOnSpacebar = (Integer)valueAnimator.getAnimatedValue();
- }
- });
- // In order to get the final value of animator.
- animator.end();
- }
- mLanguageOnSpacebarFadeoutAnimator = animator;
-
- final ValueAnimator fadeout = loadValueAnimator(altCodeKeyWhileTypingFadeoutAnimatorResId);
- if (fadeout != null) {
- fadeout.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mAltCodeKeyWhileTypingAnimAlpha = (Integer)animation.getAnimatedValue();
- updateAltCodeKeyWhileTyping();
- }
- });
+ animator.setTarget(target);
}
- mAltCodeKeyWhileTypingFadeoutAnimator = fadeout;
+ return animator;
+ }
- final ValueAnimator fadein = loadValueAnimator(altCodeKeyWhileTypingFadeinAnimatorResId);
- if (fadein != null) {
- fadein.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mAltCodeKeyWhileTypingAnimAlpha = (Integer)animation.getAnimatedValue();
- updateAltCodeKeyWhileTyping();
- }
- });
- }
- mAltCodeKeyWhileTypingFadeinAnimator = fadein;
+ // Getter/setter methods for {@link ObjectAnimator}.
+ public int getLanguageOnSpacebarAnimAlpha() {
+ return mLanguageOnSpacebarAnimAlpha;
}
- private ValueAnimator loadValueAnimator(int resId) {
- if (resId == 0) return null;
- return (ValueAnimator)AnimatorInflater.loadAnimator(getContext(), resId);
+ public void setLanguageOnSpacebarAnimAlpha(int alpha) {
+ mLanguageOnSpacebarAnimAlpha = alpha;
+ invalidateKey(mSpaceKey);
+ }
+
+ public int getAltCodeKeyWhileTypingAnimAlpha() {
+ return mAltCodeKeyWhileTypingAnimAlpha;
+ }
+
+ public void setAltCodeKeyWhileTypingAnimAlpha(int alpha) {
+ mAltCodeKeyWhileTypingAnimAlpha = alpha;
+ updateAltCodeKeyWhileTyping();
}
public void setKeyboardActionListener(KeyboardActionListener listener) {
@@ -836,19 +821,21 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
public void startDisplayLanguageOnSpacebar(boolean subtypeChanged,
boolean needsToDisplayLanguage) {
- final ValueAnimator animator = mLanguageOnSpacebarFadeoutAnimator;
- if (animator != null) {
- animator.cancel();
- }
+ final ObjectAnimator animator = mLanguageOnSpacebarFadeoutAnimator;
mNeedsToDisplayLanguage = needsToDisplayLanguage;
if (animator == null) {
mNeedsToDisplayLanguage = false;
} else {
if (subtypeChanged && needsToDisplayLanguage) {
- mSpacebarTextAlpha = ALPHA_OPAQUE;
+ setLanguageOnSpacebarAnimAlpha(ALPHA_OPAQUE);
+ if (animator.isStarted()) {
+ animator.cancel();
+ }
animator.start();
} else {
- mSpacebarTextAlpha = mFinalAlphaOfLanguageOnSpacebar;
+ if (!animator.isStarted()) {
+ mLanguageOnSpacebarAnimAlpha = mLanguageOnSpacebarFinalAlpha;
+ }
}
}
invalidateKey(mSpaceKey);
@@ -942,10 +929,10 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
final float textHeight = -paint.ascent() + descent;
final float baseline = height / 2 + textHeight / 2;
paint.setColor(mSpacebarTextShadowColor);
- paint.setAlpha(mSpacebarTextAlpha);
+ paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
canvas.drawText(language, width / 2, baseline - descent - 1, paint);
paint.setColor(mSpacebarTextColor);
- paint.setAlpha(mSpacebarTextAlpha);
+ paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
canvas.drawText(language, width / 2, baseline - descent, paint);
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 442413c0c..5c1808613 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -79,8 +79,12 @@ public class ProximityInfo {
final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo();
spellCheckerProximityInfo.mNativeProximityInfo =
spellCheckerProximityInfo.setProximityInfoNative("",
- SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, (480 / 10), proximity,
- 0, null, null, null, null, null, null, null, null);
+ SpellCheckerProximityInfo.ROW_SIZE,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT,
+ 1, proximity, 0, null, null, null, null, null, null, null, null);
return spellCheckerProximityInfo;
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index dfc8c8e9d..a9df1ce12 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -55,6 +55,8 @@ public class BinaryDictionary extends Dictionary {
public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING =
new Flag(R.bool.config_require_umlaut_processing, 0x1);
+ public static final Flag FLAG_REQUIRES_FRENCH_LIGATURES_PROCESSING =
+ new Flag(R.bool.config_require_ligatures_processing, 0x4);
// FULL_EDIT_DISTANCE is a flag that forces the dictionary to use full words
// when computing edit distance, instead of the default behavior of stopping
@@ -77,6 +79,7 @@ public class BinaryDictionary extends Dictionary {
// actual value will be read from the configuration/extra value at run time for
// the configuration at dictionary creation time.
FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING,
+ FLAG_REQUIRES_FRENCH_LIGATURES_PROCESSING,
};
private int mFlags = 0;
@@ -202,9 +205,11 @@ public class BinaryDictionary extends Dictionary {
Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE);
for (int i = 0; i < codesSize; i++) {
- int[] alternatives = codes.getCodesAt(i);
- System.arraycopy(alternatives, 0, mInputCodes, i * MAX_PROXIMITY_CHARS_SIZE,
- Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE));
+ final int[] alternatives = codes.getCodesAt(i);
+ if (alternatives == null || alternatives.length < 1) {
+ continue;
+ }
+ mInputCodes[i] = alternatives[0];
}
Arrays.fill(outputChars, (char) 0);
Arrays.fill(scores, 0);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 48fb79809..7903820f7 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -197,7 +197,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
- private final KeyboardSwitcher mKeyboardSwitcher;
+ /* package for tests */ final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
private VoiceProxy mVoiceProxy;
private boolean mShouldSwitchToLastSubtype = true;
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 9f23f174f..cabf68099 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -20,8 +20,6 @@ import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
-import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService;
-import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -127,12 +125,8 @@ public class WordComposer {
final int[] codes;
final int keyX;
final int keyY;
- if (x == KeyboardActionListener.SPELL_CHECKER_COORDINATE
- || y == KeyboardActionListener.SPELL_CHECKER_COORDINATE) {
- // only used for tests in InputLogicTests
- addKeyForSpellChecker(primaryCode, AndroidSpellCheckerService.SCRIPT_LATIN);
- return;
- } else if (x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
+ if (null == keyDetector
+ || x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
|| y == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
|| x == KeyboardActionListener.NOT_A_TOUCH_COORDINATE
|| y == KeyboardActionListener.NOT_A_TOUCH_COORDINATE) {
@@ -149,27 +143,6 @@ public class WordComposer {
add(primaryCode, codes, keyX, keyY);
}
- // TODO: remove this function
- public void addKeyForSpellChecker(int primaryCode, int script) {
- final int[] proximities;
- final int proximityIndex =
- SpellCheckerProximityInfo.getIndexOfCodeForScript(primaryCode, script);
- if (-1 == proximityIndex) {
- proximities = new int[] { primaryCode };
- } else {
- // TODO: an initial examination seems to reveal this is actually used
- // read-only. It should be possible to compute the arrays statically once
- // and skip doing a copy each time here.
- proximities = Arrays.copyOfRange(
- SpellCheckerProximityInfo.getProximityForScript(script),
- proximityIndex,
- proximityIndex + SpellCheckerProximityInfo.ROW_SIZE);
- }
- add(primaryCode, proximities,
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
- }
-
/**
* Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
* the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
@@ -197,8 +170,7 @@ public class WordComposer {
/**
* Internal method to retrieve reasonable proximity info for a character.
*/
- private void addKeyInfo(final int codePoint, final Keyboard keyboard,
- final KeyDetector keyDetector) {
+ private void addKeyInfo(final int codePoint, final Keyboard keyboard) {
for (final Key key : keyboard.mKeys) {
if (key.mCode == codePoint) {
final int x = key.mX + key.mWidth / 2;
@@ -216,27 +188,16 @@ public class WordComposer {
* Set the currently composing word to the one passed as an argument.
* This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity.
*/
- private void setComposingWord(final CharSequence word, final Keyboard keyboard,
- final KeyDetector keyDetector) {
+ public void setComposingWord(final CharSequence word, final Keyboard keyboard) {
reset();
final int length = word.length();
for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) {
int codePoint = Character.codePointAt(word, i);
- addKeyInfo(codePoint, keyboard, keyDetector);
+ addKeyInfo(codePoint, keyboard);
}
}
/**
- * Shortcut for the above method, this will create a new KeyDetector for the passed keyboard.
- */
- public void setComposingWord(final CharSequence word, final Keyboard keyboard) {
- final KeyDetector keyDetector = new KeyDetector(0);
- keyDetector.setKeyboard(keyboard, 0, 0);
- keyDetector.setProximityCorrectionEnabled(true);
- setComposingWord(word, keyboard, keyDetector);
- }
-
- /**
* Delete the last keystroke as a result of hitting backspace.
*/
public void deleteLast() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 9dc294edf..64fcd7f1a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -64,6 +64,19 @@ public class FusionDictionary implements Iterable<Word> {
mWord = word;
mFrequency = frequency;
}
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(new Object[] { mWord, mFrequency });
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof WeightedString)) return false;
+ WeightedString w = (WeightedString)o;
+ return mWord.equals(w.mWord) && mFrequency == w.mFrequency;
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/latin/makedict/Word.java b/java/src/com/android/inputmethod/latin/makedict/Word.java
index c2c01e1f8..4e0ab1049 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Word.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Word.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Utility class for a word with a frequency.
@@ -32,6 +33,8 @@ public class Word implements Comparable<Word> {
final ArrayList<WeightedString> mShortcutTargets;
final ArrayList<WeightedString> mBigrams;
+ private int mHashCode = 0;
+
public Word(final String word, final int frequency,
final ArrayList<WeightedString> shortcutTargets,
final ArrayList<WeightedString> bigrams, final boolean isShortcutOnly) {
@@ -42,6 +45,16 @@ public class Word implements Comparable<Word> {
mIsShortcutOnly = isShortcutOnly;
}
+ private static int computeHashCode(Word word) {
+ return Arrays.hashCode(new Object[] {
+ word.mWord,
+ word.mFrequency,
+ word.mIsShortcutOnly,
+ word.mShortcutTargets.hashCode(),
+ word.mBigrams.hashCode()
+ });
+ }
+
/**
* Three-way comparison.
*
@@ -63,10 +76,20 @@ public class Word implements Comparable<Word> {
*/
@Override
public boolean equals(Object o) {
+ if (o == this) return true;
if (!(o instanceof Word)) return false;
Word w = (Word)o;
return mFrequency == w.mFrequency && mWord.equals(w.mWord)
+ && mIsShortcutOnly == w.mIsShortcutOnly
&& mShortcutTargets.equals(w.mShortcutTargets)
&& mBigrams.equals(w.mBigrams);
}
+
+ @Override
+ public int hashCode() {
+ if (mHashCode == 0) {
+ mHashCode = computeHashCode(this);
+ }
+ return mHashCode;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 35a5c0f52..973a448ee 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -570,7 +570,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService
final WordComposer composer = new WordComposer();
final int length = text.length();
for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
- composer.addKeyForSpellChecker(text.codePointAt(i), mScript);
+ final int codePoint = text.codePointAt(i);
+ // The getXYForCodePointAndScript method returns (Y << 16) + X
+ final int xy = SpellCheckerProximityInfo.getXYForCodePointAndScript(
+ codePoint, mScript);
+ composer.add(codePoint, xy & 0xFFFF, xy >> 16, null);
}
final int capitalizeType = getCapitalizationType(text);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index db3544987..7627700dd 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -30,11 +30,16 @@ public class SpellCheckerProximityInfo {
// as the size of the passed array afterwards so they can't be different.
final public static int ROW_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
+ // The number of keys in a row of the grid used by the spell checker.
+ final public static int PROXIMITY_GRID_WIDTH = 11;
+ // The number of rows in the grid used by the spell checker.
+ final public static int PROXIMITY_GRID_HEIGHT = 3;
+
// Helper methods
final protected static void buildProximityIndices(final int[] proximity,
final TreeMap<Integer, Integer> indices) {
for (int i = 0; i < proximity.length; i += ROW_SIZE) {
- if (NUL != proximity[i]) indices.put(proximity[i], i);
+ if (NUL != proximity[i]) indices.put(proximity[i], i / ROW_SIZE);
}
}
final protected static int computeIndex(final int characterCode,
@@ -64,6 +69,9 @@ public class SpellCheckerProximityInfo {
// to English, many spelling errors consist of the last vowel of the word being wrong
// because in English vowels tend to merge with each other in pronunciation.
final static int[] PROXIMITY = {
+ // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
+ // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
+ // The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
'q', 'w', 's', 'a', 'z', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'w', 'q', 'a', 's', 'd', 'e', 'x', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'e', 'w', 's', 'd', 'f', 'r', 'a', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
@@ -76,9 +84,10 @@ public class SpellCheckerProximityInfo {
'p', 'o', 'l', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // Proximity for row 2. See comment above about size.
'a', 'z', 'x', 's', 'w', 'q', 'e', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
's', 'q', 'a', 'z', 'x', 'c', 'd', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL,
+ 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'f', 'e', 'd', 'c', 'v', 'b', 'g', 't', 'r', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'g', 'r', 'f', 'v', 'b', 'n', 'h', 'y', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'h', 't', 'g', 'b', 'n', 'm', 'j', 'u', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -88,6 +97,7 @@ public class SpellCheckerProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // Proximity for row 3. See comment above about size.
'z', 'a', 's', 'd', 'x', 't', 'g', 'h', 'j', 'u', 'q', 'e', NUL, NUL, NUL, NUL,
'x', 'z', 'a', 's', 'd', 'c', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'c', 'x', 's', 'd', 'f', 'v', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -109,9 +119,12 @@ public class SpellCheckerProximityInfo {
private static class Cyrillic {
final private static TreeMap<Integer, Integer> INDICES = new TreeMap<Integer, Integer>();
+ // TODO: The following table is solely based on the keyboard layout. Consult with Russian
+ // speakers on commonly misspelled words/letters.
final static int[] PROXIMITY = {
- // TODO: This table is solely based on the keyboard layout. Consult with Russian
- // speakers on commonly misspelled words/letters.
+ // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
+ // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
+ // The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
'й', 'ц', 'ф', 'ы', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ц', 'й', 'ф', 'ы', 'в', 'у', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'у', 'ц', 'ы', 'в', 'а', 'к', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -124,6 +137,7 @@ public class SpellCheckerProximityInfo {
'з', 'щ', 'д', 'ж', 'э', 'х', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'х', 'з', 'ж', 'э', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // Proximity for row 2. See comment above about size.
'ф', 'й', 'ц', 'ы', 'я', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ы', 'й', 'ц', 'у', 'ф', 'в', 'я', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'в', 'ц', 'у', 'к', 'ы', 'а', 'я', 'ч', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -136,6 +150,7 @@ public class SpellCheckerProximityInfo {
'ж', 'щ', 'з', 'х', 'д', 'э', 'б', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'э', 'з', 'х', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // Proximity for row 3. See comment above about size.
'я', 'ф', 'ы', 'в', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'ч', 'ы', 'в', 'а', 'я', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'с', 'в', 'а', 'п', 'ч', 'м', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -166,14 +181,29 @@ public class SpellCheckerProximityInfo {
throw new RuntimeException("Wrong script supplied: " + script);
}
}
- public static int getIndexOfCodeForScript(final int characterCode, final int script) {
+
+ private static int getIndexOfCodeForScript(final int codePoint, final int script) {
switch (script) {
case AndroidSpellCheckerService.SCRIPT_LATIN:
- return Latin.getIndexOf(characterCode);
+ return Latin.getIndexOf(codePoint);
case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
- return Cyrillic.getIndexOf(characterCode);
+ return Cyrillic.getIndexOf(codePoint);
default:
throw new RuntimeException("Wrong script supplied: " + script);
}
}
+
+ // Returns (Y << 16) + X to avoid creating a temporary object. This is okay because
+ // X and Y are limited to PROXIMITY_GRID_WIDTH resp. PROXIMITY_GRID_HEIGHT which is very
+ // inferior to 1 << 16
+ public static int getXYForCodePointAndScript(final int codePoint, final int script) {
+ final int index = getIndexOfCodeForScript(codePoint, script);
+ final int y = index / PROXIMITY_GRID_WIDTH;
+ final int x = index % PROXIMITY_GRID_WIDTH;
+ if (y > PROXIMITY_GRID_HEIGHT) {
+ // Safety check, should be entirely useless
+ throw new RuntimeException("Wrong y coordinate in spell checker proximity");
+ }
+ return (y << 16) + x;
+ }
}
diff --git a/native/src/defines.h b/native/src/defines.h
index 21215343e..e882c3714 100644
--- a/native/src/defines.h
+++ b/native/src/defines.h
@@ -171,7 +171,7 @@ static inline void prof_out(void) {
#define EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO -2
#define PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO -3
#define ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO -4
-#define NOT_A_INDEX -1
+#define NOT_AN_INDEX -1
#define NOT_A_FREQUENCY -1
#define KEYCODE_SPACE ' '
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index 4d03f3274..c00c4c20f 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -129,7 +129,8 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
return false;
}
-bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) {
+bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) const {
+ if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
const int left = mKeyXCoordinates[keyId];
const int top = mKeyYCoordinates[keyId];
const int right = left + mKeyWidths[keyId] + 1;
@@ -137,7 +138,8 @@ bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) {
return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
}
-int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) {
+int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) const {
+ if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
const int left = mKeyXCoordinates[keyId];
const int top = mKeyYCoordinates[keyId];
const int right = left + mKeyWidths[keyId];
@@ -150,58 +152,60 @@ int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int
}
void ProximityInfo::calculateNearbyKeyCodes(
- const int x, const int y, const int32_t primaryKey, int *inputCodes) {
+ const int x, const int y, const int32_t primaryKey, int *inputCodes) const {
int insertPos = 0;
inputCodes[insertPos++] = primaryKey;
const int startIndex = getStartIndexFromCoordinates(x, y);
- for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
- const int32_t c = mProximityCharsArray[startIndex + i];
- if (c < KEYCODE_SPACE || c == primaryKey) {
- continue;
+ if (startIndex >= 0) {
+ for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
+ const int32_t c = mProximityCharsArray[startIndex + i];
+ if (c < KEYCODE_SPACE || c == primaryKey) {
+ continue;
+ }
+ const int keyIndex = getKeyIndex(c);
+ const bool onKey = isOnKey(keyIndex, x, y);
+ const int distance = squaredDistanceToEdge(keyIndex, x, y);
+ if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) {
+ inputCodes[insertPos++] = c;
+ if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
+ if (DEBUG_DICT) {
+ assert(false);
+ }
+ return;
+ }
+ }
}
- const int keyIndex = getKeyIndex(c);
- const bool onKey = isOnKey(keyIndex, x, y);
- const int distance = squaredDistanceToEdge(keyIndex, x, y);
- if (c >= KEYCODE_SPACE && (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE)) {
- inputCodes[insertPos++] = c;
+ const int additionalProximitySize =
+ AdditionalProximityChars::getAdditionalCharsSize(&mLocaleStr, primaryKey);
+ if (additionalProximitySize > 0) {
+ inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
if (DEBUG_DICT) {
assert(false);
}
return;
}
- }
- }
- const int additionalProximitySize =
- AdditionalProximityChars::getAdditionalCharsSize(&mLocaleStr, primaryKey);
- if (additionalProximitySize > 0) {
- inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
- if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
- if (DEBUG_DICT) {
- assert(false);
- }
- return;
- }
- const int32_t* additionalProximityChars =
- AdditionalProximityChars::getAdditionalChars(&mLocaleStr, primaryKey);
- for (int j = 0; j < additionalProximitySize; ++j) {
- const int32_t ac = additionalProximityChars[j];
- int k = 0;
- for (; k < insertPos; ++k) {
- if ((int)ac == inputCodes[k]) {
- break;
+ const int32_t* additionalProximityChars =
+ AdditionalProximityChars::getAdditionalChars(&mLocaleStr, primaryKey);
+ for (int j = 0; j < additionalProximitySize; ++j) {
+ const int32_t ac = additionalProximityChars[j];
+ int k = 0;
+ for (; k < insertPos; ++k) {
+ if ((int)ac == inputCodes[k]) {
+ break;
+ }
}
- }
- if (k < insertPos) {
- continue;
- }
- inputCodes[insertPos++] = ac;
- if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
- if (DEBUG_DICT) {
- assert(false);
+ if (k < insertPos) {
+ continue;
+ }
+ inputCodes[insertPos++] = ac;
+ if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
+ if (DEBUG_DICT) {
+ assert(false);
+ }
+ return;
}
- return;
}
}
}
@@ -211,14 +215,13 @@ void ProximityInfo::calculateNearbyKeyCodes(
}
}
-// TODO: Calculate nearby codes here.
void ProximityInfo::setInputParams(const int32_t* inputCodes, const int inputLength,
const int* xCoordinates, const int* yCoordinates) {
memset(mInputCodes, 0,
MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE * sizeof(mInputCodes[0]));
for (int i = 0; i < inputLength; ++i) {
- const int32_t primaryKey = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE];
+ const int32_t primaryKey = inputCodes[i];
const int x = xCoordinates[i];
const int y = yCoordinates[i];
int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE];
@@ -303,7 +306,7 @@ inline float square(const float x) { return x * x; }
float ProximityInfo::calculateNormalizedSquaredDistance(
const int keyIndex, const int inputIndex) const {
- if (keyIndex == NOT_A_INDEX) {
+ if (keyIndex == NOT_AN_INDEX) {
return NOT_A_DISTANCE_FLOAT;
}
if (!hasSweetSpotData(keyIndex)) {
@@ -324,11 +327,11 @@ bool ProximityInfo::hasInputCoordinates() const {
int ProximityInfo::getKeyIndex(const int c) const {
if (KEY_COUNT == 0) {
// We do not have the coordinate data
- return NOT_A_INDEX;
+ return NOT_AN_INDEX;
}
const unsigned short baseLowerC = toBaseLowerCase(c);
if (baseLowerC > MAX_CHAR_CODE) {
- return NOT_A_INDEX;
+ return NOT_AN_INDEX;
}
return mCodeToKeyIndex[baseLowerC];
}
diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h
index cdc5a3d43..c1eefeacc 100644
--- a/native/src/proximity_info.h
+++ b/native/src/proximity_info.h
@@ -92,10 +92,10 @@ class ProximityInfo {
// the radius of the key is assigned to zero.
return mSweetSpotRadii[keyIndex] > 0.0;
}
- bool isOnKey(const int keyId, const int x, const int y);
- int squaredDistanceToEdge(const int keyId, const int x, const int y);
+ bool isOnKey(const int keyId, const int x, const int y) const;
+ int squaredDistanceToEdge(const int keyId, const int x, const int y) const;
void calculateNearbyKeyCodes(
- const int x, const int y, const int32_t primaryKey, int *inputCodes);
+ const int x, const int y, const int32_t primaryKey, int *inputCodes) const;
const int MAX_PROXIMITY_CHARS_SIZE;
const int KEYBOARD_WIDTH;
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index 563541dce..d21413d8b 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -34,16 +34,20 @@ const UnigramDictionary::digraph_t UnigramDictionary::GERMAN_UMLAUT_DIGRAPHS[] =
{ 'o', 'e', 0x00F6 }, // U+00F6 : LATIN SMALL LETTER O WITH DIAERESIS
{ 'u', 'e', 0x00FC } }; // U+00FC : LATIN SMALL LETTER U WITH DIAERESIS
+const UnigramDictionary::digraph_t UnigramDictionary::FRENCH_LIGATURES_DIGRAPHS[] =
+ { { 'a', 'e', 0x00E6 }, // U+00E6 : LATIN SMALL LETTER AE
+ { 'o', 'e', 0x0153 } }; // U+0153 : LATIN SMALL LIGATURE OE
+
// TODO: check the header
UnigramDictionary::UnigramDictionary(const uint8_t* const streamStart, int typedLetterMultiplier,
int fullWordMultiplier, int maxWordLength, int maxWords, int maxProximityChars,
const bool isLatestDictVersion)
: DICT_ROOT(streamStart), MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
- MAX_PROXIMITY_CHARS(maxProximityChars), IS_LATEST_DICT_VERSION(isLatestDictVersion),
+ IS_LATEST_DICT_VERSION(isLatestDictVersion),
TYPED_LETTER_MULTIPLIER(typedLetterMultiplier), FULL_WORD_MULTIPLIER(fullWordMultiplier),
// TODO : remove this variable.
ROOT_POS(0),
- BYTES_IN_ONE_CHAR(MAX_PROXIMITY_CHARS * sizeof(int)),
+ BYTES_IN_ONE_CHAR(sizeof(int)),
MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH) {
if (DEBUG_DICT) {
AKLOGI("UnigramDictionary - constructor");
@@ -53,9 +57,8 @@ UnigramDictionary::UnigramDictionary(const uint8_t* const streamStart, int typed
UnigramDictionary::~UnigramDictionary() {
}
-static inline unsigned int getCodesBufferSize(const int *codes, const int codesSize,
- const int MAX_PROXIMITY_CHARS) {
- return sizeof(*codes) * MAX_PROXIMITY_CHARS * codesSize;
+static inline unsigned int getCodesBufferSize(const int *codes, const int codesSize) {
+ return sizeof(*codes) * codesSize;
}
// TODO: This needs to take a const unsigned short* and not tinker with its contents
@@ -73,7 +76,7 @@ int UnigramDictionary::getDigraphReplacement(const int *codes, const int i, cons
// Search for the first char of some digraph
int lastDigraphIndex = -1;
- const int thisChar = codes[i * MAX_PROXIMITY_CHARS];
+ const int thisChar = codes[i];
for (lastDigraphIndex = digraphsSize - 1; lastDigraphIndex >= 0; --lastDigraphIndex) {
if (thisChar == digraphs[lastDigraphIndex].first) break;
}
@@ -81,7 +84,7 @@ int UnigramDictionary::getDigraphReplacement(const int *codes, const int i, cons
if (lastDigraphIndex < 0) return 0;
// It's an interesting digraph if the second char matches too.
- if (digraphs[lastDigraphIndex].second == codes[(i + 1) * MAX_PROXIMITY_CHARS]) {
+ if (digraphs[lastDigraphIndex].second == codes[i + 1]) {
return digraphs[lastDigraphIndex].replacement;
} else {
return 0;
@@ -102,7 +105,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
WordsPriorityQueuePool *queuePool,
const digraph_t* const digraphs, const unsigned int digraphsSize) {
- const int startIndex = (codesDest - codesBuffer) / MAX_PROXIMITY_CHARS;
+ const int startIndex = codesDest - codesBuffer;
if (currentDepth < MAX_DIGRAPH_SEARCH_DEPTH) {
for (int i = 0; i < codesRemain; ++i) {
xCoordinatesBuffer[startIndex + i] = xcoordinates[codesBufferSize - codesRemain + i];
@@ -126,19 +129,18 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
replacementCodePoint;
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates,
codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags,
- codesSrc + (i + 1) * MAX_PROXIMITY_CHARS, codesRemain - i - 1,
- currentDepth + 1, codesDest + i * MAX_PROXIMITY_CHARS, correction,
+ codesSrc + i + 1, codesRemain - i - 1,
+ currentDepth + 1, codesDest + i, correction,
queuePool, digraphs, digraphsSize);
// Copy the second char of the digraph in place, then continue processing on
// the remaining part of the word.
// In our example, after "pru" in the buffer copy the "e", and continue on "fen"
- memcpy(codesDest + i * MAX_PROXIMITY_CHARS, codesSrc + i * MAX_PROXIMITY_CHARS,
- BYTES_IN_ONE_CHAR);
+ memcpy(codesDest + i, codesSrc + i, BYTES_IN_ONE_CHAR);
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates,
codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags,
- codesSrc + i * MAX_PROXIMITY_CHARS, codesRemain - i, currentDepth + 1,
- codesDest + i * MAX_PROXIMITY_CHARS, correction, queuePool,
+ codesSrc + i, codesRemain - i, currentDepth + 1,
+ codesDest + i, correction, queuePool,
digraphs, digraphsSize);
return;
}
@@ -173,7 +175,7 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo,
Correction* masterCorrection = correction;
if (REQUIRES_GERMAN_UMLAUT_PROCESSING & flags)
{ // Incrementally tune the word and try all possibilities
- int codesBuffer[getCodesBufferSize(codes, codesSize, MAX_PROXIMITY_CHARS)];
+ int codesBuffer[getCodesBufferSize(codes, codesSize)];
int xCoordinatesBuffer[codesSize];
int yCoordinatesBuffer[codesSize];
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer,
@@ -181,6 +183,15 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo,
codesSize, flags, codes, codesSize, 0, codesBuffer, masterCorrection, queuePool,
GERMAN_UMLAUT_DIGRAPHS,
sizeof(GERMAN_UMLAUT_DIGRAPHS) / sizeof(GERMAN_UMLAUT_DIGRAPHS[0]));
+ } else if (REQUIRES_FRENCH_LIGATURES_PROCESSING & flags) {
+ int codesBuffer[getCodesBufferSize(codes, codesSize)];
+ int xCoordinatesBuffer[codesSize];
+ int yCoordinatesBuffer[codesSize];
+ getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer,
+ xCoordinatesBuffer, yCoordinatesBuffer,
+ codesSize, flags, codes, codesSize, 0, codesBuffer, masterCorrection, queuePool,
+ FRENCH_LIGATURES_DIGRAPHS,
+ sizeof(FRENCH_LIGATURES_DIGRAPHS) / sizeof(FRENCH_LIGATURES_DIGRAPHS[0]));
} else { // Normal processing
getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, codesSize, flags,
masterCorrection, queuePool);
@@ -414,7 +425,7 @@ bool UnigramDictionary::getSubStringSuggestion(
if (inputWordStartPos > 0) {
const int offset = inputWordStartPos;
initSuggestions(proximityInfo, &xcoordinates[offset], &ycoordinates[offset],
- codes + offset * MAX_PROXIMITY_CHARS, inputWordLength, correction);
+ codes + offset, inputWordLength, correction);
queuePool->clearSubQueue(currentWordIndex);
getSuggestionCandidates(useFullEditDistance, inputWordLength, correction,
queuePool, false, MAX_ERRORS_FOR_TWO_WORDS, currentWordIndex);
@@ -573,10 +584,6 @@ void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximit
const bool hasAutoCorrectionCandidate) {
if (inputLength >= MAX_WORD_LENGTH) return;
if (DEBUG_DICT) {
- // MAX_PROXIMITY_CHARS_SIZE in ProximityInfo.java should be 16
- assert(MAX_PROXIMITY_CHARS == 16);
- }
- if (DEBUG_DICT) {
AKLOGI("--- Suggest multiple words");
}
diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h
index b85913ffb..86bda77cb 100644
--- a/native/src/unigram_dictionary.h
+++ b/native/src/unigram_dictionary.h
@@ -143,7 +143,6 @@ class UnigramDictionary {
const uint8_t* const DICT_ROOT;
const int MAX_WORD_LENGTH;
const int MAX_WORDS;
- const int MAX_PROXIMITY_CHARS;
const bool IS_LATEST_DICT_VERSION;
const int TYPED_LETTER_MULTIPLIER;
const int FULL_WORD_MULTIPLIER;
@@ -157,9 +156,11 @@ class UnigramDictionary {
// Please update both at the same time.
enum {
REQUIRES_GERMAN_UMLAUT_PROCESSING = 0x1,
- USE_FULL_EDIT_DISTANCE = 0x2
+ USE_FULL_EDIT_DISTANCE = 0x2,
+ REQUIRES_FRENCH_LIGATURES_PROCESSING = 0x4
};
static const digraph_t GERMAN_UMLAUT_DIGRAPHS[];
+ static const digraph_t FRENCH_LIGATURES_DIGRAPHS[];
// Still bundled members
unsigned short mWord[MAX_WORD_LENGTH_INTERNAL];// TODO: remove
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
new file mode 100644
index 000000000..81f744da9
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012 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.Keyboard;
+
+public class BlueUnderlineTests extends InputTestsBase {
+
+ public void testBlueUnderline() {
+ final String STRING_TO_TYPE = "tgis";
+ final int EXPECTED_SPAN_START = 0;
+ final int EXPECTED_SPAN_END = 4;
+ type(STRING_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ final Span span = new Span(mTextView.getText());
+ assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart);
+ assertEquals("show blue underline, span end", EXPECTED_SPAN_END, span.mEnd);
+ assertEquals("show blue underline, span color", true, span.isAutoCorrectionIndicator());
+ }
+
+ public void testBlueUnderlineDisappears() {
+ final String STRING_1_TO_TYPE = "tgis";
+ final String STRING_2_TO_TYPE = "q";
+ final int EXPECTED_SPAN_START = 0;
+ final int EXPECTED_SPAN_END = 5;
+ type(STRING_1_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ type(STRING_2_TO_TYPE);
+ // We haven't have time to look into the dictionary yet, so the line should still be
+ // blue to avoid any flicker.
+ final Span spanBefore = new Span(mTextView.getText());
+ assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart);
+ assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd);
+ assertEquals("extend blue underline, span color", true,
+ spanBefore.isAutoCorrectionIndicator());
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span
+ final Span spanAfter = new Span(mTextView.getText());
+ assertNull("hide blue underline", spanAfter.mSpan);
+ }
+
+ public void testBlueUnderlineOnBackspace() {
+ final String STRING_TO_TYPE = "tgis";
+ final int EXPECTED_SPAN_START = 0;
+ final int EXPECTED_SPAN_END = 4;
+ type(STRING_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ type(Keyboard.CODE_SPACE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ type(Keyboard.CODE_DELETE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ type(Keyboard.CODE_DELETE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ final Span span = new Span(mTextView.getText());
+ assertEquals("show blue underline after backspace, span start",
+ EXPECTED_SPAN_START, span.mStart);
+ assertEquals("show blue underline after backspace, span end",
+ EXPECTED_SPAN_END, span.mEnd);
+ assertEquals("show blue underline after backspace, span color", true,
+ span.isAutoCorrectionIndicator());
+ }
+
+ public void testBlueUnderlineDisappearsWhenCursorMoved() {
+ final String STRING_TO_TYPE = "tgis";
+ final int NEW_CURSOR_POSITION = 0;
+ type(STRING_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ // Simulate the onUpdateSelection() event
+ mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
+ runMessages();
+ // Here the blue underline has been set. testBlueUnderline() is testing for this already,
+ // so let's not test it here again.
+ // Now simulate the user moving the cursor.
+ mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
+ mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ final Span span = new Span(mTextView.getText());
+ assertNull("blue underline removed when cursor is moved", span.mSpan);
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java b/tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java
new file mode 100644
index 000000000..5db120d82
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/InputLogicFrenchTests.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 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.Keyboard;
+
+public class InputLogicFrenchTests extends InputTestsBase {
+
+ public void testAutoCorrectForFrench() {
+ final String STRING_TO_TYPE = "irq ";
+ final String EXPECTED_RESULT = "ira ";
+ changeLanguage("fr");
+ type(STRING_TO_TYPE);
+ assertEquals("simple auto-correct for French", EXPECTED_RESULT,
+ mTextView.getText().toString());
+ }
+
+ public void testManualPickThenSeparatorForFrench() {
+ final String WORD1_TO_TYPE = "test";
+ final String WORD2_TO_TYPE = "!";
+ final String EXPECTED_RESULT = "test !";
+ changeLanguage("fr");
+ type(WORD1_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
+ type(WORD2_TO_TYPE);
+ assertEquals("manual pick then separator for French", EXPECTED_RESULT,
+ mTextView.getText().toString());
+ }
+
+ public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() {
+ final String WORD_TO_TYPE = "test ";
+ final String PUNCTUATION_FROM_STRIP = "!";
+ final String EXPECTED_RESULT = "test !!";
+ changeLanguage("fr");
+ type(WORD_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ assertTrue("type word then type space should display punctuation strip",
+ mLatinIME.isShowingPunctuationList());
+ mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+ mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+ assertEquals("type word then type space then punctuation from strip twice for French",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 595fe5b10..11eb6ab19 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -16,183 +16,9 @@
package com.android.inputmethod.latin;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.preference.PreferenceManager;
-import android.test.ServiceTestCase;
-import android.text.InputType;
-import android.text.SpannableStringBuilder;
-import android.text.style.SuggestionSpan;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-import android.view.View;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardActionListener;
-import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService; // for proximity info
-import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class InputLogicTests extends ServiceTestCase<LatinIME> {
-
- private static final String PREF_DEBUG_MODE = "debug_mode";
-
- private LatinIME mLatinIME;
- private TextView mTextView;
- private InputConnection mInputConnection;
-
- public InputLogicTests() {
- super(LatinIME.class);
- }
-
- // returns the previous setting value
- private boolean setDebugMode(final boolean mode) {
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
- final boolean previousDebugSetting = prefs.getBoolean(PREF_DEBUG_MODE, false);
- final SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(PREF_DEBUG_MODE, true);
- editor.commit();
- return previousDebugSetting;
- }
- @Override
- protected void setUp() {
- try {
- super.setUp();
- } catch (Exception e) {
- e.printStackTrace();
- }
- mTextView = new TextView(getContext());
- mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
- mTextView.setEnabled(true);
- setupService();
- mLatinIME = getService();
- final boolean previousDebugSetting = setDebugMode(true);
- mLatinIME.onCreate();
- setDebugMode(previousDebugSetting);
- final EditorInfo ei = new EditorInfo();
- ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
- final InputConnection ic = mTextView.onCreateInputConnection(ei);
- ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
- final LayoutInflater inflater =
- (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- final ViewGroup vg = new FrameLayout(getContext());
- final View inputView = inflater.inflate(R.layout.input_view, vg);
- mLatinIME.setInputView(inputView);
- mLatinIME.onBindInput();
- mLatinIME.onCreateInputView();
- mLatinIME.onStartInputView(ei, false);
- mLatinIME.onCreateInputMethodInterface().startInput(ic, ei);
- mInputConnection = ic;
- changeLanguage("en_US");
- }
-
- // We need to run the messages added to the handler from LatinIME. The only way to do
- // that is to call Looper#loop() on the right looper, so we're going to get the looper
- // object and call #loop() here. The messages in the handler actually run on the UI
- // thread of the keyboard by design of the handler, so we want to call it synchronously
- // on the same thread that the tests are running on to mimic the actual environment as
- // closely as possible.
- // Now, Looper#loop() never exits in normal operation unless the Looper#quit() method
- // is called, so we need to do that at the right time so that #loop() returns at some
- // point and we don't end up in an infinite loop.
- // After we quit, the looper is still technically ready to process more messages but
- // the handler will refuse to enqueue any because #quit() has been called and it
- // explicitly tests for it on message enqueuing, so we'll have to reset it so that
- // it lets us continue normal operation.
- private void runMessages() {
- // Here begins deep magic.
- final Looper looper = mLatinIME.mHandler.getLooper();
- mLatinIME.mHandler.post(new Runnable() {
- @Override
- public void run() {
- looper.quit();
- }
- });
- // The only way to get out of Looper#loop() is to call #quit() on it (or on its queue).
- // Once #quit() is called remaining messages are not processed, which is why we post
- // a message that calls it instead of calling it directly.
- looper.loop();
-
- // Once #quit() has been called, the message queue has an "mQuiting" field that prevents
- // any subsequent post in this queue. However the queue itself is still fully functional!
- // If we have a way of resetting "queue.mQuiting" then we can continue using it as normal,
- // coming back to this method to run the messages.
- MessageQueue queue = looper.getQueue();
- try {
- // However there is no way of doing it externally, and mQuiting is private.
- // So... get out the big guns.
- java.lang.reflect.Field f = MessageQueue.class.getDeclaredField("mQuiting");
- f.setAccessible(true); // What do you mean "private"?
- f.setBoolean(queue, false);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- // type(int) and type(String): helper methods to send a code point resp. a string to LatinIME.
- private void type(final int codePoint) {
- // onPressKey and onReleaseKey are explicitly deactivated here, but they do happen in the
- // code (although multitouch/slide input and other factors make the sequencing complicated).
- // They are supposed to be entirely deconnected from the input logic from LatinIME point of
- // view and only delegates to the parts of the code that care. So we don't include them here
- // to keep these tests as pinpoint as possible and avoid bringing it too many dependencies,
- // but keep them in mind if something breaks. Commenting them out as is should work.
- //mLatinIME.onPressKey(codePoint);
- mLatinIME.onCodeInput(codePoint,
- KeyboardActionListener.SPELL_CHECKER_COORDINATE,
- KeyboardActionListener.SPELL_CHECKER_COORDINATE);
- //mLatinIME.onReleaseKey(codePoint, false);
- }
-
- private void type(final String stringToType) {
- for (int i = 0; i < stringToType.length(); i = stringToType.offsetByCodePoints(i, 1)) {
- type(stringToType.codePointAt(i));
- }
- }
-
- private void waitForDictionaryToBeLoaded() {
- int remainingAttempts = 10;
- while (remainingAttempts > 0 && !mLatinIME.mSuggest.hasMainDictionary()) {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- // Don't do much
- } finally {
- --remainingAttempts;
- }
- }
- if (!mLatinIME.mSuggest.hasMainDictionary()) {
- throw new RuntimeException("Can't initialize the main dictionary");
- }
- }
-
- private void changeLanguage(final String locale) {
- SubtypeSwitcher.getInstance().updateSubtype(
- new ArbitrarySubtype(locale, LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE));
- waitForDictionaryToBeLoaded();
- }
-
-
- // Helper to avoid writing the try{}catch block each time
- private static void sleep(final int milliseconds) {
- try {
- Thread.sleep(milliseconds);
- } catch (InterruptedException e) {}
- }
+public class InputLogicTests extends InputTestsBase {
public void testTypeWord() {
final String WORD_TO_TYPE = "abcd";
@@ -283,15 +109,6 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
assertEquals("simple auto-correct", EXPECTED_RESULT, mTextView.getText().toString());
}
- public void testAutoCorrectForFrench() {
- final String STRING_TO_TYPE = "irq ";
- final String EXPECTED_RESULT = "ira ";
- changeLanguage("fr");
- type(STRING_TO_TYPE);
- assertEquals("simple auto-correct for French", EXPECTED_RESULT,
- mTextView.getText().toString());
- }
-
public void testAutoCorrectWithPeriod() {
final String STRING_TO_TYPE = "tgis.";
final String EXPECTED_RESULT = "this.";
@@ -379,71 +196,6 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
assertEquals("manual pick then separator", EXPECTED_RESULT, mTextView.getText().toString());
}
- public void testWordThenSpaceThenPunctuationFromStripTwice() {
- final String WORD_TO_TYPE = "this ";
- final String PUNCTUATION_FROM_STRIP = "!";
- final String EXPECTED_RESULT = "this!! ";
- type(WORD_TO_TYPE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- assertTrue("type word then type space should display punctuation strip",
- mLatinIME.isShowingPunctuationList());
- mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
- mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
- assertEquals("type word then type space then punctuation from strip twice", EXPECTED_RESULT,
- mTextView.getText().toString());
- }
-
- public void testManualPickThenSeparatorForFrench() {
- final String WORD1_TO_TYPE = "test";
- final String WORD2_TO_TYPE = "!";
- final String EXPECTED_RESULT = "test !";
- changeLanguage("fr");
- type(WORD1_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
- type(WORD2_TO_TYPE);
- assertEquals("manual pick then separator for French", EXPECTED_RESULT,
- mTextView.getText().toString());
- }
-
- public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() {
- final String WORD_TO_TYPE = "test ";
- final String PUNCTUATION_FROM_STRIP = "!";
- final String EXPECTED_RESULT = "test !!";
- changeLanguage("fr");
- type(WORD_TO_TYPE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- assertTrue("type word then type space should display punctuation strip",
- mLatinIME.isShowingPunctuationList());
- mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
- mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
- assertEquals("type word then type space then punctuation from strip twice for French",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testWordThenSpaceThenPunctuationFromKeyboardTwice() {
- final String WORD_TO_TYPE = "this !!";
- final String EXPECTED_RESULT = "this !!";
- type(WORD_TO_TYPE);
- assertEquals("manual pick then space then punctuation from keyboard twice", EXPECTED_RESULT,
- mTextView.getText().toString());
- }
-
- public void testManualPickThenPunctuationFromStripTwiceThenType() {
- final String WORD1_TO_TYPE = "this";
- final String WORD2_TO_TYPE = "is";
- final String PUNCTUATION_FROM_STRIP = "!";
- final String EXPECTED_RESULT = "this!! is";
- type(WORD1_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
- mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
- type(WORD2_TO_TYPE);
- assertEquals("pick word then pick punctuation twice then type", EXPECTED_RESULT,
- mTextView.getText().toString());
- }
-
public void testManualPickThenSpaceThenType() {
final String WORD1_TO_TYPE = "this";
final String WORD2_TO_TYPE = " is";
@@ -469,17 +221,6 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
mTextView.getText().toString());
}
- public void testManualPickThenManualPickWithPunctAtStart() {
- final String WORD1_TO_TYPE = "this";
- final String WORD2_TO_PICK = "!is";
- final String EXPECTED_RESULT = "this!is";
- type(WORD1_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
- mLatinIME.pickSuggestionManually(1, WORD2_TO_PICK);
- assertEquals("manual pick then manual pick a word with punct at start", EXPECTED_RESULT,
- mTextView.getText().toString());
- }
-
public void testDeleteWholeComposingWord() {
final String WORD_TO_TYPE = "this";
type(WORD_TO_TYPE);
@@ -488,197 +229,5 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
}
assertEquals("delete whole composing word", "", mTextView.getText().toString());
}
-
- public void testManuallyPickedWordThenColon() {
- final String WORD_TO_TYPE = "this";
- final String PUNCTUATION = ":";
- final String EXPECTED_RESULT = "this:";
- type(WORD_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
- type(PUNCTUATION);
- assertEquals("manually pick word then colon",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testManuallyPickedWordThenOpenParen() {
- final String WORD_TO_TYPE = "this";
- final String PUNCTUATION = "(";
- final String EXPECTED_RESULT = "this (";
- type(WORD_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
- type(PUNCTUATION);
- assertEquals("manually pick word then open paren",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testManuallyPickedWordThenCloseParen() {
- final String WORD_TO_TYPE = "this";
- final String PUNCTUATION = ")";
- final String EXPECTED_RESULT = "this)";
- type(WORD_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
- type(PUNCTUATION);
- assertEquals("manually pick word then close paren",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testManuallyPickedWordThenSmiley() {
- final String WORD_TO_TYPE = "this";
- final String SPECIAL_KEY = ":-)";
- final String EXPECTED_RESULT = "this :-)";
- type(WORD_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
- mLatinIME.onTextInput(SPECIAL_KEY);
- assertEquals("manually pick word then press the smiley key",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testManuallyPickedWordThenDotCom() {
- final String WORD_TO_TYPE = "this";
- final String SPECIAL_KEY = ".com";
- final String EXPECTED_RESULT = "this.com";
- type(WORD_TO_TYPE);
- mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
- mLatinIME.onTextInput(SPECIAL_KEY);
- assertEquals("manually pick word then press the .com key",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testTypeWordTypeDotThenPressDotCom() {
- final String WORD_TO_TYPE = "this.";
- final String SPECIAL_KEY = ".com";
- final String EXPECTED_RESULT = "this.com";
- type(WORD_TO_TYPE);
- mLatinIME.onTextInput(SPECIAL_KEY);
- assertEquals("type word type dot then press the .com key",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testAutoCorrectionWithSingleQuoteInside() {
- final String WORD_TO_TYPE = "you'f ";
- final String EXPECTED_RESULT = "you'd ";
- type(WORD_TO_TYPE);
- assertEquals("auto-correction with single quote inside",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- public void testAutoCorrectionWithSingleQuotesAround() {
- final String WORD_TO_TYPE = "'tgis' ";
- final String EXPECTED_RESULT = "'this' ";
- type(WORD_TO_TYPE);
- assertEquals("auto-correction with single quotes around",
- EXPECTED_RESULT, mTextView.getText().toString());
- }
-
- // A helper class to ease span tests
- private static class Span {
- final SpannableStringBuilder mInputText;
- final SuggestionSpan mSpan;
- final int mStart;
- final int mEnd;
- // The supplied CharSequence should be an instance of SpannableStringBuilder,
- // and it should contain exactly zero or one SuggestionSpan. Otherwise, an exception
- // is thrown.
- public Span(final CharSequence inputText) {
- mInputText = (SpannableStringBuilder)inputText;
- final SuggestionSpan[] spans =
- mInputText.getSpans(0, mInputText.length(), SuggestionSpan.class);
- if (0 == spans.length) {
- mSpan = null;
- mStart = -1;
- mEnd = -1;
- } else if (1 == spans.length) {
- mSpan = spans[0];
- mStart = mInputText.getSpanStart(mSpan);
- mEnd = mInputText.getSpanEnd(mSpan);
- } else {
- throw new RuntimeException("Expected one SuggestionSpan, found " + spans.length);
- }
- }
- public boolean isAutoCorrectionIndicator() {
- return 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & mSpan.getFlags());
- }
- }
-
- static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200; // The message is posted with a 100 ms delay
- public void testBlueUnderline() {
- final String STRING_TO_TYPE = "tgis";
- final int EXPECTED_SPAN_START = 0;
- final int EXPECTED_SPAN_END = 4;
- type(STRING_TO_TYPE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- final Span span = new Span(mTextView.getText());
- assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart);
- assertEquals("show blue underline, span end", EXPECTED_SPAN_END, span.mEnd);
- assertEquals("show blue underline, span color", true, span.isAutoCorrectionIndicator());
- }
-
- public void testBlueUnderlineDisappears() {
- final String STRING_1_TO_TYPE = "tgis";
- final String STRING_2_TO_TYPE = "q";
- final int EXPECTED_SPAN_START = 0;
- final int EXPECTED_SPAN_END = 5;
- type(STRING_1_TO_TYPE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- type(STRING_2_TO_TYPE);
- // We haven't have time to look into the dictionary yet, so the line should still be
- // blue to avoid any flicker.
- final Span spanBefore = new Span(mTextView.getText());
- assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart);
- assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd);
- assertEquals("extend blue underline, span color", true,
- spanBefore.isAutoCorrectionIndicator());
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span
- final Span spanAfter = new Span(mTextView.getText());
- assertNull("hide blue underline", spanAfter.mSpan);
- }
-
- public void testBlueUnderlineOnBackspace() {
- final String STRING_TO_TYPE = "tgis";
- final int EXPECTED_SPAN_START = 0;
- final int EXPECTED_SPAN_END = 4;
- type(STRING_TO_TYPE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- type(Keyboard.CODE_SPACE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- type(Keyboard.CODE_DELETE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- type(Keyboard.CODE_DELETE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- final Span span = new Span(mTextView.getText());
- assertEquals("show blue underline after backspace, span start",
- EXPECTED_SPAN_START, span.mStart);
- assertEquals("show blue underline after backspace, span end",
- EXPECTED_SPAN_END, span.mEnd);
- assertEquals("show blue underline after backspace, span color", true,
- span.isAutoCorrectionIndicator());
- }
-
- public void testBlueUnderlineDisappearsWhenCursorMoved() {
- final String STRING_TO_TYPE = "tgis";
- final int NEW_CURSOR_POSITION = 0;
- type(STRING_TO_TYPE);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- // Simulate the onUpdateSelection() event
- mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
- runMessages();
- // Here the blue underline has been set. testBlueUnderline() is testing for this already,
- // so let's not test it here again.
- // Now simulate the user moving the cursor.
- mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
- mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
- sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
- runMessages();
- final Span span = new Span(mTextView.getText());
- assertNull("blue underline removed when cursor is moved", span.mSpan);
- }
// TODO: Add some tests for non-BMP characters
}
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
new file mode 100644
index 000000000..2c63993d7
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2012 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 android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.preference.PreferenceManager;
+import android.test.ServiceTestCase;
+import android.text.InputType;
+import android.text.SpannableStringBuilder;
+import android.text.style.SuggestionSpan;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class InputTestsBase extends ServiceTestCase<LatinIME> {
+
+ private static final String PREF_DEBUG_MODE = "debug_mode";
+
+ // The message that sets the underline is posted with a 100 ms delay
+ protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200;
+
+ protected LatinIME mLatinIME;
+ protected Keyboard mKeyboard;
+ protected TextView mTextView;
+ protected InputConnection mInputConnection;
+
+ // A helper class to ease span tests
+ public static class Span {
+ final SpannableStringBuilder mInputText;
+ final SuggestionSpan mSpan;
+ final int mStart;
+ final int mEnd;
+ // The supplied CharSequence should be an instance of SpannableStringBuilder,
+ // and it should contain exactly zero or one SuggestionSpan. Otherwise, an exception
+ // is thrown.
+ public Span(final CharSequence inputText) {
+ mInputText = (SpannableStringBuilder)inputText;
+ final SuggestionSpan[] spans =
+ mInputText.getSpans(0, mInputText.length(), SuggestionSpan.class);
+ if (0 == spans.length) {
+ mSpan = null;
+ mStart = -1;
+ mEnd = -1;
+ } else if (1 == spans.length) {
+ mSpan = spans[0];
+ mStart = mInputText.getSpanStart(mSpan);
+ mEnd = mInputText.getSpanEnd(mSpan);
+ } else {
+ throw new RuntimeException("Expected one SuggestionSpan, found " + spans.length);
+ }
+ }
+ public boolean isAutoCorrectionIndicator() {
+ return 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & mSpan.getFlags());
+ }
+ }
+
+ public InputTestsBase() {
+ super(LatinIME.class);
+ }
+
+ // returns the previous setting value
+ protected boolean setDebugMode(final boolean mode) {
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
+ final boolean previousDebugSetting = prefs.getBoolean(PREF_DEBUG_MODE, false);
+ final SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(PREF_DEBUG_MODE, true);
+ editor.commit();
+ return previousDebugSetting;
+ }
+
+ @Override
+ protected void setUp() {
+ try {
+ super.setUp();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ mTextView = new TextView(getContext());
+ mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
+ mTextView.setEnabled(true);
+ setupService();
+ mLatinIME = getService();
+ final boolean previousDebugSetting = setDebugMode(true);
+ mLatinIME.onCreate();
+ setDebugMode(previousDebugSetting);
+ final EditorInfo ei = new EditorInfo();
+ ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
+ final InputConnection ic = mTextView.onCreateInputConnection(ei);
+ ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
+ final LayoutInflater inflater =
+ (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ final ViewGroup vg = new FrameLayout(getContext());
+ final View inputView = inflater.inflate(R.layout.input_view, vg);
+ mLatinIME.setInputView(inputView);
+ mLatinIME.onBindInput();
+ mLatinIME.onCreateInputView();
+ mLatinIME.onStartInputView(ei, false);
+ mLatinIME.onCreateInputMethodInterface().startInput(ic, ei);
+ mInputConnection = ic;
+ mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();
+ changeLanguage("en_US");
+ }
+
+ // We need to run the messages added to the handler from LatinIME. The only way to do
+ // that is to call Looper#loop() on the right looper, so we're going to get the looper
+ // object and call #loop() here. The messages in the handler actually run on the UI
+ // thread of the keyboard by design of the handler, so we want to call it synchronously
+ // on the same thread that the tests are running on to mimic the actual environment as
+ // closely as possible.
+ // Now, Looper#loop() never exits in normal operation unless the Looper#quit() method
+ // is called, so we need to do that at the right time so that #loop() returns at some
+ // point and we don't end up in an infinite loop.
+ // After we quit, the looper is still technically ready to process more messages but
+ // the handler will refuse to enqueue any because #quit() has been called and it
+ // explicitly tests for it on message enqueuing, so we'll have to reset it so that
+ // it lets us continue normal operation.
+ protected void runMessages() {
+ // Here begins deep magic.
+ final Looper looper = mLatinIME.mHandler.getLooper();
+ mLatinIME.mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ looper.quit();
+ }
+ });
+ // The only way to get out of Looper#loop() is to call #quit() on it (or on its queue).
+ // Once #quit() is called remaining messages are not processed, which is why we post
+ // a message that calls it instead of calling it directly.
+ looper.loop();
+
+ // Once #quit() has been called, the message queue has an "mQuiting" field that prevents
+ // any subsequent post in this queue. However the queue itself is still fully functional!
+ // If we have a way of resetting "queue.mQuiting" then we can continue using it as normal,
+ // coming back to this method to run the messages.
+ MessageQueue queue = looper.getQueue();
+ try {
+ // However there is no way of doing it externally, and mQuiting is private.
+ // So... get out the big guns.
+ java.lang.reflect.Field f = MessageQueue.class.getDeclaredField("mQuiting");
+ f.setAccessible(true); // What do you mean "private"?
+ f.setBoolean(queue, false);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // type(int) and type(String): helper methods to send a code point resp. a string to LatinIME.
+ protected void type(final int codePoint) {
+ // onPressKey and onReleaseKey are explicitly deactivated here, but they do happen in the
+ // code (although multitouch/slide input and other factors make the sequencing complicated).
+ // They are supposed to be entirely deconnected from the input logic from LatinIME point of
+ // view and only delegates to the parts of the code that care. So we don't include them here
+ // to keep these tests as pinpoint as possible and avoid bringing it too many dependencies,
+ // but keep them in mind if something breaks. Commenting them out as is should work.
+ //mLatinIME.onPressKey(codePoint);
+ for (final Key key : mKeyboard.mKeys) {
+ if (key.mCode == codePoint) {
+ final int x = key.mX + key.mWidth / 2;
+ final int y = key.mY + key.mHeight / 2;
+ mLatinIME.onCodeInput(codePoint, x, y);
+ return;
+ }
+ }
+ mLatinIME.onCodeInput(codePoint,
+ KeyboardActionListener.SPELL_CHECKER_COORDINATE,
+ KeyboardActionListener.SPELL_CHECKER_COORDINATE);
+ //mLatinIME.onReleaseKey(codePoint, false);
+ }
+
+ protected void type(final String stringToType) {
+ for (int i = 0; i < stringToType.length(); i = stringToType.offsetByCodePoints(i, 1)) {
+ type(stringToType.codePointAt(i));
+ }
+ }
+
+ protected void waitForDictionaryToBeLoaded() {
+ int remainingAttempts = 10;
+ while (remainingAttempts > 0 && !mLatinIME.mSuggest.hasMainDictionary()) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ // Don't do much
+ } finally {
+ --remainingAttempts;
+ }
+ }
+ if (!mLatinIME.mSuggest.hasMainDictionary()) {
+ throw new RuntimeException("Can't initialize the main dictionary");
+ }
+ }
+
+ protected void changeLanguage(final String locale) {
+ SubtypeSwitcher.getInstance().updateSubtype(
+ new ArbitrarySubtype(locale, LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE));
+ waitForDictionaryToBeLoaded();
+ }
+
+
+ // Helper to avoid writing the try{}catch block each time
+ protected static void sleep(final int milliseconds) {
+ try {
+ Thread.sleep(milliseconds);
+ } catch (InterruptedException e) {}
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/PunctuationTests.java b/tests/src/com/android/inputmethod/latin/PunctuationTests.java
new file mode 100644
index 000000000..cc549bceb
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/PunctuationTests.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 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.Keyboard;
+
+public class PunctuationTests extends InputTestsBase {
+
+ public void testWordThenSpaceThenPunctuationFromStripTwice() {
+ final String WORD_TO_TYPE = "this ";
+ final String PUNCTUATION_FROM_STRIP = "!";
+ final String EXPECTED_RESULT = "this!! ";
+ type(WORD_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
+ runMessages();
+ assertTrue("type word then type space should display punctuation strip",
+ mLatinIME.isShowingPunctuationList());
+ mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+ mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+ assertEquals("type word then type space then punctuation from strip twice", EXPECTED_RESULT,
+ mTextView.getText().toString());
+ }
+
+ public void testWordThenSpaceThenPunctuationFromKeyboardTwice() {
+ final String WORD_TO_TYPE = "this !!";
+ final String EXPECTED_RESULT = "this !!";
+ type(WORD_TO_TYPE);
+ assertEquals("manual pick then space then punctuation from keyboard twice", EXPECTED_RESULT,
+ mTextView.getText().toString());
+ }
+
+ public void testManualPickThenPunctuationFromStripTwiceThenType() {
+ final String WORD1_TO_TYPE = "this";
+ final String WORD2_TO_TYPE = "is";
+ final String PUNCTUATION_FROM_STRIP = "!";
+ final String EXPECTED_RESULT = "this!! is";
+ type(WORD1_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+ mLatinIME.pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
+ type(WORD2_TO_TYPE);
+ assertEquals("pick word then pick punctuation twice then type", EXPECTED_RESULT,
+ mTextView.getText().toString());
+ }
+
+ public void testManualPickThenManualPickWithPunctAtStart() {
+ final String WORD1_TO_TYPE = "this";
+ final String WORD2_TO_PICK = "!is";
+ final String EXPECTED_RESULT = "this!is";
+ type(WORD1_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD1_TO_TYPE);
+ mLatinIME.pickSuggestionManually(1, WORD2_TO_PICK);
+ assertEquals("manual pick then manual pick a word with punct at start", EXPECTED_RESULT,
+ mTextView.getText().toString());
+ }
+
+ public void testManuallyPickedWordThenColon() {
+ final String WORD_TO_TYPE = "this";
+ final String PUNCTUATION = ":";
+ final String EXPECTED_RESULT = "this:";
+ type(WORD_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+ type(PUNCTUATION);
+ assertEquals("manually pick word then colon",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testManuallyPickedWordThenOpenParen() {
+ final String WORD_TO_TYPE = "this";
+ final String PUNCTUATION = "(";
+ final String EXPECTED_RESULT = "this (";
+ type(WORD_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+ type(PUNCTUATION);
+ assertEquals("manually pick word then open paren",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testManuallyPickedWordThenCloseParen() {
+ final String WORD_TO_TYPE = "this";
+ final String PUNCTUATION = ")";
+ final String EXPECTED_RESULT = "this)";
+ type(WORD_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+ type(PUNCTUATION);
+ assertEquals("manually pick word then close paren",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testManuallyPickedWordThenSmiley() {
+ final String WORD_TO_TYPE = "this";
+ final String SPECIAL_KEY = ":-)";
+ final String EXPECTED_RESULT = "this :-)";
+ type(WORD_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+ mLatinIME.onTextInput(SPECIAL_KEY);
+ assertEquals("manually pick word then press the smiley key",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testManuallyPickedWordThenDotCom() {
+ final String WORD_TO_TYPE = "this";
+ final String SPECIAL_KEY = ".com";
+ final String EXPECTED_RESULT = "this.com";
+ type(WORD_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
+ mLatinIME.onTextInput(SPECIAL_KEY);
+ assertEquals("manually pick word then press the .com key",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testTypeWordTypeDotThenPressDotCom() {
+ final String WORD_TO_TYPE = "this.";
+ final String SPECIAL_KEY = ".com";
+ final String EXPECTED_RESULT = "this.com";
+ type(WORD_TO_TYPE);
+ mLatinIME.onTextInput(SPECIAL_KEY);
+ assertEquals("type word type dot then press the .com key",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testAutoCorrectionWithSingleQuoteInside() {
+ final String WORD_TO_TYPE = "you'f ";
+ final String EXPECTED_RESULT = "you'd ";
+ type(WORD_TO_TYPE);
+ assertEquals("auto-correction with single quote inside",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+
+ public void testAutoCorrectionWithSingleQuotesAround() {
+ final String WORD_TO_TYPE = "'tgis' ";
+ final String EXPECTED_RESULT = "'this' ";
+ type(WORD_TO_TYPE);
+ assertEquals("auto-correction with single quotes around",
+ EXPECTED_RESULT, mTextView.getText().toString());
+ }
+}