aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/values-ar/donottranslate-altchars.xml15
-rw-r--r--java/res/values-es/donottranslate-altchars.xml1
-rw-r--r--java/res/values/attrs.xml4
-rw-r--r--java/res/values/dimens.xml2
-rw-r--r--java/res/values/donottranslate-altchars.xml15
-rw-r--r--java/res/values/donottranslate.xml22
-rw-r--r--java/res/values/strings.xml6
-rw-r--r--java/res/xml-sw600dp/kbd_key_styles.xml6
-rw-r--r--java/res/xml-sw600dp/kbd_qwerty_f2.xml8
-rw-r--r--java/res/xml-sw600dp/kbd_rows_symbols.xml4
-rw-r--r--java/res/xml-sw768dp/kbd_number.xml2
-rw-r--r--java/res/xml-sw768dp/kbd_phone.xml2
-rw-r--r--java/res/xml-sw768dp/kbd_phone_shift.xml2
-rw-r--r--java/res/xml-sw768dp/kbd_qwerty_row4.xml2
-rw-r--r--java/res/xml-sw768dp/kbd_rows_symbols.xml6
-rw-r--r--java/res/xml-sw768dp/kbd_rows_symbols_shift.xml2
-rw-r--r--java/res/xml/kbd_key_styles.xml89
-rw-r--r--java/res/xml/kbd_qwerty_f1.xml84
-rw-r--r--java/res/xml/kbd_qwerty_row4.xml38
-rw-r--r--java/res/xml/kbd_settings_or_tab.xml45
-rw-r--r--java/res/xml/kbd_symbols_f1.xml29
-rw-r--r--java/res/xml/kbd_symbols_row4.xml42
-rw-r--r--java/res/xml/kbd_symbols_shift_row4.xml36
-rw-r--r--java/res/xml/prefs.xml10
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java58
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java51
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java40
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java269
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java60
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java18
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java52
-rw-r--r--java/src/com/android/inputmethod/latin/CandidateView.java9
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java112
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java27
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java24
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java20
-rw-r--r--native/Android.mk4
-rw-r--r--native/src/correction_state.cpp52
-rw-r--r--native/src/correction_state.h52
-rw-r--r--native/src/proximity_info.cpp8
-rw-r--r--native/src/proximity_info.h5
-rw-r--r--native/src/unigram_dictionary.cpp340
-rw-r--r--native/src/unigram_dictionary.h47
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestTests.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestTestsBase.java21
-rw-r--r--tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java8
52 files changed, 810 insertions, 989 deletions
diff --git a/java/res/values-ar/donottranslate-altchars.xml b/java/res/values-ar/donottranslate-altchars.xml
index b72ed501a..970666538 100644
--- a/java/res/values-ar/donottranslate-altchars.xml
+++ b/java/res/values-ar/donottranslate-altchars.xml
@@ -31,9 +31,7 @@
\u064b: ARABIC FATHATAN
\u064d: ARABIC KASRATAN -->
<string name="alternates_for_punctuation">"\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0651,\u0652,\u064c,\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
- <string name="alternates_for_web_tab_punctuation">".,\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0651,\u0652,\u064c,\u0640,\u064f,\u064e,\u0650,\u064b,\u064d"</string>
<integer name="popup_keyboard_column_for_punctuation">9</integer>
- <integer name="popup_keyboard_column_for_web_punctuation">10</integer>
<string name="keyhintlabel_for_punctuation">\u064b</string>
<string name="keylabel_for_symbols_1">"١"</string>
<string name="keylabel_for_symbols_2">"٢"</string>
@@ -55,15 +53,18 @@
<string name="alternates_for_symbols_8">8</string>
<string name="alternates_for_symbols_9">9</string>
<string name="alternates_for_symbols_0">0,ⁿ,∅</string>
- <string name="keylabel_for_symbols_comma">\u060c</string>
- <string name="keylabel_for_symbols_f1">\u060c</string>
+ <string name="keylabel_for_comma">\u060c</string>
+ <string name="keylabel_for_f1">\u060c</string>
<string name="keylabel_for_symbols_question">\u061f</string>
<string name="keylabel_for_symbols_semicolon">\u061b</string>
<!-- \u066a: ARABIC PERCENT SIGN -->
<string name="keylabel_for_symbols_percent">\u066a</string>
- <string name="alternates_for_symbols_comma">,</string>
- <!-- @icon/5 is iconsSettingsKey -->
- <string name="alternates_for_symbols_f1">"\\,,\@icon/5|\@integer/key_settings"</string>
+ <string name="alternates_for_comma">,</string>
+ <string name="alternates_for_f1">,</string>
+ <!-- @icon/5 is iconSettingsKey -->
+ <string name="alternates_for_f1_settings">\\,,\@icon/5|\@integer/key_settings</string>
+ <!-- @icon/10 is iconTabKey -->
+ <string name="alternates_for_f1_navigate">\\,,\@icon/10|\@integer/key_tab</string>
<string name="alternates_for_symbols_question">\?,¿</string>
<string name="alternates_for_symbols_semicolon">;</string>
<string name="alternates_for_symbols_percent">%,‰</string>
diff --git a/java/res/values-es/donottranslate-altchars.xml b/java/res/values-es/donottranslate-altchars.xml
index 16111ec42..e1f849f62 100644
--- a/java/res/values-es/donottranslate-altchars.xml
+++ b/java/res/values-es/donottranslate-altchars.xml
@@ -26,5 +26,4 @@
<string name="alternates_for_n">ñ,ń</string>
<string name="alternates_for_c">ç,ć,č</string>
<string name="alternates_for_punctuation">"\\,,\?,!,¿,¡,:,-,\',\",),(,/,;,+,&amp;,\@"</string>
- <string name="alternates_for_web_tab_punctuation">".,\\,,\?,!,¿,¡,:,-,\',\",),(,/,;,+,&amp;,\@"</string>
</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e503d98a4..af7484fa8 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -266,8 +266,8 @@
<enum name="shortcutImeOrSettings" value="3" />
</attr>
<attr name="clobberSettingsKey" format="boolean" />
- <attr name="voiceKeyEnabled" format="boolean" />
- <attr name="hasVoiceKey" format="boolean" />
+ <attr name="shortcutKeyEnabled" format="boolean" />
+ <attr name="hasShortcutKey" format="boolean" />
<attr name="imeAction" format="enum">
<!-- This should be aligned with EditorInfo.IME_ACTION_* -->
<enum name="actionUnspecified" value="0" />
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index ff0458cfe..a66caa7bd 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -57,7 +57,7 @@
<dimen name="mini_keyboard_vertical_correction">-0.330in</dimen>
<!-- We use "inch", not "dip" because this value tries dealing with physical distance related
to user's finger. -->
- <dimen name="keyboard_vertical_correction">-0.05in</dimen>
+ <dimen name="keyboard_vertical_correction">0.0in</dimen>
<fraction name="key_letter_ratio">55%</fraction>
<fraction name="key_large_letter_ratio">65%</fraction>
diff --git a/java/res/values/donottranslate-altchars.xml b/java/res/values/donottranslate-altchars.xml
index 38d406c91..05026508b 100644
--- a/java/res/values/donottranslate-altchars.xml
+++ b/java/res/values/donottranslate-altchars.xml
@@ -50,9 +50,7 @@
<string name="alternates_for_currency_general">¢,$,€,£,¥,₱</string>
<string name="alternates_for_smiley">":-)|:-) ,:-(|:-( ,;-)|;-) ,:-P|:-P ,=-O|=-O ,:-*|:-* ,:O|:O ,B-)|B-) ,:-$|:-$ ,:-!|:-! ,:-[|:-[ ,O:-)|O:-) ,:-\\\\\\\\|:-\\\\\\\\ ,:\'(|:\'( ,:-D|:-D "</string>
<string name="alternates_for_punctuation">"\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
- <string name="alternates_for_web_tab_punctuation">".,\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
<integer name="popup_keyboard_column_for_punctuation">7</integer>
- <integer name="popup_keyboard_column_for_web_punctuation">8</integer>
<string name="keyhintlabel_for_punctuation"></string>
<string name="keylabel_for_popular_domain">".com"</string>
<!-- popular web domains for the locale - most popular, displayed on the keyboard -->
@@ -77,14 +75,17 @@
<string name="alternates_for_symbols_8"></string>
<string name="alternates_for_symbols_9"></string>
<string name="alternates_for_symbols_0">ⁿ,∅</string>
- <string name="keylabel_for_symbols_comma">,</string>
- <string name="keylabel_for_symbols_f1">,</string>
+ <string name="keylabel_for_comma">,</string>
+ <string name="keylabel_for_f1">,</string>
<string name="keylabel_for_symbols_question">\?</string>
<string name="keylabel_for_symbols_semicolon">;</string>
<string name="keylabel_for_symbols_percent">%</string>
- <string name="alternates_for_symbols_comma"></string>
- <!-- @icon/5 is iconsSettingsKey -->
- <string name="alternates_for_symbols_f1">\@icon/5|\@integer/key_settings</string>
+ <string name="alternates_for_comma"></string>
+ <string name="alternates_for_f1"></string>
+ <!-- @icon/5 is iconSettingsKey -->
+ <string name="alternates_for_f1_settings">\@icon/5|\@integer/key_settings</string>
+ <!-- @icon/10 is iconTabKey -->
+ <string name="alternates_for_f1_navigate">\@icon/10|\@integer/key_tab</string>
<string name="alternates_for_symbols_question">¿</string>
<string name="alternates_for_symbols_semicolon"></string>
<string name="alternates_for_symbols_percent">‰</string>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 4cf930399..b6adf6342 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -41,7 +41,7 @@
<!-- Label for "switch to phone numeric" key. Must be short to fit on key! -->
<string name="label_to_phone_numeric_key">123</string>
<!-- Label for "switch to phone symbols" key. Must be short to fit on key! -->
- <string name="label_to_phone_symbols_key">\uff0a\uff03\uff08</string>
+ <string name="label_to_phone_symbols_key">\uff0a\uff03</string>
<!-- Character for candidate divider (BOX DRAWINGS LIGHT VERTICAL) -->
<string name="label_candidate_divider">\u2502</string>
@@ -50,26 +50,6 @@
<!-- Character for close candidates pane (BLACK UP-POINTING TRIANGLE) -->
<string name="label_close_candidates_pane">\u25b2</string>
- <!-- Option values to show/hide the settings key in onscreen keyboard -->
- <!-- Automatically decide to show or hide the settings key -->
- <string name="settings_key_mode_auto">0</string>
- <!-- Always show the settings key -->
- <string name="settings_key_mode_always_show">1</string>
- <!-- Always hide the settings key -->
- <string name="settings_key_mode_always_hide">2</string>
- <!-- Array of the settings key mode values -->
- <string-array name="settings_key_modes_values">
- <item>@string/settings_key_mode_auto</item>
- <item>@string/settings_key_mode_always_show</item>
- <item>@string/settings_key_mode_always_hide</item>
- </string-array>
- <!-- Array of the settings key modes -->
- <string-array name="settings_key_modes">
- <item>@string/settings_key_mode_auto_name</item>
- <item>@string/settings_key_mode_always_show_name</item>
- <item>@string/settings_key_mode_always_hide_name</item>
- </string-array>
-
<!-- Always show the suggestion strip -->
<string name="prefs_suggestion_visibility_show_value">0</string>
<!-- Show the suggestion strip only on portrait mode -->
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index e5b85fec3..253581836 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -82,12 +82,6 @@
<!-- Option to show/hide the settings key -->
<string name="prefs_settings_key">Show settings key</string>
- <!-- Option to automatically decide to show/hide the settings key -->
- <string name="settings_key_mode_auto_name">Automatic</string>
- <!-- Option to always show the settings key -->
- <string name="settings_key_mode_always_show_name">Always show</string>
- <!-- Option to always hide the settings key -->
- <string name="settings_key_mode_always_hide_name">Always hide</string>
<!-- Option to decide the auto correction threshold score -->
<!-- Option to enable auto correction [CHAR LIMIT=20]-->
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/kbd_key_styles.xml
index f94309911..b679368a2 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/kbd_key_styles.xml
@@ -31,12 +31,12 @@
latin:clobberSettingsKey="true"
>
<key-style
- latin:styleName="settingsPopupStyle"
+ latin:styleName="f2PopupStyle"
latin:parentStyle="functionalKeyStyle" />
</case>
<default>
<key-style
- latin:styleName="settingsPopupStyle"
+ latin:styleName="f2PopupStyle"
latin:keyLabelOption="hasPopupHint"
latin:popupCharacters="\@icon/5|\@integer/key_settings"
latin:parentStyle="functionalKeyStyle" />
@@ -79,7 +79,7 @@
latin:code="@integer/key_shortcut"
latin:keyIcon="iconShortcutKey"
latin:keyIconPreview="iconPreviewShortcutKey"
- latin:parentStyle="settingsPopupStyle" />
+ latin:parentStyle="f2PopupStyle" />
<key-style
latin:styleName="settingsKeyStyle"
latin:code="@integer/key_settings"
diff --git a/java/res/xml-sw600dp/kbd_qwerty_f2.xml b/java/res/xml-sw600dp/kbd_qwerty_f2.xml
index 3ea11805f..b25afc12f 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_f2.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_f2.xml
@@ -34,13 +34,13 @@
>
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
latin:keyWidth="fillBoth" />
</case>
- <!-- voiceKeyEnabled="false" -->
+ <!-- shortcutKeyEnabled="false" -->
<default>
<Spacer />
</default>
@@ -51,13 +51,13 @@
>
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
latin:keyWidth="fillBoth" />
</case>
- <!-- voiceKeyEnabled="false" -->
+ <!-- shortcutKeyEnabled="false" -->
<default>
<Key
latin:keyStyle="settingsKeyStyle"
diff --git a/java/res/xml-sw600dp/kbd_rows_symbols.xml b/java/res/xml-sw600dp/kbd_rows_symbols.xml
index 9982f4575..058c97efd 100644
--- a/java/res/xml-sw600dp/kbd_rows_symbols.xml
+++ b/java/res/xml-sw600dp/kbd_rows_symbols.xml
@@ -128,8 +128,8 @@
latin:keyLabel="@string/keylabel_for_symbols_semicolon"
latin:popupCharacters="@string/alternates_for_symbols_semicolon" />
<Key
- latin:keyLabel="@string/keylabel_for_symbols_comma"
- latin:popupCharacters="@string/alternates_for_symbols_comma" />
+ latin:keyLabel="@string/keylabel_for_comma"
+ latin:popupCharacters="@string/alternates_for_comma" />
<Key
latin:keyLabel="." />
<Key
diff --git a/java/res/xml-sw768dp/kbd_number.xml b/java/res/xml-sw768dp/kbd_number.xml
index 1706eaac2..369e91a77 100644
--- a/java/res/xml-sw768dp/kbd_number.xml
+++ b/java/res/xml-sw768dp/kbd_number.xml
@@ -209,7 +209,7 @@
latin:keyStyle="numKeyStyle" />
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
diff --git a/java/res/xml-sw768dp/kbd_phone.xml b/java/res/xml-sw768dp/kbd_phone.xml
index 945b641ea..cf6790f79 100644
--- a/java/res/xml-sw768dp/kbd_phone.xml
+++ b/java/res/xml-sw768dp/kbd_phone.xml
@@ -127,7 +127,7 @@
latin:keyStyle="numKeyStyle" />
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
diff --git a/java/res/xml-sw768dp/kbd_phone_shift.xml b/java/res/xml-sw768dp/kbd_phone_shift.xml
index 693400e67..7f6271628 100644
--- a/java/res/xml-sw768dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw768dp/kbd_phone_shift.xml
@@ -139,7 +139,7 @@
latin:keyStyle="numKeyStyle" />
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row4.xml b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
index d463de9a6..1ff9d81f1 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
@@ -101,7 +101,7 @@
</switch>
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
diff --git a/java/res/xml-sw768dp/kbd_rows_symbols.xml b/java/res/xml-sw768dp/kbd_rows_symbols.xml
index 1d5bd9d15..2a01fe298 100644
--- a/java/res/xml-sw768dp/kbd_rows_symbols.xml
+++ b/java/res/xml-sw768dp/kbd_rows_symbols.xml
@@ -135,8 +135,8 @@
latin:keyLabel="@string/keylabel_for_symbols_semicolon"
latin:popupCharacters="@string/alternates_for_symbols_semicolon" />
<Key
- latin:keyLabel="@string/keylabel_for_symbols_comma"
- latin:popupCharacters="@string/alternates_for_symbols_comma" />
+ latin:keyLabel="@string/keylabel_for_comma"
+ latin:popupCharacters="@string/alternates_for_comma" />
<Key
latin:keyLabel="." />
<Key
@@ -180,7 +180,7 @@
latin:keyLabel="_" />
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
diff --git a/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml b/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
index 2219bdc92..5c120827f 100644
--- a/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
+++ b/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
@@ -155,7 +155,7 @@
latin:keyWidth="37.500%p" />
<switch>
<case
- latin:voiceKeyEnabled="true"
+ latin:shortcutKeyEnabled="true"
>
<Key
latin:keyStyle="shortcutKeyStyle"
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index 6436b27f0..5c4bf52b4 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -25,40 +25,43 @@
<key-style
latin:styleName="functionalKeyStyle"
latin:isFunctional="true" />
- <!-- Base key style for the key which may have settings key as popup key -->
+ <!-- Base key style for the key which may have settings or tab key as popup key. -->
<switch>
<case
latin:clobberSettingsKey="true"
>
<key-style
- latin:styleName="settingsPopupStyle"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="symbolsF1PopupStyle"
+ latin:styleName="f1PopupStyle"
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_f1"
latin:parentStyle="functionalKeyStyle" />
</case>
+ <!-- clobberSettingsKey="false -->
<case
- latin:clobberSettingsKey="false"
- latin:hasSettingsKey="true"
+ latin:hasSettingsKey="false"
>
<key-style
- latin:styleName="settingsPopupStyle"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="symbolsF1PopupStyle"
+ latin:styleName="f1PopupStyle"
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_f1_settings"
latin:parentStyle="functionalKeyStyle" />
</case>
- <!-- clobberSettingsKey="false" and hasSettingsKey="false" -->
- <default>
+ <!-- clobberSettingsKey="false" hasSettingsKey="true" -->
+ <case
+ latin:navigateAction="true"
+ >
<key-style
- latin:styleName="settingsPopupStyle"
+ latin:styleName="f1PopupStyle"
latin:keyLabelOption="hasPopupHint"
- latin:popupCharacters="\@icon/5|\@integer/key_settings"
+ latin:popupCharacters="@string/alternates_for_f1_navigate"
latin:parentStyle="functionalKeyStyle" />
+ </case>
+ <!-- clobberSettingsKey="false" and hasSettingsKey="true" navigateAction="false" -->
+ <default>
<key-style
- latin:styleName="symbolsF1PopupStyle"
+ latin:styleName="f1PopupStyle"
latin:keyLabelOption="hasPopupHint"
- latin:popupCharacters="@string/alternates_for_symbols_f1"
+ latin:popupCharacters="@string/alternates_for_f1"
latin:parentStyle="functionalKeyStyle" />
</default>
</switch>
@@ -79,6 +82,19 @@
<!-- Return key style -->
<switch>
<case
+ latin:mode="im"
+ >
+ <!-- Smiley key. -->
+ <key-style
+ latin:styleName="returnKeyStyle"
+ latin:keyLabel=":-)"
+ latin:keyOutputText=":-) "
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_smiley"
+ latin:maxPopupKeyboardColumn="5"
+ latin:parentStyle="functionalKeyStyle" />
+ </case>
+ <case
latin:imeAction="actionGo"
>
<key-style
@@ -136,19 +152,11 @@
latin:code="@integer/key_space"
latin:parentStyle="functionalKeyStyle" />
<key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyLabelOption="hasPopupHint"
- latin:popupCharacters="@string/alternates_for_smiley"
- latin:maxPopupKeyboardColumn="5"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
latin:styleName="shortcutKeyStyle"
latin:code="@integer/key_shortcut"
latin:keyIcon="iconShortcutKey"
latin:keyIconPreview="iconPreviewShortcutKey"
- latin:parentStyle="settingsPopupStyle" />
+ latin:parentStyle="f1PopupStyle" />
<key-style
latin:styleName="settingsKeyStyle"
latin:code="@integer/key_settings"
@@ -169,11 +177,12 @@
latin:keyIcon="iconTabKey"
latin:keyIconPreview="iconPreviewTabKey" />
<switch>
- <!-- When this qwerty keyboard has no voice key but voice key is enabled, then symbol
- keyboard will have mic key. That means we should use "?123mic" key here. -->
+ <!-- When this qwerty keyboard has no shortcut keys but shortcut key is enabled, then symbol
+ keyboard will have a shortcut key. That means we should use
+ iconToSymbolKeyWithShortcutKey here. -->
<case
- latin:voiceKeyEnabled="true"
- latin:hasVoiceKey="false"
+ latin:shortcutKeyEnabled="true"
+ latin:hasShortcutKey="false"
>
<key-style
latin:styleName="toSymbolKeyStyle"
@@ -224,29 +233,11 @@
</default>
</switch>
<key-style
- latin:styleName="basePunctuationKeyStyle"
+ latin:styleName="punctuationKeyStyle"
latin:keyLabel="."
latin:keyHintLabel="@string/keyhintlabel_for_punctuation"
latin:keyLabelOption="hasPopupHint"
latin:popupCharacters="@string/alternates_for_punctuation"
latin:maxPopupKeyboardColumn="@integer/popup_keyboard_column_for_punctuation"
latin:parentStyle="functionalKeyStyle" />
- <switch>
- <case
- latin:navigateAction="true"
- >
- <key-style
- latin:styleName="punctuationKeyStyle"
- latin:keyHintLabel="@string/keyhintlabel_for_punctuation"
- latin:keyLabelOption="hasPopupHint"
- latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
- latin:maxPopupKeyboardColumn="@integer/popup_keyboard_column_for_web_punctuation"
- latin:parentStyle="tabKeyStyle" />
- </case>
- <default>
- <key-style
- latin:styleName="punctuationKeyStyle"
- latin:parentStyle="basePunctuationKeyStyle" />
- </default>
- </switch>
</merge>
diff --git a/java/res/xml/kbd_qwerty_f1.xml b/java/res/xml/kbd_qwerty_f1.xml
index 1546f49c9..83b6ecc8d 100644
--- a/java/res/xml/kbd_qwerty_f1.xml
+++ b/java/res/xml/kbd_qwerty_f1.xml
@@ -23,7 +23,8 @@
>
<switch>
<case
- latin:hasSettingsKey="true"
+ latin:hasSettingsKey="false"
+ latin:navigateAction="false"
>
<switch>
<case
@@ -31,46 +32,30 @@
>
<Key
latin:keyLabel="/"
- latin:keyWidth="9.2%p"
- latin:keyStyle="settingsPopupStyle" />
+ latin:keyStyle="f1PopupStyle" />
</case>
<case
latin:mode="email"
>
<Key
latin:keyLabel="\@"
- latin:keyWidth="9.2%p"
- latin:keyStyle="settingsPopupStyle" />
+ latin:keyStyle="f1PopupStyle" />
+ </case>
+ <case
+ latin:hasShortcutKey="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle" />
</case>
+ <!-- latin:hasShortcutKey="false" -->
<default>
- <switch>
- <case
- latin:hasVoiceKey="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle"
- latin:keyWidth="9.2%p" />
- </case>
- <!-- latin:hasVoiceKey="false" -->
- <case
- latin:navigateAction="true"
- >
- <Key
- latin:keyLabel="."
- latin:keyWidth="9.2%p"
- latin:keyStyle="settingsPopupStyle" />
- </case>
- <default>
- <Key
- latin:keyLabel="@string/keylabel_for_symbols_comma"
- latin:keyWidth="9.2%p"
- latin:keyStyle="settingsPopupStyle" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="@string/keylabel_for_comma"
+ latin:keyStyle="f1PopupStyle" />
</default>
</switch>
</case>
- <!-- hasSettingsKey="false" -->
+ <!-- hasSettingsKey="true" or navigateAction="true" -->
<default>
<switch>
<case
@@ -78,37 +63,30 @@
>
<Key
latin:keyLabel="/"
- latin:keyStyle="settingsPopupStyle" />
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="f1PopupStyle" />
</case>
<case
latin:mode="email"
>
<Key
latin:keyLabel="\@"
- latin:keyStyle="settingsPopupStyle" />
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="f1PopupStyle" />
</case>
+ <case
+ latin:hasShortcutKey="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="9.2%p" />
+ </case>
+ <!-- hasShortcutKey="false" -->
<default>
- <switch>
- <case
- latin:hasVoiceKey="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle" />
- </case>
- <!-- latin:hasVoiceKey="false" -->
- <case
- latin:navigateAction="true"
- >
- <Key
- latin:keyLabel="."
- latin:keyStyle="settingsPopupStyle" />
- </case>
- <default>
- <Key
- latin:keyLabel="@string/keylabel_for_symbols_comma"
- latin:keyStyle="settingsPopupStyle" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="@string/keylabel_for_comma"
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="f1PopupStyle" />
</default>
</switch>
</default>
diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/kbd_qwerty_row4.xml
index 771333ca9..eb1e9b8b3 100644
--- a/java/res/xml/kbd_qwerty_row4.xml
+++ b/java/res/xml/kbd_qwerty_row4.xml
@@ -26,46 +26,38 @@
>
<switch>
<case
- latin:hasSettingsKey="true"
+ latin:hasSettingsKey="false"
+ latin:navigateAction="false"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyWidth="13.75%p" />
- <Key
- latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="9.2%p" />
+ latin:keyWidth="15%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="35.83%p" />
+ latin:keyWidth="50%p" />
<Key
- latin:keyStyle="punctuationKeyStyle"
- latin:keyWidth="9.2%p" />
+ latin:keyStyle="punctuationKeyStyle" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyWidth="fillRight" />
</case>
- <!-- latin:hasSettingsKey="false" -->
+ <!-- hasSettingsKey="true" or navigateAction="true" -->
<default>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyWidth="15%p" />
+ latin:keyWidth="13.75%p" />
+ <include
+ latin:keyboardLayout="@xml/kbd_settings_or_tab" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="50%p" />
- <Key
- latin:keyStyle="punctuationKeyStyle" />
- </default>
- </switch>
- <switch>
- <case
- latin:mode="im"
- >
+ latin:keyWidth="35.83%p" />
<Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="fillRight" />
- </case>
- <default>
+ latin:keyStyle="punctuationKeyStyle"
+ latin:keyWidth="9.2%p" />
<Key
latin:keyStyle="returnKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml/kbd_settings_or_tab.xml b/java/res/xml/kbd_settings_or_tab.xml
new file mode 100644
index 000000000..4a8bcc7a6
--- /dev/null
+++ b/java/res/xml/kbd_settings_or_tab.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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:hasSettingsKey="true"
+ >
+ <Key
+ latin:keyStyle="settingsKeyStyle"
+ latin:keyWidth="9.2%p" />
+ </case>
+ <!-- hasSettingsKey="false" -->
+ <case
+ latin:navigateAction="true"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyWidth="9.2%p" />
+ </case>
+ <!-- hasSettingsKey="false" and navigateAction="false" -->
+ <default>
+ <!-- No key. -->
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/kbd_symbols_f1.xml b/java/res/xml/kbd_symbols_f1.xml
index cebb4f0b2..0dd3d9109 100644
--- a/java/res/xml/kbd_symbols_f1.xml
+++ b/java/res/xml/kbd_symbols_f1.xml
@@ -23,39 +23,40 @@
>
<switch>
<case
- latin:hasSettingsKey="true"
+ latin:hasSettingsKey="false"
+ latin:navigateAction="false"
>
<switch>
<case
- latin:hasVoiceKey="true"
+ latin:hasShortcutKey="true"
>
<Key
- latin:keyStyle="shortcutKeyStyle"
- latin:keyWidth="9.2%p" />
+ latin:keyStyle="shortcutKeyStyle" />
</case>
- <!-- latin:hasVoiceKey="false" -->
+ <!-- latin:hasShortcutKey="false" -->
<default>
<Key
- latin:keyLabel="@string/keylabel_for_symbols_f1"
- latin:keyWidth="9.2%p"
- latin:keyStyle="symbolsF1PopupStyle" />
+ latin:keyLabel="@string/keylabel_for_f1"
+ latin:keyStyle="f1PopupStyle" />
</default>
</switch>
</case>
- <!-- hasSettingsKey="false" -->
+ <!-- hasSettingsKey="true" or navigateAction="true" -->
<default>
<switch>
<case
- latin:hasVoiceKey="true"
+ latin:hasShortcutKey="true"
>
<Key
- latin:keyStyle="shortcutKeyStyle" />
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="9.2%p" />
</case>
- <!-- latin:hasVoiceKey="false" -->
+ <!-- latin:hasShortcutKey="false" -->
<default>
<Key
- latin:keyLabel="@string/keylabel_for_symbols_f1"
- latin:keyStyle="symbolsF1PopupStyle" />
+ latin:keyLabel="@string/keylabel_for_f1"
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="f1PopupStyle" />
</default>
</switch>
</default>
diff --git a/java/res/xml/kbd_symbols_row4.xml b/java/res/xml/kbd_symbols_row4.xml
index 3fda8883e..864cf2b8e 100644
--- a/java/res/xml/kbd_symbols_row4.xml
+++ b/java/res/xml/kbd_symbols_row4.xml
@@ -26,46 +26,38 @@
>
<switch>
<case
- latin:hasSettingsKey="true"
+ latin:hasSettingsKey="false"
+ latin:navigateAction="false"
>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="13.75%p" />
- <Key
- latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="9.2%p" />
+ latin:keyWidth="15%p" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f1" />
+ latin:keyboardLayout="@xml/kbd_symbols_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="35.83%p" />
+ latin:keyWidth="50%p" />
<Key
- latin:keyStyle="basePunctuationKeyStyle"
- latin:keyWidth="9.2%p" />
+ latin:keyStyle="punctuationKeyStyle" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyWidth="fillRight" />
</case>
- <!-- latin:hasSettingsKey="false" -->
+ <!-- hasSettingsKey="true" or navigateAction="true" -->
<default>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="15%p" />
+ latin:keyWidth="13.75%p" />
<include
- latin:keyboardLayout="@xml/kbd_symbols_f1" />
+ latin:keyboardLayout="@xml/kbd_settings_or_tab" />
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="50%p" />
- <Key
- latin:keyStyle="basePunctuationKeyStyle" />
- </default>
- </switch>
- <switch>
- <case
- latin:mode="im"
- >
+ latin:keyWidth="35.83%p" />
<Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="fillRight" />
- </case>
- <default>
+ latin:keyStyle="punctuationKeyStyle"
+ latin:keyWidth="9.2%p" />
<Key
latin:keyStyle="returnKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/kbd_symbols_shift_row4.xml
index 35d444a75..9cb453fbc 100644
--- a/java/res/xml/kbd_symbols_shift_row4.xml
+++ b/java/res/xml/kbd_symbols_shift_row4.xml
@@ -26,53 +26,45 @@
>
<switch>
<case
- latin:hasSettingsKey="true"
+ latin:hasSettingsKey="false"
+ latin:navigateAction="false"
>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="13.75%p" />
- <Key
- latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="9.2%p" />
+ latin:keyWidth="15%p" />
<Key
latin:keyLabel="„"
latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
- latin:keyWidth="9.2%p"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="35.83%p" />
+ latin:keyWidth="50%p" />
<Key
latin:keyLabel="…"
- latin:keyWidth="9.2%p"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyWidth="fillRight" />
</case>
- <!-- latin:hasSettingsKey="false" -->
+ <!-- hasSettingsKey="true" or navigateAction="true" -->
<default>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="15%p" />
+ latin:keyWidth="13.75%p" />
+ <include
+ latin:keyboardLayout="@xml/kbd_settings_or_tab" />
<Key
latin:keyLabel="„"
latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
+ latin:keyWidth="9.2%p"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="50%p" />
+ latin:keyWidth="35.83%p" />
<Key
latin:keyLabel="…"
+ latin:keyWidth="9.2%p"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
- </default>
- </switch>
- <switch>
- <case
- latin:mode="im"
- >
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="fillRight" />
- </case>
- <default>
<Key
latin:keyStyle="returnKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index babbfaa8c..552e3cf4f 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -49,13 +49,11 @@
android:summary="@string/prefs_enable_recorrection_summary"
android:persistent="true"
android:defaultValue="@bool/config_default_recorrection_enabled" />
- <ListPreference
- android:key="settings_key"
+ <CheckBoxPreference
+ android:key="show_settings_key"
android:title="@string/prefs_settings_key"
android:persistent="true"
- android:entryValues="@array/settings_key_modes_values"
- android:entries="@array/settings_key_modes"
- android:defaultValue="@string/settings_key_mode_auto" />
+ android:defaultValue="false" />
<ListPreference
android:key="voice_mode"
android:title="@string/voice_input"
@@ -73,7 +71,7 @@
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="com.google.android.inputmethod.latin.dictionarypack"
- android:targetClass="com.google.android.inputmethod.latin.dictionarypack.DictionarySettings" />
+ android:targetClass="com.google.android.inputmethod.latin.dictionarypack.DictionarySettingsActivity" />
</PreferenceScreen>
<ListPreference
android:key="auto_correction_threshold"
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index 86a56308a..ae9809e56 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -118,15 +118,6 @@ public class AccessibleKeyboardViewProxy {
return onHoverEventInternal(event, tracker);
}
- public boolean dispatchTouchEvent(MotionEvent event) {
- // Since touch exploration translates hover double-tap to a regular
- // single-tap, we're going to drop non-touch exploration events.
- if (!AccessibilityUtils.getInstance().isTouchExplorationEvent(event))
- return true;
-
- return false;
- }
-
/**
* Handles touch exploration events when Accessibility is turned on.
*
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 0ee8d7174..5b34dd5db 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -33,7 +33,6 @@ import com.android.inputmethod.keyboard.internal.PopupCharactersParser;
import com.android.inputmethod.keyboard.internal.Row;
import com.android.inputmethod.latin.R;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -292,13 +291,18 @@ public class Key {
mY = y;
mWidth = keyWidth - mGap;
- final CharSequence[] popupCharacters = style.getTextArray(keyAttr,
- R.styleable.Keyboard_Key_popupCharacters);
+ CharSequence[] popupCharacters = style.getTextArray(
+ keyAttr, R.styleable.Keyboard_Key_popupCharacters);
+ if (mKeyboard.mId.mPasswordInput) {
+ popupCharacters = PopupCharactersParser.filterOut(
+ res, popupCharacters, PopupCharactersParser.NON_ASCII_FILTER);
+ }
// In Arabic symbol layouts, we'd like to keep digits in popup characters regardless of
// config_digit_popup_characters_enabled.
if (mKeyboard.mId.isAlphabetKeyboard() && !res.getBoolean(
R.bool.config_digit_popup_characters_enabled)) {
- mPopupCharacters = filterOutDigitPopupCharacters(popupCharacters);
+ mPopupCharacters = PopupCharactersParser.filterOut(
+ res, popupCharacters, PopupCharactersParser.DIGIT_FILTER);
} else {
mPopupCharacters = popupCharacters;
}
@@ -325,6 +329,13 @@ public class Key {
keyAttr, R.styleable.Keyboard_Key_keyIcon,
KeyboardIconsSet.ICON_UNDEFINED));
Keyboard.setDefaultBounds(mIcon);
+ final int shiftedIconId = style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIconShifted,
+ KeyboardIconsSet.ICON_UNDEFINED);
+ if (shiftedIconId != KeyboardIconsSet.ICON_UNDEFINED) {
+ final Drawable shiftedIcon = iconsSet.getIcon(shiftedIconId);
+ Keyboard.setDefaultBounds(shiftedIcon);
+ mKeyboard.addShiftedIcon(this, shiftedIcon);
+ }
mHintLabel = style.getText(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
mLabel = style.getText(keyAttr, R.styleable.Keyboard_Key_keyLabel);
@@ -342,12 +353,9 @@ public class Key {
} else {
mCode = Keyboard.CODE_DUMMY;
}
-
- final Drawable shiftedIcon = iconsSet.getIcon(style.getInt(
- keyAttr, R.styleable.Keyboard_Key_keyIconShifted,
- KeyboardIconsSet.ICON_UNDEFINED));
- if (shiftedIcon != null)
- mKeyboard.getShiftedIcons().put(this, shiftedIcon);
+ if (mCode == Keyboard.CODE_SHIFT) {
+ mKeyboard.addShiftKey(this);
+ }
} finally {
keyAttr.recycle();
}
@@ -398,36 +406,6 @@ public class Key {
return (mLabelOption & LABEL_OPTION_HAS_HINT_LABEL) != 0;
}
- private static boolean isDigitPopupCharacter(CharSequence label) {
- return label != null && label.length() == 1 && Character.isDigit(label.charAt(0));
- }
-
- private static CharSequence[] filterOutDigitPopupCharacters(CharSequence[] popupCharacters) {
- if (popupCharacters == null || popupCharacters.length < 1)
- return null;
- if (popupCharacters.length == 1 && isDigitPopupCharacter(
- PopupCharactersParser.getLabel(popupCharacters[0].toString())))
- return null;
- ArrayList<CharSequence> filtered = null;
- for (int i = 0; i < popupCharacters.length; i++) {
- final CharSequence popupSpec = popupCharacters[i];
- if (isDigitPopupCharacter(PopupCharactersParser.getLabel(popupSpec.toString()))) {
- if (filtered == null) {
- filtered = new ArrayList<CharSequence>();
- for (int j = 0; j < i; j++)
- filtered.add(popupCharacters[j]);
- }
- } else if (filtered != null) {
- filtered.add(popupSpec);
- }
- }
- if (filtered == null)
- return popupCharacters;
- if (filtered.size() == 0)
- return null;
- return filtered.toArray(new CharSequence[filtered.size()]);
- }
-
public Drawable getIcon() {
return mIcon;
}
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 19847c5ec..8840c79da 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -34,7 +34,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
/**
* Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
@@ -77,6 +76,8 @@ public class Keyboard {
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
+ public static final int CODE_DIGIT0 = '0';
+ public static final int CODE_PLUS = '+';
/** Special keys code. These should be aligned with values/keycodes.xml */
@@ -116,8 +117,8 @@ public class Keyboard {
/** List of shift keys in this keyboard and its icons and state */
private final List<Key> mShiftKeys = new ArrayList<Key>();
private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>();
- private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>();
- private final HashSet<Key> mShiftLockEnabled = new HashSet<Key>();
+ private final HashMap<Key, Drawable> mUnshiftedIcons = new HashMap<Key, Drawable>();
+ private final HashSet<Key> mShiftLockKeys = new HashSet<Key>();
private final KeyboardShiftState mShiftState = new KeyboardShiftState();
/** Total height of the keyboard, including the padding and keys */
@@ -284,30 +285,35 @@ public class Keyboard {
mMaxPopupColumn = column;
}
- public List<Key> getShiftKeys() {
- return mShiftKeys;
+ public void addShiftKey(Key key) {
+ if (key == null) return;
+ mShiftKeys.add(key);
+ if (key.mSticky) {
+ mShiftLockKeys.add(key);
+ }
}
- public Map<Key, Drawable> getShiftedIcons() {
- return mShiftedIcons;
+ public void addShiftedIcon(Key key, Drawable icon) {
+ if (key == null) return;
+ mUnshiftedIcons.put(key, key.getIcon());
+ mShiftedIcons.put(key, icon);
}
- public void enableShiftLock() {
- for (final Key key : getShiftKeys()) {
- mShiftLockEnabled.add(key);
- mNormalShiftIcons.put(key, key.getIcon());
- }
- }
-
- public boolean isShiftLockEnabled(Key key) {
- return mShiftLockEnabled.contains(key);
+ public boolean hasShiftLockKey() {
+ return !mShiftLockKeys.isEmpty();
}
public boolean setShiftLocked(boolean newShiftLockState) {
- final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
- for (final Key key : getShiftKeys()) {
+ for (final Key key : mShiftLockKeys) {
+ // To represent "shift locked" state. The highlight is handled by background image that
+ // might be a StateListDrawable.
key.setHighlightOn(newShiftLockState);
- key.setIcon(newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key));
+ // To represent "shifted" state. The key might have a shifted icon.
+ if (newShiftLockState && mShiftedIcons.containsKey(key)) {
+ key.setIcon(mShiftedIcons.get(key));
+ } else {
+ key.setIcon(mUnshiftedIcons.get(key));
+ }
}
mShiftState.setShiftLocked(newShiftLockState);
return true;
@@ -318,12 +324,11 @@ public class Keyboard {
}
public boolean setShifted(boolean newShiftState) {
- final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
- for (final Key key : getShiftKeys()) {
+ for (final Key key : mShiftKeys) {
if (!newShiftState && !mShiftState.isShiftLocked()) {
- key.setIcon(mNormalShiftIcons.get(key));
+ key.setIcon(mUnshiftedIcons.get(key));
} else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
- key.setIcon(shiftedIcons.get(key));
+ key.setIcon(mShiftedIcons.get(key));
}
}
return mShiftState.setShifted(newShiftState);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 3f30165aa..9299c6c58 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -55,10 +55,9 @@ public class KeyboardId {
public final boolean mHasSettingsKey;
public final int mF2KeyMode;
public final boolean mClobberSettingsKey;
- public final boolean mVoiceKeyEnabled;
- public final boolean mHasVoiceKey;
+ public final boolean mShortcutKeyEnabled;
+ public final boolean mHasShortcutKey;
public final int mImeAction;
- public final boolean mEnableShiftLock;
public final String mXmlName;
public final EditorInfo mAttribute;
@@ -67,8 +66,7 @@ public class KeyboardId {
public KeyboardId(String xmlName, int xmlId, Locale locale, int orientation, int width,
int mode, EditorInfo attribute, boolean hasSettingsKey, int f2KeyMode,
- boolean clobberSettingsKey, boolean voiceKeyEnabled, boolean hasVoiceKey,
- boolean enableShiftLock) {
+ boolean clobberSettingsKey, boolean shortcutKeyEnabled, boolean hasShortcutKey) {
final int inputType = (attribute != null) ? attribute.inputType : 0;
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
this.mLocale = locale;
@@ -85,13 +83,12 @@ public class KeyboardId {
this.mHasSettingsKey = hasSettingsKey;
this.mF2KeyMode = f2KeyMode;
this.mClobberSettingsKey = clobberSettingsKey;
- this.mVoiceKeyEnabled = voiceKeyEnabled;
- this.mHasVoiceKey = hasVoiceKey;
+ this.mShortcutKeyEnabled = shortcutKeyEnabled;
+ this.mHasShortcutKey = hasShortcutKey;
// We are interested only in {@link EditorInfo#IME_MASK_ACTION} enum value and
// {@link EditorInfo#IME_FLAG_NO_ENTER_ACTION}.
this.mImeAction = imeOptions & (
EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
- this.mEnableShiftLock = enableShiftLock;
this.mXmlName = xmlName;
this.mAttribute = attribute;
@@ -107,24 +104,23 @@ public class KeyboardId {
hasSettingsKey,
f2KeyMode,
clobberSettingsKey,
- voiceKeyEnabled,
- hasVoiceKey,
+ shortcutKeyEnabled,
+ hasShortcutKey,
mImeAction,
- enableShiftLock,
});
}
public KeyboardId cloneAsMiniKeyboard() {
return new KeyboardId("mini popup keyboard", MINI_KEYBOARD_ID_MARKER, mLocale, mOrientation,
- mWidth, mMode, mAttribute, false, F2KEY_MODE_NONE, false, false, false, false);
+ mWidth, mMode, mAttribute, false, F2KEY_MODE_NONE, false, false, false);
}
public KeyboardId cloneWithNewGeometry(int orientation, int width) {
if (mWidth == width)
return this;
return new KeyboardId(mXmlName, mXmlId, mLocale, orientation, width, mMode, mAttribute,
- mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey,
- mEnableShiftLock);
+ mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mShortcutKeyEnabled,
+ mHasShortcutKey);
}
public int getXmlId() {
@@ -160,7 +156,7 @@ public class KeyboardId {
return other instanceof KeyboardId && equals((KeyboardId) other);
}
- boolean equals(KeyboardId other) {
+ private boolean equals(KeyboardId other) {
return other.mLocale.equals(this.mLocale)
&& other.mOrientation == this.mOrientation
&& other.mWidth == this.mWidth
@@ -171,10 +167,9 @@ public class KeyboardId {
&& other.mHasSettingsKey == this.mHasSettingsKey
&& other.mF2KeyMode == this.mF2KeyMode
&& other.mClobberSettingsKey == this.mClobberSettingsKey
- && other.mVoiceKeyEnabled == this.mVoiceKeyEnabled
- && other.mHasVoiceKey == this.mHasVoiceKey
- && other.mImeAction == this.mImeAction
- && other.mEnableShiftLock == this.mEnableShiftLock;
+ && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
+ && other.mHasShortcutKey == this.mHasShortcutKey
+ && other.mImeAction == this.mImeAction;
}
@Override
@@ -184,7 +179,7 @@ public class KeyboardId {
@Override
public String toString() {
- return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s%s]",
+ return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s]",
mXmlName,
mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth,
@@ -195,9 +190,8 @@ public class KeyboardId {
(mNavigateAction ? " navigateAction" : ""),
(mPasswordInput ? " passwordInput" : ""),
(mHasSettingsKey ? " hasSettingsKey" : ""),
- (mVoiceKeyEnabled ? " voiceKeyEnabled" : ""),
- (mHasVoiceKey ? " hasVoiceKey" : ""),
- (mEnableShiftLock ? " enableShiftLock" : "")
+ (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
+ (mHasShortcutKey ? " hasShortcutKey" : "")
);
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 552a3cd30..17fdd0cc4 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -18,7 +18,9 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.res.Configuration;
import android.content.res.Resources;
+import android.inputmethodservice.InputMethodService;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.InflateException;
@@ -38,6 +40,7 @@ import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Utils;
import java.lang.ref.SoftReference;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
@@ -62,6 +65,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private View mCurrentInputView;
private LatinKeyboardView mKeyboardView;
private LatinIME mInputMethodService;
+ private String mPackageName;
+ private Resources mResources;
// TODO: Combine these key state objects with auto mode switch state.
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
@@ -74,6 +79,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private KeyboardId mCurrentId;
private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache =
new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
+ // TODO: Remove this cache object when {@link DisplayMetrics} has actual window width excluding
+ // system navigation bar.
+ private WindowWidthCache mWindowWidthCache;
/** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of
* what user actually typed. */
@@ -91,20 +99,82 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private static final int SWITCH_STATE_CHORDING_SYMBOL = 6;
private int mSwitchState = SWITCH_STATE_ALPHA;
- private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto;
- private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW =
- R.string.settings_key_mode_always_show;
- // NOTE: No need to have SETTINGS_KEY_MODE_ALWAYS_HIDE here because it's not being referred to
- // in the source code now.
- // Default is SETTINGS_KEY_MODE_AUTO.
- private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO;
-
private int mThemeIndex = -1;
private Context mThemeContext;
- private int mWindowWidth;
private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
+ private static class WindowWidthCache {
+ private final InputMethodService mService;
+ private final Resources mResources;
+ private final boolean mIsRegistered[] = new boolean[Configuration.ORIENTATION_SQUARE + 1];
+ private final int mWidth[] = new int[Configuration.ORIENTATION_SQUARE + 1];
+
+ public WindowWidthCache(InputMethodService service) {
+ mService = service;
+ mResources = service.getResources();
+
+ Arrays.fill(mIsRegistered, false);
+ Arrays.fill(mWidth, 0);
+ }
+
+ private int getCurrentWindowWidth() {
+ return mService.getWindow().getWindow().getDecorView().getWidth();
+ }
+
+ public int getWidth(Configuration conf) {
+ final int orientation = conf.orientation;
+ try {
+ final int width = mWidth[orientation];
+ if (mIsRegistered[orientation] || width > 0) {
+ // Return registered or cached window width for this orientation.
+ return width;
+ }
+ // Fall through
+ } catch (IndexOutOfBoundsException e) {
+ Log.w(TAG, "unknwon orientation value " + orientation);
+ // Fall through
+ }
+
+ // Return screen width as default window width.
+ return mResources.getDisplayMetrics().widthPixels;
+ }
+
+ public int getWidthOnSizeChanged(Configuration conf) {
+ final int orientation = conf.orientation;
+ try {
+ if (mIsRegistered[orientation]) {
+ // Return registered window width for this orientation.
+ return mWidth[orientation];
+ }
+
+ // Cache the current window width without registering.
+ final int width = getCurrentWindowWidth();
+ mWidth[orientation] = width;
+ return width;
+ } catch (IndexOutOfBoundsException e) {
+ Log.w(TAG, "unknwon orientation value " + orientation);
+ return 0;
+ }
+ }
+
+ public void registerWidth() {
+ final int orientation = mResources.getConfiguration().orientation;
+ try {
+ if (!mIsRegistered[orientation]) {
+ final int width = getCurrentWindowWidth();
+ if (width > 0) {
+ // Register current window width.
+ mWidth[orientation] = width;
+ mIsRegistered[orientation] = true;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ Log.w(TAG, "unknwon orientation value " + orientation);
+ }
+ }
+ }
+
public static KeyboardSwitcher getInstance() {
return sInstance;
}
@@ -114,11 +184,18 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public static void init(LatinIME ims, SharedPreferences prefs) {
- sInstance.mInputMethodService = ims;
- sInstance.mPrefs = prefs;
- sInstance.mSubtypeSwitcher = SubtypeSwitcher.getInstance();
- sInstance.setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs));
- prefs.registerOnSharedPreferenceChangeListener(sInstance);
+ sInstance.initInternal(ims, prefs);
+ }
+
+ private void initInternal(LatinIME ims, SharedPreferences prefs) {
+ mInputMethodService = ims;
+ mPackageName = ims.getPackageName();
+ mResources = ims.getResources();
+ mPrefs = prefs;
+ mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ mWindowWidthCache = new WindowWidthCache(ims);
+ setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs));
+ prefs.registerOnSharedPreferenceChangeListener(this);
}
private static int getKeyboardThemeIndex(Context context, SharedPreferences prefs) {
@@ -143,17 +220,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
- public void loadKeyboard(EditorInfo attribute, Settings.Values settings) {
+ public void loadKeyboard(EditorInfo editorInfo, Settings.Values settingsValues) {
mSwitchState = SWITCH_STATE_ALPHA;
try {
- final boolean voiceKeyEnabled = settings.isVoiceKeyEnabled(attribute);
- final boolean voiceKeyOnMain = settings.isVoiceKeyOnMain();
- mMainKeyboardId = getKeyboardId(
- attribute, false, false, voiceKeyEnabled, voiceKeyOnMain);
- mSymbolsKeyboardId = getKeyboardId(
- attribute, true, false, voiceKeyEnabled, voiceKeyOnMain);
- mSymbolsShiftedKeyboardId = getKeyboardId(
- attribute, true, true, voiceKeyEnabled, voiceKeyOnMain);
+ mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues);
+ mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
+ mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
setKeyboard(getKeyboard(mMainKeyboardId));
} catch (RuntimeException e) {
Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
@@ -161,24 +233,22 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
+ public void onHideWindow() {
+ mIsAutoCorrectionActive = false;
+ }
+
@SuppressWarnings("unused")
public void onSizeChanged(int w, int h, int oldw, int oldh) {
- final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth();
+ // TODO: This hack should be removed when display metric returns a proper width.
+ // Until then, the behavior of KeyboardSwitcher is suboptimal on a device that has a
+ // vertical system navigation bar in landscape screen orientation, for instance.
+ final Configuration conf = mResources.getConfiguration();
+ final int width = mWindowWidthCache.getWidthOnSizeChanged(conf);
// If the window width hasn't fixed yet or keyboard doesn't exist, nothing to do with.
if (width == 0 || mCurrentId == null)
return;
- // The window width is fixed.
- mWindowWidth = width;
- // If this is the first time the {@link KeyboardView} has been shown, no need to reload
- // keyboard.
- if (oldw == 0 && oldh == 0)
- return;
// Reload keyboard with new width.
- final int orientation = mInputMethodService.getResources().getConfiguration().orientation;
- final KeyboardId newId = mCurrentId.cloneWithNewGeometry(orientation, width);
- // If the new keyboard is the same as the current one, no need to reload it.
- if (newId.equals(mCurrentId))
- return;
+ final KeyboardId newId = mCurrentId.cloneWithNewGeometry(conf.orientation, width);
setKeyboard(getKeyboard(newId));
}
@@ -186,10 +256,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
mKeyboardView.setKeyboard(newKeyboard);
mCurrentId = newKeyboard.mId;
- final Resources res = mInputMethodService.getResources();
mKeyboardView.setKeyPreviewPopupEnabled(
- Settings.Values.isKeyPreviewPopupEnabled(mPrefs, res),
- Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, res));
+ Settings.Values.isKeyPreviewPopupEnabled(mPrefs, mResources),
+ Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, mResources));
final boolean localeChanged = (oldKeyboard == null)
|| !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
@@ -199,22 +268,16 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id);
LatinKeyboard keyboard = (ref == null) ? null : ref.get();
if (keyboard == null) {
- final Resources res = mInputMethodService.getResources();
- final Locale savedLocale = Utils.setSystemLocale(res,
- mSubtypeSwitcher.getInputLocale());
+ final Locale savedLocale = Utils.setSystemLocale(
+ mResources, mSubtypeSwitcher.getInputLocale());
keyboard = new LatinKeyboard(mThemeContext, id, id.mWidth);
-
- if (id.mEnableShiftLock) {
- keyboard.enableShiftLock();
- }
-
mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
if (DEBUG_CACHE)
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
- Utils.setSystemLocale(res, savedLocale);
+ Utils.setSystemLocale(mResources, savedLocale);
} else if (DEBUG_CACHE) {
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
}
@@ -229,28 +292,16 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
return keyboard;
}
- private static boolean hasSettingsKey(SharedPreferences prefs, Context context,
- EditorInfo attribute) {
- return getSettingsKeyMode(prefs, context)
- && !Utils.inPrivateImeOptions(context.getPackageName(),
- LatinIME.IME_OPTION_NO_SETTINGS_KEY, attribute);
- }
-
- private KeyboardId getKeyboardId(EditorInfo attribute, final boolean isSymbols,
- final boolean isShift, final boolean voiceKeyEnabled, final boolean voiceKeyOnMain) {
- final int mode = Utils.getKeyboardMode(attribute);
- final boolean hasVoiceKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain);
+ private KeyboardId getKeyboardId(EditorInfo editorInfo, final boolean isSymbols,
+ final boolean isShift, Settings.Values settingsValues) {
+ final int mode = Utils.getKeyboardMode(editorInfo);
final int xmlId;
- final boolean enableShiftLock;
-
switch (mode) {
case KeyboardId.MODE_PHONE:
xmlId = (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone;
- enableShiftLock = true;
break;
case KeyboardId.MODE_NUMBER:
xmlId = R.xml.kbd_number;
- enableShiftLock = false;
break;
default:
if (isSymbols) {
@@ -258,24 +309,28 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
} else {
xmlId = R.xml.kbd_qwerty;
}
- enableShiftLock = true;
break;
}
- final boolean hasSettingsKey = hasSettingsKey(mPrefs, mInputMethodService, attribute);
- final int f2KeyMode = getF2KeyMode(mPrefs, mInputMethodService, attribute);
- final boolean clobberSettingsKey = Utils.inPrivateImeOptions(
- mInputMethodService.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY,
- attribute);
- final Resources res = mInputMethodService.getResources();
- final int orientation = res.getConfiguration().orientation;
- if (mWindowWidth == 0)
- mWindowWidth = res.getDisplayMetrics().widthPixels;
- final Locale locale = mSubtypeSwitcher.getInputLocale();
+ final boolean settingsKeyEnabled = settingsValues.isSettingsKeyEnabled(editorInfo);
+ final boolean noMicrophone = Utils.inPrivateImeOptions(
+ mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo)
+ || Utils.inPrivateImeOptions(
+ null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo);
+ final boolean voiceKeyEnabled = settingsValues.isVoiceKeyEnabled(editorInfo)
+ && !noMicrophone;
+ final boolean voiceKeyOnMain = settingsValues.isVoiceKeyOnMain();
+ final boolean noSettingsKey = Utils.inPrivateImeOptions(
+ mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, editorInfo);
+ final boolean hasSettingsKey = settingsKeyEnabled && !noSettingsKey;
+ final int f2KeyMode = getF2KeyMode(settingsKeyEnabled, noSettingsKey);
+ final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain);
+ final Configuration conf = mResources.getConfiguration();
+
return new KeyboardId(
- res.getResourceEntryName(xmlId), xmlId, locale, orientation, mWindowWidth,
- mode, attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, voiceKeyEnabled,
- hasVoiceKey, enableShiftLock);
+ mResources.getResourceEntryName(xmlId), xmlId, mSubtypeSwitcher.getInputLocale(),
+ conf.orientation, mWindowWidthCache.getWidth(conf), mode, editorInfo,
+ hasSettingsKey, f2KeyMode, noSettingsKey, voiceKeyEnabled, hasShortcutKey);
}
public int getKeyboardMode() {
@@ -548,6 +603,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
+ " symbolKeyState=" + mSymbolKeyState);
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
+ mWindowWidthCache.registerWidth();
}
public void onCancelInput() {
@@ -571,7 +627,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a.
// sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked()
// that takes care of the current keyboard having such ALT key or not.
- keyboard.setShiftLocked(hasStickyShiftKey(keyboard));
+ keyboard.setShiftLocked(keyboard.hasShiftLockKey());
} else {
keyboard = getKeyboard(mSymbolsKeyboardId);
// Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the
@@ -581,14 +637,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
setKeyboard(keyboard);
}
- private static boolean hasStickyShiftKey(Keyboard keyboard) {
- for (final Key shiftKey : keyboard.getShiftKeys()) {
- if (shiftKey.mSticky)
- return true;
- }
- return false;
- }
-
public boolean isInMomentarySwitchState() {
return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL
|| mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
@@ -771,9 +819,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (PREF_KEYBOARD_LAYOUT.equals(key)) {
- final int layoutId = getKeyboardThemeIndex(mInputMethodService, sharedPreferences);
- postSetInputView(createInputView(layoutId, false));
- } else if (Settings.PREF_SETTINGS_KEY.equals(key)) {
+ final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences);
+ postSetInputView(createInputView(themeIndex, false));
+ } else if (Settings.PREF_SHOW_SETTINGS_KEY.equals(key)) {
postSetInputView(createInputView(mThemeIndex, true));
}
}
@@ -791,41 +839,18 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
- private static boolean getSettingsKeyMode(SharedPreferences prefs, Context context) {
- final Resources res = context.getResources();
- final boolean showSettingsKeyOption = res.getBoolean(
- R.bool.config_enable_show_settings_key_option);
- if (showSettingsKeyOption) {
- final String settingsKeyMode = prefs.getString(Settings.PREF_SETTINGS_KEY,
- res.getString(DEFAULT_SETTINGS_KEY_MODE));
- // We show the settings key when 1) SETTINGS_KEY_MODE_ALWAYS_SHOW or
- // 2) SETTINGS_KEY_MODE_AUTO and there are two or more enabled IMEs on the system
- if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))
- || (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_AUTO))
- && Utils.hasMultipleEnabledIMEsOrSubtypes(
- (InputMethodManagerCompatWrapper.getInstance())))) {
- return true;
- }
- return false;
- }
- // If the show settings key option is disabled, we always try showing the settings key.
- return true;
- }
-
- private static int getF2KeyMode(SharedPreferences prefs, Context context,
- EditorInfo attribute) {
- final boolean clobberSettingsKey = Utils.inPrivateImeOptions(
- context.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY, attribute);
- final Resources res = context.getResources();
- final String settingsKeyMode = prefs.getString(Settings.PREF_SETTINGS_KEY,
- res.getString(DEFAULT_SETTINGS_KEY_MODE));
- if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_AUTO))) {
- return clobberSettingsKey ? KeyboardId.F2KEY_MODE_SHORTCUT_IME
- : KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
- } else if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))) {
- return clobberSettingsKey ? KeyboardId.F2KEY_MODE_NONE : KeyboardId.F2KEY_MODE_SETTINGS;
- } else { // SETTINGS_KEY_MODE_ALWAYS_HIDE
+ private static int getF2KeyMode(boolean settingsKeyEnabled, boolean noSettingsKey) {
+ if (noSettingsKey) {
+ // Never shows the Settings key
return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
}
+
+ if (settingsKeyEnabled) {
+ return KeyboardId.F2KEY_MODE_SETTINGS;
+ } else {
+ // It should be alright to fall back to the Settings key on 7-inch layouts
+ // even when the Settings key is not explicitly enabled.
+ return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
+ }
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index fc47713b8..4086a8e77 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -630,7 +630,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
// Draw popup hint "..." at the bottom right corner of the key.
- if (key.hasPopupHint()) {
+ if (key.hasPopupHint() && key.mPopupCharacters != null && key.mPopupCharacters.length > 0) {
paint.setTextSize(params.mKeyHintLetterSize);
paint.setColor(params.mKeyHintLabelColor);
paint.setTextAlign(Align.CENTER);
@@ -754,10 +754,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
@Override
public void dismissKeyPreview(PointerTracker tracker) {
- if (mShowKeyPreviewPopup) {
- mDrawingHandler.cancelShowKeyPreview(tracker);
- mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
- }
+ mDrawingHandler.cancelShowKeyPreview(tracker);
+ mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
}
private void addKeyPreview(TextView keyPreview) {
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
index cb1a2b782..b397ca757 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
@@ -567,9 +567,9 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
+ // Drop non-hover touch events when touch exploration is enabled.
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- return AccessibleKeyboardViewProxy.getInstance().dispatchTouchEvent(event)
- || super.dispatchTouchEvent(event);
+ return false;
}
return super.dispatchTouchEvent(event);
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index c404a5dfb..b78fd94ea 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -53,55 +53,55 @@ public class LatinKeyboardView extends LatinKeyboardBaseView {
@Override
public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null
- && (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard())) {
- // Phone and number keyboard never shows popup preview (except language switch).
- super.setKeyPreviewPopupEnabled(false, delay);
- } else {
- super.setKeyPreviewPopupEnabled(previewEnabled, delay);
+ final Keyboard keyboard = getKeyboard();
+ if (keyboard instanceof LatinKeyboard) {
+ final LatinKeyboard latinKeyboard = (LatinKeyboard)keyboard;
+ if (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard()) {
+ // Phone and number keyboard never shows popup preview.
+ super.setKeyPreviewPopupEnabled(false, delay);
+ return;
+ }
}
+ super.setKeyPreviewPopupEnabled(previewEnabled, delay);
}
@Override
public void setKeyboard(Keyboard newKeyboard) {
super.setKeyboard(newKeyboard);
// One-seventh of the keyboard width seems like a reasonable threshold
- mJumpThresholdSquare = newKeyboard.getMinWidth() / 7;
- mJumpThresholdSquare *= mJumpThresholdSquare;
- }
-
- private LatinKeyboard getLatinKeyboard() {
- Keyboard keyboard = getKeyboard();
- if (keyboard instanceof LatinKeyboard) {
- return (LatinKeyboard)keyboard;
- } else {
- return null;
- }
+ final int jumpThreshold = newKeyboard.getMinWidth() / 7;
+ mJumpThresholdSquare = jumpThreshold * jumpThreshold;
}
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboard oldKeyboard) {
- final LatinKeyboard currentKeyboard = getLatinKeyboard();
+ final Keyboard keyboard = getKeyboard();
// We should not set text fade factor to the keyboard which does not display the language on
// its spacebar.
- if (currentKeyboard != null && currentKeyboard == oldKeyboard)
- currentKeyboard.setSpacebarTextFadeFactor(fadeFactor, this);
+ if (keyboard instanceof LatinKeyboard && keyboard == oldKeyboard) {
+ ((LatinKeyboard)keyboard).setSpacebarTextFadeFactor(fadeFactor, this);
+ }
}
@Override
protected boolean onLongPress(Key key, PointerTracker tracker) {
- int primaryCode = key.mCode;
+ final int primaryCode = key.mCode;
+ final Keyboard keyboard = getKeyboard();
+ if (keyboard instanceof LatinKeyboard) {
+ final LatinKeyboard latinKeyboard = (LatinKeyboard) keyboard;
+ if (primaryCode == Keyboard.CODE_DIGIT0 && latinKeyboard.isPhoneKeyboard()) {
+ tracker.onLongPressed();
+ // Long pressing on 0 in phone number keypad gives you a '+'.
+ return invokeOnKey(Keyboard.CODE_PLUS);
+ }
+ if (primaryCode == Keyboard.CODE_SHIFT && latinKeyboard.isAlphaKeyboard()) {
+ tracker.onLongPressed();
+ return invokeOnKey(Keyboard.CODE_CAPSLOCK);
+ }
+ }
if (primaryCode == Keyboard.CODE_SETTINGS || primaryCode == Keyboard.CODE_SPACE) {
tracker.onLongPressed();
// Both long pressing settings key and space key invoke IME switcher dialog.
return invokeOnKey(Keyboard.CODE_SETTINGS_LONGPRESS);
- } else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) {
- tracker.onLongPressed();
- // Long pressing on 0 in phone number keypad gives you a '+'.
- return invokeOnKey('+');
- } else if (primaryCode == Keyboard.CODE_SHIFT) {
- tracker.onLongPressed();
- return invokeOnKey(Keyboard.CODE_CAPSLOCK);
} else {
return super.onLongPress(key, tracker);
}
@@ -194,7 +194,7 @@ public class LatinKeyboardView extends LatinKeyboardBaseView {
@Override
public boolean onTouchEvent(MotionEvent me) {
- if (getLatinKeyboard() == null) return true;
+ if (getKeyboard() == null) return true;
// If there was a sudden jump, return without processing the actual motion event.
if (handleSuddenJump(me)) {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 6b6a4538f..b25754de4 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -329,36 +329,28 @@ public class PointerTracker {
return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
}
- public boolean isSpaceKey(int keyIndex) {
- Key key = getKey(keyIndex);
- return key != null && key.mCode == Keyboard.CODE_SPACE;
- }
-
private void setReleasedKeyGraphics(int keyIndex) {
mDrawingProxy.dismissKeyPreview(this);
final Key key = getKey(keyIndex);
- if (key != null) {
+ if (key != null && key.isEnabled()) {
key.onReleased();
mDrawingProxy.invalidateKey(key);
}
}
private void setPressedKeyGraphics(int keyIndex) {
- if (isKeyPreviewRequired(keyIndex)) {
- mDrawingProxy.showKeyPreview(keyIndex, this);
- }
final Key key = getKey(keyIndex);
if (key != null && key.isEnabled()) {
+ if (isKeyPreviewRequired(key)) {
+ mDrawingProxy.showKeyPreview(keyIndex, this);
+ }
key.onPressed();
mDrawingProxy.invalidateKey(key);
}
}
// The modifier key, such as shift key, should not show its key preview.
- private boolean isKeyPreviewRequired(int keyIndex) {
- final Key key = getKey(keyIndex);
- if (key == null || !key.isEnabled())
- return false;
+ private static boolean isKeyPreviewRequired(Key key) {
final int code = key.mCode;
if (isModifierCode(code) || code == Keyboard.CODE_DELETE
|| code == Keyboard.CODE_ENTER || code == Keyboard.CODE_SPACE)
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 30d9692a8..3f9f35993 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -212,7 +212,7 @@ public class KeyStyles {
public void parseKeyStyleAttributes(TypedArray keyStyleAttr, TypedArray keyAttrs,
XmlResourceParser parser) {
- String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
+ final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
if (DEBUG) Log.d(TAG, String.format("<%s styleName=%s />",
KeyboardParser.TAG_KEY_STYLE, styleName));
if (mStyles.containsKey(styleName))
@@ -220,11 +220,11 @@ public class KeyStyles {
final DeclaredKeyStyle style = new DeclaredKeyStyle();
if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
- String parentStyle = keyStyleAttr.getString(
+ final String parentStyle = keyStyleAttr.getString(
R.styleable.Keyboard_KeyStyle_parentStyle);
final DeclaredKeyStyle parent = mStyles.get(parentStyle);
if (parent == null)
- throw new ParseException("Unknown parentStyle " + parent, parser);
+ throw new ParseException("Unknown parentStyle " + parentStyle, parser);
style.addParent(parent);
}
style.parseKeyStyleAttributes(keyAttrs);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
index 8eae2bb42..f6f46750c 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
@@ -338,8 +338,6 @@ public class KeyboardParser {
Arrays.toString(key.mPopupCharacters)));
checkEndTag(TAG_KEY, parser);
keys.add(key);
- if (key.mCode == Keyboard.CODE_SHIFT)
- mKeyboard.getShiftKeys().add(key);
endKey(key);
}
}
@@ -496,10 +494,10 @@ public class KeyboardParser {
R.styleable.Keyboard_Case_f2KeyMode, id.mF2KeyMode);
final boolean clobberSettingsKeyMatched = matchBoolean(a,
R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
- final boolean voiceEnabledMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_voiceKeyEnabled, id.mVoiceKeyEnabled);
- final boolean voiceKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_hasVoiceKey, id.mHasVoiceKey);
+ final boolean shortcutKeyEnabledMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
+ final boolean hasShortcutKeyMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
// As noted at {@link KeyboardId} class, we are interested only in enum value masked by
// {@link android.view.inputmethod.EditorInfo#IME_MASK_ACTION} and
// {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_ENTER_ACTION}. So matching
@@ -514,7 +512,7 @@ public class KeyboardParser {
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
final boolean selected = modeMatched && navigateActionMatched && passwordInputMatched
&& hasSettingsKeyMatched && f2KeyModeMatched && clobberSettingsKeyMatched
- && voiceEnabledMatched && voiceKeyMatched && imeActionMatched &&
+ && shortcutKeyEnabledMatched && hasShortcutKeyMatched && imeActionMatched &&
localeCodeMatched && languageCodeMatched && countryCodeMatched;
if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
@@ -526,8 +524,9 @@ public class KeyboardParser {
a.getInt(R.styleable.Keyboard_Case_f2KeyMode, -1)), "f2KeyMode"),
booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
"clobberSettingsKey"),
- booleanAttr(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"),
- booleanAttr(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"),
+ booleanAttr(
+ a, R.styleable.Keyboard_Case_shortcutKeyEnabled, "shortcutKeyEnabled"),
+ booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey, "hasShortcutKey"),
textAttr(EditorInfoCompatUtils.imeOptionsName(
a.getInt(R.styleable.Keyboard_Case_imeAction, -1)), "imeAction"),
textAttr(a.getString(R.styleable.Keyboard_Case_localeCode), "localeCode"),
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java b/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
index 8276f5d78..032489e66 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
@@ -23,6 +23,8 @@ import android.util.Log;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.R;
+import java.util.ArrayList;
+
/**
* String parser of popupCharacters attribute of Key.
* The string is comma separated texts each of which represents one popup key.
@@ -182,4 +184,54 @@ public class PopupCharactersParser {
super(message);
}
}
+
+ public interface CodeFilter {
+ public boolean shouldFilterOut(int code);
+ }
+
+ public static final CodeFilter DIGIT_FILTER = new CodeFilter() {
+ @Override
+ public boolean shouldFilterOut(int code) {
+ return Character.isDigit(code);
+ }
+ };
+
+ public static final CodeFilter NON_ASCII_FILTER = new CodeFilter() {
+ @Override
+ public boolean shouldFilterOut(int code) {
+ return code < 0x20 || code > 0x7e;
+ }
+ };
+
+ public static CharSequence[] filterOut(Resources res, CharSequence[] popupCharacters,
+ CodeFilter filter) {
+ if (popupCharacters == null || popupCharacters.length < 1) {
+ return null;
+ }
+ if (popupCharacters.length == 1
+ && filter.shouldFilterOut(getCode(res, popupCharacters[0].toString()))) {
+ return null;
+ }
+ ArrayList<CharSequence> filtered = null;
+ for (int i = 0; i < popupCharacters.length; i++) {
+ final CharSequence popupSpec = popupCharacters[i];
+ if (filter.shouldFilterOut(getCode(res, popupSpec.toString()))) {
+ if (filtered == null) {
+ filtered = new ArrayList<CharSequence>();
+ for (int j = 0; j < i; j++) {
+ filtered.add(popupCharacters[j]);
+ }
+ }
+ } else if (filtered != null) {
+ filtered.add(popupSpec);
+ }
+ }
+ if (filtered == null) {
+ return popupCharacters;
+ }
+ if (filtered.size() == 0) {
+ return null;
+ }
+ return filtered.toArray(new CharSequence[filtered.size()]);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index 4baf52e52..713f3abe2 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -323,8 +323,11 @@ public class CandidateView extends LinearLayout implements OnClickListener {
word.setTag(i);
word.setOnClickListener(this);
mWords.add(word);
+ final View divider = inflater.inflate(R.layout.candidate_divider, null);
+ divider.setTag(i);
+ divider.setOnClickListener(this);
+ mDividers.add(divider);
mInfos.add((TextView)inflater.inflate(R.layout.candidate_info, null));
- mDividers.add(inflater.inflate(R.layout.candidate_divider, null));
}
mTouchToSave = findViewById(R.id.touch_to_save);
@@ -476,6 +479,7 @@ public class CandidateView extends LinearLayout implements OnClickListener {
final TextView word = mWords.get(pos);
final TextPaint paint = word.getPaint();
+ final View divider = mDividers.get(pos);
// TODO: Reorder candidates in strip as appropriate. The center candidate should hold
// the word when space is typed (valid typed word or auto corrected word).
word.setTextColor(getCandidateTextColor(isAutoCorrect,
@@ -505,7 +509,7 @@ public class CandidateView extends LinearLayout implements OnClickListener {
word.setTextScaleX(scaleX);
if (i != 0) {
// Add divider if this isn't the left most suggestion in candidate strip.
- mCandidatesStrip.addView(mDividers.get(i));
+ mCandidatesStrip.addView(divider);
}
mCandidatesStrip.addView(word);
if (params.mCanUseFixedWidthColumns) {
@@ -534,7 +538,6 @@ public class CandidateView extends LinearLayout implements OnClickListener {
}
if (x != 0) {
// Add divider if this isn't the left most suggestion in current row.
- final View divider = mDividers.get(i);
mCandidatesPane.addView(divider);
FrameLayoutCompatUtils.placeViewAt(
divider, x, y + (mCandidateStripHeight - params.mDividerHeight) / 2,
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d9d421411..bdcbfbcb1 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -557,7 +557,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// If orientation changed while predicting, commit the change
if (conf.orientation != mDisplayOrientation) {
mHandler.startOrientationChanging(mDisplayWidth, mDisplayHeight);
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
commitTyped(ic);
if (ic != null) ic.finishComposingText(); // For voice input
if (isShowingOptionDialog())
@@ -789,7 +789,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final boolean selectionChanged = (newSelStart != candidatesEnd
|| newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart;
final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1;
- if (((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars)
+ if (!mExpectingUpdateSelection
+ && ((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars)
|| mVoiceProxy.isVoiceInputHighlighted())
&& (selectionChanged || candidatesCleared)) {
if (candidatesCleared) {
@@ -807,7 +808,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
setPunctuationSuggestions();
}
TextEntryState.reset();
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.finishComposingText();
}
@@ -872,7 +873,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public void hideWindow() {
LatinImeLogger.commit();
- mKeyboardSwitcher.onAutoCorrectionStateChanged(false);
+ mKeyboardSwitcher.onHideWindow();
if (TRACE) Debug.stopMethodTracing();
if (mOptionsDialog != null && mOptionsDialog.isShowing()) {
@@ -917,7 +918,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (onEvaluateInputViewShown() && mCandidateViewContainer != null) {
final boolean shouldShowCandidates = shown
&& (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true);
- if (isExtractViewShown()) {
+ if (isFullscreenMode()) {
// No need to have extra space to show the key preview.
mCandidateViewContainer.setMinimumHeight(0);
mCandidateViewContainer.setVisibility(
@@ -1012,7 +1013,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
event.getAction(), event.getKeyCode(), event.getRepeatCount(),
event.getDeviceId(), event.getScanCode(),
KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON);
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic != null)
ic.sendKeyEvent(newEvent);
return true;
@@ -1022,12 +1023,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return super.onKeyUp(keyCode, event);
}
- public void commitTyped(InputConnection inputConnection) {
+ public void commitTyped(final InputConnection ic) {
if (!mHasUncommittedTypedChars) return;
mHasUncommittedTypedChars = false;
if (mComposingStringBuilder.length() > 0) {
- if (inputConnection != null) {
- inputConnection.commitText(mComposingStringBuilder, 1);
+ if (ic != null) {
+ ic.commitText(mComposingStringBuilder, 1);
}
mCommittedLength = mComposingStringBuilder.length();
TextEntryState.acceptedTyped(mComposingStringBuilder);
@@ -1038,7 +1039,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
public boolean getCurrentAutoCapsState() {
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
EditorInfo ei = getCurrentInputEditorInfo();
if (mSettingsValues.mAutoCap && ic != null && ei != null
&& ei.inputType != InputType.TYPE_NULL) {
@@ -1062,25 +1063,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
- private static boolean canBeFollowedByPeriod(final int codePoint) {
- // TODO: Check again whether there really ain't a better way to check this.
- // TODO: This should probably be language-dependant...
- return Character.isLetterOrDigit(codePoint)
- || codePoint == Keyboard.CODE_SINGLE_QUOTE
- || codePoint == Keyboard.CODE_DOUBLE_QUOTE
- || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS
- || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET
- || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET
- || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET;
- }
-
private void maybeDoubleSpace() {
if (mCorrectionMode == Suggest.CORRECTION_NONE) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
final CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3
- && canBeFollowedByPeriod(lastThree.charAt(0))
+ && Utils.canBeFollowedByPeriod(lastThree.charAt(0))
&& lastThree.charAt(1) == Keyboard.CODE_SPACE
&& lastThree.charAt(2) == Keyboard.CODE_SPACE
&& mHandler.isAcceptingDoubleSpaces()) {
@@ -1096,10 +1085,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
- private void maybeRemovePreviousPeriod(CharSequence text) {
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
-
+ // "ic" must not null
+ private void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) {
// When the text's first character is '.', remove the previous period
// if there is one.
CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
@@ -1238,12 +1225,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public void onTextInput(CharSequence text) {
mVoiceProxy.commitVoiceInput();
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
mRecorrection.abortRecorrection(false);
ic.beginBatchEdit();
commitTyped(ic);
- maybeRemovePreviousPeriod(text);
+ maybeRemovePreviousPeriod(ic, text);
ic.commitText(text, 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
@@ -1293,14 +1280,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
TextEntryState.backspace();
if (TextEntryState.isUndoCommit()) {
- revertLastWord(deleteChar);
+ revertLastWord(ic);
ic.endBatchEdit();
return;
}
if (justReplacedDoubleSpace) {
- if (revertDoubleSpace()) {
- ic.endBatchEdit();
- return;
+ if (revertDoubleSpace(ic)) {
+ ic.endBatchEdit();
+ return;
}
}
@@ -1315,7 +1302,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// different behavior only in the case of picking the first
// suggestion (typed word). It's intentional to have made this
// inconsistent with backspacing after selecting other suggestions.
- revertLastWord(true /* deleteChar */);
+ revertLastWord(ic);
} else {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
if (mDeleteCount > DELETE_ACCELERATE_AT) {
@@ -1398,7 +1385,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
mComposingStringBuilder.append((char) code);
mWordComposer.add(code, keyCodes, x, y);
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
// If it's the first letter, make note of auto-caps state
if (mWordComposer.size() == 1) {
@@ -1663,15 +1650,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSettingsValues.mWordSeparators);
final boolean recorrecting = TextEntryState.isRecorrecting();
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.beginBatchEdit();
}
if (mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null
&& index >= 0 && index < mApplicationSpecifiedCompletions.length) {
- CompletionInfo ci = mApplicationSpecifiedCompletions[index];
if (ic != null) {
- ic.commitCompletion(ci);
+ final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index];
+ ic.commitCompletion(completionInfo);
}
mCommittedLength = suggestion.length();
if (mCandidateView != null) {
@@ -1783,10 +1770,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
* Commits the chosen word to the text field and saves it for later retrieval.
*/
private void commitBestWord(CharSequence bestWord) {
- KeyboardSwitcher switcher = mKeyboardSwitcher;
+ final KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
mVoiceProxy.rememberReplacedWord(bestWord, mSettingsValues.mWordSeparators);
SuggestedWords suggestedWords = mCandidateView.getSuggestions();
@@ -1878,7 +1865,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
public boolean isCursorTouchingWord() {
- InputConnection ic = getCurrentInputConnection();
+ final InputConnection ic = getCurrentInputConnection();
if (ic == null) return false;
CharSequence toLeft = ic.getTextBeforeCursor(1, 0);
CharSequence toRight = ic.getTextAfterCursor(1, 0);
@@ -1895,36 +1882,33 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return false;
}
- private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) {
+ // "ic" must not null
+ private boolean sameAsTextBeforeCursor(final InputConnection ic, CharSequence text) {
CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0);
return TextUtils.equals(text, beforeText);
}
- private void revertLastWord(boolean deleteChar) {
+ // "ic" must not null
+ private void revertLastWord(final InputConnection ic) {
if (mHasUncommittedTypedChars || mComposingStringBuilder.length() <= 0) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
return;
}
- final InputConnection ic = getCurrentInputConnection();
- final CharSequence punctuation = ic.getTextBeforeCursor(1, 0);
- if (deleteChar) ic.deleteSurroundingText(1, 0);
- final CharSequence textToTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
- final int toDeleteLength = (!TextUtils.isEmpty(textToTheLeft)
- && mSettingsValues.isWordSeparator(textToTheLeft.charAt(0)))
- ? mCommittedLength - 1 : mCommittedLength;
- ic.deleteSurroundingText(toDeleteLength, 0);
-
- // Re-insert punctuation only when the deleted character was word separator and the
- // composing text wasn't equal to the auto-corrected text.
- if (deleteChar
- && !TextUtils.isEmpty(punctuation)
- && mSettingsValues.isWordSeparator(punctuation.charAt(0))
- && !TextUtils.equals(mComposingStringBuilder, textToTheLeft)) {
+ final CharSequence separator = ic.getTextBeforeCursor(1, 0);
+ ic.deleteSurroundingText(mCommittedLength + 1 /* separator */, 0);
+
+ // Re-insert "separator" only when the deleted character was word separator and the
+ // composing text wasn't equal to the auto-corrected text which can be found before
+ // the cursor.
+ if (!TextUtils.isEmpty(separator)
+ && mSettingsValues.isWordSeparator(separator.charAt(0))
+ && !TextUtils.equals(mComposingStringBuilder,
+ ic.getTextBeforeCursor(mCommittedLength, 0))) {
ic.commitText(mComposingStringBuilder, 1);
TextEntryState.acceptedTyped(mComposingStringBuilder);
- ic.commitText(punctuation, 1);
- TextEntryState.typedCharacter(punctuation.charAt(0), true,
+ ic.commitText(separator, 1);
+ TextEntryState.typedCharacter(separator.charAt(0), true,
WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
// Clear composing text
mComposingStringBuilder.setLength(0);
@@ -1937,9 +1921,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHandler.postUpdateSuggestions();
}
- private boolean revertDoubleSpace() {
+ // "ic" must not null
+ private boolean revertDoubleSpace(final InputConnection ic) {
mHandler.cancelDoubleSpacesTimer();
- final InputConnection ic = getCurrentInputConnection();
// Here we test whether we indeed have a period and a space before us. This should not
// be needed, but it's there just in case something went wrong.
final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0);
@@ -2163,8 +2147,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
};
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setIcon(R.drawable.ic_dialog_keyboard)
- .setNegativeButton(android.R.string.cancel, null)
.setItems(items, listener)
.setTitle(title);
showOptionDialogInternal(builder.create());
@@ -2191,8 +2173,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
};
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setIcon(R.drawable.ic_dialog_keyboard)
- .setNegativeButton(android.R.string.cancel, null)
.setItems(items, listener)
.setTitle(title);
showOptionDialogInternal(builder.create());
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index e44ae29d9..35af91b0f 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -61,7 +61,7 @@ public class Settings extends InputMethodSettingsActivity
public static final String PREF_KEY_PREVIEW_POPUP_ON = "popup_on";
public static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled";
public static final String PREF_AUTO_CAP = "auto_cap";
- public static final String PREF_SETTINGS_KEY = "settings_key";
+ public static final String PREF_SHOW_SETTINGS_KEY = "show_settings_key";
public static final String PREF_VOICE_SETTINGS_KEY = "voice_mode";
public static final String PREF_INPUT_LANGUAGE = "input_language";
public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
@@ -118,6 +118,7 @@ public class Settings extends InputMethodSettingsActivity
public final boolean mBigramPredictionEnabled;
public final boolean mUseContactsDict;
+ private final boolean mShowSettingsKey;
private final boolean mVoiceKeyEnabled;
private final boolean mVoiceKeyOnMain;
@@ -165,21 +166,17 @@ public class Settings extends InputMethodSettingsActivity
mVibrateOn = hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false);
mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
res.getBoolean(R.bool.config_default_sound_enabled));
-
mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res);
mKeyPreviewPopupDismissDelay = getKeyPreviewPopupDismissDelay(prefs, res);
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
-
mAutoCorrectEnabled = isAutoCorrectEnabled(prefs, res);
mBigramSuggestionEnabled = mAutoCorrectEnabled
&& isBigramSuggestionEnabled(prefs, res, mAutoCorrectEnabled);
mBigramPredictionEnabled = mBigramSuggestionEnabled
&& isBigramPredictionEnabled(prefs, res);
-
mAutoCorrectionThreshold = getAutoCorrectionThreshold(prefs, res);
-
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
-
+ mShowSettingsKey = prefs.getBoolean(Settings.PREF_SHOW_SETTINGS_KEY, false);
final String voiceModeMain = res.getString(R.string.voice_mode_main);
final String voiceModeOff = res.getString(R.string.voice_mode_off);
final String voiceMode = prefs.getString(PREF_VOICE_SETTINGS_KEY, voiceModeMain);
@@ -284,6 +281,10 @@ public class Settings extends InputMethodSettingsActivity
return builder.setIsPunctuationSuggestions().build();
}
+ public boolean isSettingsKeyEnabled(EditorInfo attribute) {
+ return mShowSettingsKey;
+ }
+
public boolean isVoiceKeyEnabled(EditorInfo attribute) {
final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
final int inputType = (attribute != null) ? attribute.inputType : 0;
@@ -298,7 +299,7 @@ public class Settings extends InputMethodSettingsActivity
private PreferenceScreen mInputLanguageSelection;
private ListPreference mVoicePreference;
- private ListPreference mSettingsKeyPreference;
+ private CheckBoxPreference mShowSettingsKeyPreference;
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThreshold;
private ListPreference mKeyPreviewPopupDismissDelay;
@@ -345,7 +346,7 @@ public class Settings extends InputMethodSettingsActivity
mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES);
mInputLanguageSelection.setOnPreferenceClickListener(this);
mVoicePreference = (ListPreference) findPreference(PREF_VOICE_SETTINGS_KEY);
- mSettingsKeyPreference = (ListPreference) findPreference(PREF_SETTINGS_KEY);
+ mShowSettingsKeyPreference = (CheckBoxPreference) findPreference(PREF_SHOW_SETTINGS_KEY);
mShowCorrectionSuggestionsPreference =
(ListPreference) findPreference(PREF_SHOW_SUGGESTIONS_SETTING);
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
@@ -376,7 +377,7 @@ public class Settings extends InputMethodSettingsActivity
final boolean showSettingsKeyOption = res.getBoolean(
R.bool.config_enable_show_settings_key_option);
if (!showSettingsKeyOption) {
- generalSettings.removePreference(mSettingsKeyPreference);
+ generalSettings.removePreference(mShowSettingsKeyPreference);
}
final boolean showVoiceKeyOption = res.getBoolean(
@@ -457,7 +458,6 @@ public class Settings extends InputMethodSettingsActivity
} else {
getPreferenceScreen().removePreference(mVoicePreference);
}
- updateSettingsKeySummary();
updateShowCorrectionSuggestionsSummary();
updateKeyPreviewPopupDelaySummary();
}
@@ -489,7 +489,6 @@ public class Settings extends InputMethodSettingsActivity
mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
.equals(mVoiceModeOff));
updateVoiceModeSummary();
- updateSettingsKeySummary();
updateShowCorrectionSuggestionsSummary();
updateKeyPreviewPopupDelaySummary();
}
@@ -513,12 +512,6 @@ public class Settings extends InputMethodSettingsActivity
mShowCorrectionSuggestionsPreference.getValue())]);
}
- private void updateSettingsKeySummary() {
- mSettingsKeyPreference.setSummary(
- getResources().getStringArray(R.array.settings_key_modes)
- [mSettingsKeyPreference.findIndexOfValue(mSettingsKeyPreference.getValue())]);
- }
-
private void updateKeyPreviewPopupDelaySummary() {
final ListPreference lp = mKeyPreviewPopupDismissDelay;
lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]);
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 6bdc0a857..16a2b0e5f 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -190,6 +190,18 @@ public class Utils {
}
}
+ public static boolean canBeFollowedByPeriod(final int codePoint) {
+ // TODO: Check again whether there really ain't a better way to check this.
+ // TODO: This should probably be language-dependant...
+ return Character.isLetterOrDigit(codePoint)
+ || codePoint == Keyboard.CODE_SINGLE_QUOTE
+ || codePoint == Keyboard.CODE_DOUBLE_QUOTE
+ || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS
+ || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET
+ || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET
+ || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET;
+ }
+
/* package */ static class RingCharBuffer {
private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
@@ -546,11 +558,11 @@ public class Utils {
}
}
- public static int getKeyboardMode(EditorInfo attribute) {
- if (attribute == null)
+ public static int getKeyboardMode(EditorInfo editorInfo) {
+ if (editorInfo == null)
return KeyboardId.MODE_TEXT;
- final int inputType = attribute.inputType;
+ final int inputType = editorInfo.inputType;
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
switch (inputType & InputType.TYPE_MASK_CLASS) {
@@ -587,11 +599,11 @@ public class Utils {
}
public static boolean inPrivateImeOptions(String packageName, String key,
- EditorInfo attribute) {
- if (attribute == null)
+ EditorInfo editorInfo) {
+ if (editorInfo == null)
return false;
return containsInCsv(packageName != null ? packageName + "." + key : key,
- attribute.privateImeOptions);
+ editorInfo.privateImeOptions);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 156510b40..ae938aea8 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin.spellcheck;
import android.service.textservice.SpellCheckerService;
+import android.util.Log;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
@@ -24,11 +25,26 @@ import android.view.textservice.TextInfo;
* Service for spell checking, using LatinIME's dictionaries and mechanisms.
*/
public class AndroidSpellCheckerService extends SpellCheckerService {
+ private static final String TAG = AndroidSpellCheckerService.class.getSimpleName();
+ private static final boolean DBG = true;
@Override
public SuggestionsInfo getSuggestions(TextInfo textInfo, int suggestionsLimit,
String locale) {
// TODO: implement this
- String[] candidates = new String[] {"candidate1", "candidate2", "candidate3"};
- return new SuggestionsInfo(0, candidates);
+ final String text = textInfo.getText();
+ if (DBG) {
+ Log.w(TAG, "getSuggestions: " + text);
+ }
+ String[] candidates0 = new String[] {text, "candidate1", "candidate2", "candidate3"};
+ String[] candidates1 = new String[] {text, "candidateA", "candidateB"};
+ final int textLength = textInfo.getText().length() % 3;
+ if (textLength % 3 == 0) {
+ return new SuggestionsInfo(SuggestionsInfo.RESULT_ATTR_LOOKS_TYPO
+ | SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY, candidates0);
+ } else if (textLength % 3 == 1) {
+ return new SuggestionsInfo(SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY, candidates1);
+ } else {
+ return new SuggestionsInfo(0, null);
+ }
}
}
diff --git a/native/Android.mk b/native/Android.mk
index bc246a990..04819e456 100644
--- a/native/Android.mk
+++ b/native/Android.mk
@@ -8,15 +8,13 @@ LOCAL_CFLAGS += -Werror -Wall
# To suppress compiler warnings for unused variables/functions used for debug features etc.
LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-function
-# Use the new dictionary format
-LOCAL_CFLAGS += -DNEW_DICTIONARY_FORMAT
-
LOCAL_SRC_FILES := \
jni/com_android_inputmethod_keyboard_ProximityInfo.cpp \
jni/com_android_inputmethod_latin_BinaryDictionary.cpp \
jni/jni_common.cpp \
src/bigram_dictionary.cpp \
src/char_utils.cpp \
+ src/correction_state.cpp \
src/dictionary.cpp \
src/proximity_info.cpp \
src/unigram_dictionary.cpp
diff --git a/native/src/correction_state.cpp b/native/src/correction_state.cpp
new file mode 100644
index 000000000..aa5efce40
--- /dev/null
+++ b/native/src/correction_state.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LOG_TAG "LatinIME: correction_state.cpp"
+
+#include "correction_state.h"
+
+namespace latinime {
+
+CorrectionState::CorrectionState() {
+}
+
+void CorrectionState::setCorrectionParams(const ProximityInfo *pi, const int inputLength,
+ const int skipPos, const int excessivePos, const int transposedPos) {
+ mProximityInfo = pi;
+ mSkipPos = skipPos;
+ mExcessivePos = excessivePos;
+ mTransposedPos = transposedPos;
+}
+
+void CorrectionState::checkState() {
+ if (DEBUG_DICT) {
+ int inputCount = 0;
+ if (mSkipPos >= 0) ++inputCount;
+ if (mExcessivePos >= 0) ++inputCount;
+ if (mTransposedPos >= 0) ++inputCount;
+ // TODO: remove this assert
+ assert(inputCount <= 1);
+ }
+}
+
+CorrectionState::~CorrectionState() {
+}
+
+} // namespace latinime
diff --git a/native/src/correction_state.h b/native/src/correction_state.h
new file mode 100644
index 000000000..5b7392590
--- /dev/null
+++ b/native/src/correction_state.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef LATINIME_CORRECTION_STATE_H
+#define LATINIME_CORRECTION_STATE_H
+
+#include <stdint.h>
+
+#include "defines.h"
+
+namespace latinime {
+
+class ProximityInfo;
+
+class CorrectionState {
+public:
+ CorrectionState();
+ void setCorrectionParams(const ProximityInfo *pi, const int inputLength, const int skipPos,
+ const int excessivePos, const int transposedPos);
+ void checkState();
+ virtual ~CorrectionState();
+ int getSkipPos() const {
+ return mSkipPos;
+ }
+ int getExcessivePos() const {
+ return mExcessivePos;
+ }
+ int getTransposedPos() const {
+ return mTransposedPos;
+ }
+private:
+ const ProximityInfo *mProximityInfo;
+ int mInputLength;
+ int mSkipPos;
+ int mExcessivePos;
+ int mTransposedPos;
+};
+} // namespace latinime
+#endif // LATINIME_CORRECTION_INFO_H
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index c45393f18..bed92cf9e 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -78,7 +78,7 @@ unsigned short ProximityInfo::getPrimaryCharAt(const int index) const {
return getProximityCharsAt(index)[0];
}
-bool ProximityInfo::existsCharInProximityAt(const int index, const int c) const {
+inline bool ProximityInfo::existsCharInProximityAt(const int index, const int c) const {
const int *chars = getProximityCharsAt(index);
int i = 0;
while (chars[i] > 0 && i < MAX_PROXIMITY_CHARS_SIZE) {
@@ -114,8 +114,10 @@ bool ProximityInfo::existsAdjacentProximityChars(const int index) const {
// in their list. The non-accented version of the character should be considered
// "close", but not the other keys close to the non-accented version.
ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
- const int index, const unsigned short c, const int skipPos,
- const int excessivePos, const int transposedPos) const {
+ const int index, const unsigned short c, CorrectionState *correctionState) const {
+ const int skipPos = correctionState->getSkipPos();
+ const int excessivePos = correctionState->getExcessivePos();
+ const int transposedPos = correctionState->getTransposedPos();
const int *currentChars = getProximityCharsAt(index);
const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h
index 435a60151..b28191d01 100644
--- a/native/src/proximity_info.h
+++ b/native/src/proximity_info.h
@@ -23,6 +23,8 @@
namespace latinime {
+class CorrectionState;
+
class ProximityInfo {
public:
typedef enum { // Used as a return value for character comparison
@@ -42,8 +44,7 @@ public:
bool existsCharInProximityAt(const int index, const int c) const;
bool existsAdjacentProximityChars(const int index) const;
ProximityType getMatchedProximityId(
- const int index, const unsigned short c, const int skipPos,
- const int excessivePos, const int transposedPos) const;
+ const int index, const unsigned short c, CorrectionState *correctionState) const;
bool sameAsTyped(const unsigned short *word, int length) const;
private:
int getStartIndexFromCoordinates(const int x, const int y) const;
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index bccd37a61..f0bb384fb 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -24,9 +24,7 @@
#include "dictionary.h"
#include "unigram_dictionary.h"
-#ifdef NEW_DICTIONARY_FORMAT
#include "binary_format.h"
-#endif // NEW_DICTIONARY_FORMAT
namespace latinime {
@@ -39,28 +37,23 @@ const UnigramDictionary::digraph_t UnigramDictionary::GERMAN_UMLAUT_DIGRAPHS[] =
UnigramDictionary::UnigramDictionary(const uint8_t* const streamStart, int typedLetterMultiplier,
int fullWordMultiplier, int maxWordLength, int maxWords, int maxProximityChars,
const bool isLatestDictVersion)
-#ifndef NEW_DICTIONARY_FORMAT
- : DICT_ROOT(streamStart),
-#else // NEW_DICTIONARY_FORMAT
: DICT_ROOT(streamStart + NEW_DICTIONARY_HEADER_SIZE),
-#endif // NEW_DICTIONARY_FORMAT
MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
MAX_PROXIMITY_CHARS(maxProximityChars), IS_LATEST_DICT_VERSION(isLatestDictVersion),
TYPED_LETTER_MULTIPLIER(typedLetterMultiplier), FULL_WORD_MULTIPLIER(fullWordMultiplier),
-#ifndef NEW_DICTIONARY_FORMAT
- ROOT_POS(isLatestDictVersion ? DICTIONARY_HEADER_SIZE : 0),
-#else // NEW_DICTIONARY_FORMAT
// TODO : remove this variable.
ROOT_POS(0),
-#endif // NEW_DICTIONARY_FORMAT
BYTES_IN_ONE_CHAR(MAX_PROXIMITY_CHARS * sizeof(int)),
MAX_UMLAUT_SEARCH_DEPTH(DEFAULT_MAX_UMLAUT_SEARCH_DEPTH) {
if (DEBUG_DICT) {
LOGI("UnigramDictionary - constructor");
}
+ mCorrectionState = new CorrectionState();
}
-UnigramDictionary::~UnigramDictionary() {}
+UnigramDictionary::~UnigramDictionary() {
+ delete mCorrectionState;
+}
static inline unsigned int getCodesBufferSize(const int* codes, const int codesSize,
const int MAX_PROXIMITY_CHARS) {
@@ -362,6 +355,8 @@ void UnigramDictionary::getSuggestionCandidates(const int skipPos,
assert(excessivePos < mInputLength);
assert(missingPos < mInputLength);
}
+ mCorrectionState->setCorrectionParams(mProximityInfo, mInputLength, skipPos, excessivePos,
+ transposedPos);
int rootPosition = ROOT_POS;
// Get the number of children of root, then increment the position
int childCount = Dictionary::getCount(DICT_ROOT, &rootPosition);
@@ -389,8 +384,8 @@ void UnigramDictionary::getSuggestionCandidates(const int skipPos,
// depth will never be greater than maxDepth because in that case,
// needsToTraverseChildrenNodes should be false
const bool needsToTraverseChildrenNodes = processCurrentNode(siblingPos, outputIndex,
- maxDepth, traverseAllNodes, matchWeight, inputIndex, diffs, skipPos,
- excessivePos, transposedPos, nextLetters, nextLettersSize, &childCount,
+ maxDepth, traverseAllNodes, matchWeight, inputIndex, diffs,
+ nextLetters, nextLettersSize, mCorrectionState, &childCount,
&firstChildPos, &traverseAllNodes, &matchWeight, &inputIndex, &diffs,
&siblingPos, &outputIndex);
// Update next sibling pos
@@ -521,8 +516,12 @@ bool UnigramDictionary::getMistypedSpaceWords(const int inputLength, const int s
}
inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int depth,
- const int matchWeight, const int skipPos, const int excessivePos, const int transposedPos,
- const int freq, const bool sameLength) const {
+ const int matchWeight, const int freq, const bool sameLength,
+ CorrectionState *correctionState) const {
+ const int skipPos = correctionState->getSkipPos();
+ const int excessivePos = correctionState->getExcessivePos();
+ const int transposedPos = correctionState->getTransposedPos();
+
// TODO: Demote by edit distance
int finalFreq = freq * matchWeight;
if (skipPos >= 0) {
@@ -587,16 +586,16 @@ inline bool UnigramDictionary::needsToSkipCurrentNode(const unsigned short c,
inline void UnigramDictionary::onTerminal(unsigned short int* word, const int depth,
const uint8_t* const root, const uint8_t flags, const int pos,
- const int inputIndex, const int matchWeight, const int skipPos,
- const int excessivePos, const int transposedPos, const int freq, const bool sameLength,
- int* nextLetters, const int nextLettersSize) {
+ const int inputIndex, const int matchWeight, const int freq, const bool sameLength,
+ int* nextLetters, const int nextLettersSize, CorrectionState *correctionState) {
+ const int skipPos = correctionState->getSkipPos();
const bool isSameAsTyped = sameLength ? mProximityInfo->sameAsTyped(word, depth + 1) : false;
if (isSameAsTyped) return;
if (depth >= MIN_SUGGEST_DEPTH) {
- const int finalFreq = calculateFinalFreq(inputIndex, depth, matchWeight, skipPos,
- excessivePos, transposedPos, freq, sameLength);
+ const int finalFreq = calculateFinalFreq(inputIndex, depth, matchWeight,
+ freq, sameLength, correctionState);
if (!isSameAsTyped)
addWord(word, depth + 1, finalFreq);
}
@@ -647,282 +646,6 @@ bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength,
return true;
}
-#ifndef NEW_DICTIONARY_FORMAT
-// The following functions will be entirely replaced with new implementations.
-void UnigramDictionary::getWordsOld(const int initialPos, const int inputLength, const int skipPos,
- const int excessivePos, const int transposedPos,int *nextLetters,
- const int nextLettersSize) {
- int initialPosition = initialPos;
- const int count = Dictionary::getCount(DICT_ROOT, &initialPosition);
- getWordsRec(count, initialPosition, 0,
- min(inputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH),
- mInputLength <= 0, 1, 0, 0, skipPos, excessivePos, transposedPos, nextLetters,
- nextLettersSize);
-}
-
-void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, const int depth,
- const int maxDepth, const bool traverseAllNodes, const int matchWeight,
- const int inputIndex, const int diffs, const int skipPos, const int excessivePos,
- const int transposedPos, int *nextLetters, const int nextLettersSize) {
- int siblingPos = pos;
- for (int i = 0; i < childrenCount; ++i) {
- int newCount;
- int newChildPosition;
- bool newTraverseAllNodes;
- int newMatchRate;
- int newInputIndex;
- int newDiffs;
- int newSiblingPos;
- int newOutputIndex;
- const bool needsToTraverseChildrenNodes = processCurrentNode(siblingPos, depth, maxDepth,
- traverseAllNodes, matchWeight, inputIndex, diffs,
- skipPos, excessivePos, transposedPos,
- nextLetters, nextLettersSize,
- &newCount, &newChildPosition, &newTraverseAllNodes, &newMatchRate,
- &newInputIndex, &newDiffs, &newSiblingPos, &newOutputIndex);
- siblingPos = newSiblingPos;
-
- if (needsToTraverseChildrenNodes) {
- getWordsRec(newCount, newChildPosition, newOutputIndex, maxDepth, newTraverseAllNodes,
- newMatchRate, newInputIndex, newDiffs, skipPos, excessivePos, transposedPos,
- nextLetters, nextLettersSize);
- }
- }
-}
-
-inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex,
- const int inputLength, unsigned short *word) {
- int pos = ROOT_POS;
- int count = Dictionary::getCount(DICT_ROOT, &pos);
- int maxFreq = 0;
- int depth = 0;
- unsigned short newWord[MAX_WORD_LENGTH_INTERNAL];
- bool terminal = false;
-
- mStackChildCount[0] = count;
- mStackSiblingPos[0] = pos;
-
- while (depth >= 0) {
- if (mStackChildCount[depth] > 0) {
- --mStackChildCount[depth];
- int firstChildPos;
- int newFreq;
- int siblingPos = mStackSiblingPos[depth];
- const bool needsToTraverseChildrenNodes = processCurrentNodeForExactMatch(siblingPos,
- startInputIndex, depth, newWord, &firstChildPos, &count, &terminal, &newFreq,
- &siblingPos);
- mStackSiblingPos[depth] = siblingPos;
- if (depth == (inputLength - 1)) {
- // Traverse sibling node
- if (terminal) {
- if (newFreq > maxFreq) {
- for (int i = 0; i < inputLength; ++i) word[i] = newWord[i];
- if (DEBUG_DICT && DEBUG_NODE) {
-#ifdef FLAG_DBG
- char s[inputLength + 1];
- for (int i = 0; i < inputLength; ++i) s[i] = word[i];
- s[inputLength] = 0;
- LOGI("New missing space word found: %d > %d (%s), %d, %d",
- newFreq, maxFreq, s, inputLength, depth);
-#endif
- }
- maxFreq = newFreq;
- }
- }
- } else if (needsToTraverseChildrenNodes) {
- // Traverse children nodes
- ++depth;
- mStackChildCount[depth] = count;
- mStackSiblingPos[depth] = firstChildPos;
- }
- } else {
- // Traverse parent node
- --depth;
- }
- }
-
- word[inputLength] = 0;
- return maxFreq;
-}
-
-inline bool UnigramDictionary::processCurrentNodeForExactMatch(const int firstChildPos,
- const int startInputIndex, const int depth, unsigned short *word, int *newChildPosition,
- int *newCount, bool *newTerminal, int *newFreq, int *siblingPos) {
- const int inputIndex = startInputIndex + depth;
- unsigned short c;
- *siblingPos = Dictionary::setDictionaryValues(DICT_ROOT, IS_LATEST_DICT_VERSION, firstChildPos,
- &c, newChildPosition, newTerminal, newFreq);
- const unsigned int inputC = mProximityInfo->getPrimaryCharAt(inputIndex);
- if (DEBUG_DICT) {
- assert(inputC <= U_SHORT_MAX);
- }
- const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
- const bool matched = (inputC == baseLowerC || inputC == c);
- const bool hasChild = *newChildPosition != 0;
- if (matched) {
- word[depth] = c;
- if (DEBUG_DICT && DEBUG_NODE) {
- LOGI("Node(%c, %c)<%d>, %d, %d", inputC, c, matched, hasChild, *newFreq);
- if (*newTerminal) {
- LOGI("Terminal %d", *newFreq);
- }
- }
- if (hasChild) {
- *newCount = Dictionary::getCount(DICT_ROOT, newChildPosition);
- return true;
- } else {
- return false;
- }
- } else {
- // If this node is not user typed character, this method treats this word as unmatched.
- // Thus newTerminal shouldn't be true.
- *newTerminal = false;
- return false;
- }
-}
-
-// TODO: use uint32_t instead of unsigned short
-bool UnigramDictionary::isValidWord(unsigned short *word, int length) {
- if (IS_LATEST_DICT_VERSION) {
- return (getBigramPosition(DICTIONARY_HEADER_SIZE, word, 0, length) != NOT_VALID_WORD);
- } else {
- return (getBigramPosition(0, word, 0, length) != NOT_VALID_WORD);
- }
-}
-
-
-// Require strict exact match.
-int UnigramDictionary::getBigramPosition(int pos, unsigned short *word, int offset,
- int length) const {
- // returns address of bigram data of that word
- // return -99 if not found
-
- int count = Dictionary::getCount(DICT_ROOT, &pos);
- unsigned short currentChar = (unsigned short) word[offset];
- for (int j = 0; j < count; j++) {
- unsigned short c = Dictionary::getChar(DICT_ROOT, &pos);
- int terminal = Dictionary::getTerminal(DICT_ROOT, &pos);
- int childPos = Dictionary::getAddress(DICT_ROOT, &pos);
- if (c == currentChar) {
- if (offset == length - 1) {
- if (terminal) {
- return (pos+1);
- }
- } else {
- if (childPos != 0) {
- int t = getBigramPosition(childPos, word, offset + 1, length);
- if (t > 0) {
- return t;
- }
- }
- }
- }
- if (terminal) {
- Dictionary::getFreq(DICT_ROOT, IS_LATEST_DICT_VERSION, &pos);
- }
- // There could be two instances of each alphabet - upper and lower case. So continue
- // looking ...
- }
- return NOT_VALID_WORD;
-}
-
-// The following functions will be modified.
-inline bool UnigramDictionary::processCurrentNode(const int initialPos, const int initialDepth,
- const int maxDepth, const bool initialTraverseAllNodes, int matchWeight, int inputIndex,
- const int initialDiffs, const int skipPos, const int excessivePos, const int transposedPos,
- int *nextLetters, const int nextLettersSize, int *newCount, int *newChildPosition,
- bool *newTraverseAllNodes, int *newMatchRate, int *newInputIndex, int *newDiffs,
- int *nextSiblingPosition, int *nextOutputIndex) {
- if (DEBUG_DICT) {
- int inputCount = 0;
- if (skipPos >= 0) ++inputCount;
- if (excessivePos >= 0) ++inputCount;
- if (transposedPos >= 0) ++inputCount;
- assert(inputCount <= 1);
- }
- unsigned short c;
- int childPosition;
- bool terminal;
- int freq;
- bool isSameAsUserTypedLength = false;
-
- const int pos = initialPos;
- const int depth = initialDepth;
- const int traverseAllNodes = initialTraverseAllNodes;
- const int diffs = initialDiffs;
-
- const uint8_t flags = 0; // No flags for now
-
- if (excessivePos == depth && inputIndex < mInputLength - 1) ++inputIndex;
-
- *nextSiblingPosition = Dictionary::setDictionaryValues(DICT_ROOT, IS_LATEST_DICT_VERSION, pos,
- &c, &childPosition, &terminal, &freq);
- *nextOutputIndex = depth + 1;
-
- const bool needsToTraverseChildrenNodes = childPosition != 0;
-
- // If we are only doing traverseAllNodes, no need to look at the typed characters.
- if (traverseAllNodes || needsToSkipCurrentNode(c, inputIndex, skipPos, depth)) {
- mWord[depth] = c;
- if (traverseAllNodes && terminal) {
- onTerminal(mWord, depth, DICT_ROOT, flags, pos, inputIndex, matchWeight, skipPos,
- excessivePos, transposedPos, freq, false, nextLetters, nextLettersSize);
- }
- if (!needsToTraverseChildrenNodes) return false;
- *newTraverseAllNodes = traverseAllNodes;
- *newMatchRate = matchWeight;
- *newDiffs = diffs;
- *newInputIndex = inputIndex;
- } else {
- int inputIndexForProximity = inputIndex;
-
- if (transposedPos >= 0) {
- if (inputIndex == transposedPos) ++inputIndexForProximity;
- if (inputIndex == (transposedPos + 1)) --inputIndexForProximity;
- }
-
- ProximityInfo::ProximityType matchedProximityCharId = mProximityInfo->getMatchedProximityId(
- inputIndexForProximity, c, skipPos, excessivePos, transposedPos);
- if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) return false;
- mWord[depth] = c;
- // If inputIndex is greater than mInputLength, that means there is no
- // proximity chars. So, we don't need to check proximity.
- if (ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
- multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &matchWeight);
- }
- bool isSameAsUserTypedLength = mInputLength == inputIndex + 1
- || (excessivePos == mInputLength - 1 && inputIndex == mInputLength - 2);
- if (isSameAsUserTypedLength && terminal) {
- onTerminal(mWord, depth, DICT_ROOT, flags, pos, inputIndex, matchWeight, skipPos,
- excessivePos, transposedPos, freq, true, nextLetters, nextLettersSize);
- }
- if (!needsToTraverseChildrenNodes) return false;
- // Start traversing all nodes after the index exceeds the user typed length
- *newTraverseAllNodes = isSameAsUserTypedLength;
- *newMatchRate = matchWeight;
- *newDiffs = diffs
- + ((ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) ? 1 : 0);
- *newInputIndex = inputIndex + 1;
- }
- // Optimization: Prune out words that are too long compared to how much was typed.
- if (depth >= maxDepth || *newDiffs > mMaxEditDistance) {
- return false;
- }
-
- // If inputIndex is greater than mInputLength, that means there are no proximity chars.
- // TODO: Check if this can be isSameAsUserTypedLength only.
- if (isSameAsUserTypedLength || mInputLength <= *newInputIndex) {
- *newTraverseAllNodes = true;
- }
- // get the count of nodes and increment childAddress.
- *newCount = Dictionary::getCount(DICT_ROOT, &childPosition);
- *newChildPosition = childPosition;
- if (DEBUG_DICT) assert(needsToTraverseChildrenNodes);
- return needsToTraverseChildrenNodes;
-}
-
-#else // NEW_DICTIONARY_FORMAT
-
// Wrapper for getMostFrequentWordLikeInner, which matches it to the previous
// interface.
inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex,
@@ -1081,16 +804,15 @@ int UnigramDictionary::getBigramPosition(int pos, unsigned short *word, int offs
// given level, as output into newCount when traversing this level's parent.
inline bool UnigramDictionary::processCurrentNode(const int initialPos, const int initialDepth,
const int maxDepth, const bool initialTraverseAllNodes, int matchWeight, int inputIndex,
- const int initialDiffs, const int skipPos, const int excessivePos, const int transposedPos,
- int *nextLetters, const int nextLettersSize, int *newCount, int *newChildrenPosition,
+ const int initialDiffs, int *nextLetters, const int nextLettersSize,
+ CorrectionState *correctionState, int *newCount, int *newChildrenPosition,
bool *newTraverseAllNodes, int *newMatchRate, int *newInputIndex, int *newDiffs,
int *nextSiblingPosition, int *newOutputIndex) {
+ const int skipPos = correctionState->getSkipPos();
+ const int excessivePos = correctionState->getExcessivePos();
+ const int transposedPos = correctionState->getTransposedPos();
if (DEBUG_DICT) {
- int inputCount = 0;
- if (skipPos >= 0) ++inputCount;
- if (excessivePos >= 0) ++inputCount;
- if (transposedPos >= 0) ++inputCount;
- assert(inputCount <= 1);
+ correctionState->checkState();
}
int pos = initialPos;
int depth = initialDepth;
@@ -1146,8 +868,8 @@ inline bool UnigramDictionary::processCurrentNode(const int initialPos, const in
// The frequency should be here, because we come here only if this is actually
// a terminal node, and we are on its last char.
const int freq = BinaryFormat::readFrequencyWithoutMovingPointer(DICT_ROOT, pos);
- onTerminal(mWord, depth, DICT_ROOT, flags, pos, inputIndex, matchWeight, skipPos,
- excessivePos, transposedPos, freq, false, nextLetters, nextLettersSize);
+ onTerminal(mWord, depth, DICT_ROOT, flags, pos, inputIndex, matchWeight,
+ freq, false, nextLetters, nextLettersSize, mCorrectionState);
}
if (!hasChildren) {
// If we don't have children here, that means we finished processing all
@@ -1170,7 +892,7 @@ inline bool UnigramDictionary::processCurrentNode(const int initialPos, const in
}
int matchedProximityCharId = mProximityInfo->getMatchedProximityId(
- inputIndexForProximity, c, skipPos, excessivePos, transposedPos);
+ inputIndexForProximity, c, mCorrectionState);
if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) {
// We found that this is an unrelated character, so we should give up traversing
// this node and its children entirely.
@@ -1197,8 +919,8 @@ inline bool UnigramDictionary::processCurrentNode(const int initialPos, const in
|| (excessivePos == mInputLength - 1 && inputIndex == mInputLength - 2);
if (isSameAsUserTypedLength && isTerminal) {
const int freq = BinaryFormat::readFrequencyWithoutMovingPointer(DICT_ROOT, pos);
- onTerminal(mWord, depth, DICT_ROOT, flags, pos, inputIndex, matchWeight, skipPos,
- excessivePos, transposedPos, freq, true, nextLetters, nextLettersSize);
+ onTerminal(mWord, depth, DICT_ROOT, flags, pos, inputIndex, matchWeight,
+ freq, true, nextLetters, nextLettersSize, mCorrectionState);
}
// This character matched the typed character (enough to traverse the node at least)
// so we just evaluated it. Now we should evaluate this virtual node's children - that
@@ -1276,6 +998,4 @@ inline bool UnigramDictionary::processCurrentNode(const int initialPos, const in
return true;
}
-#endif // NEW_DICTIONARY_FORMAT
-
} // namespace latinime
diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h
index 97198ef13..41e381860 100644
--- a/native/src/unigram_dictionary.h
+++ b/native/src/unigram_dictionary.h
@@ -18,6 +18,7 @@
#define LATINIME_UNIGRAM_DICTIONARY_H
#include <stdint.h>
+#include "correction_state.h"
#include "defines.h"
#include "proximity_info.h"
@@ -30,7 +31,6 @@ namespace latinime {
class UnigramDictionary {
public:
-#ifdef NEW_DICTIONARY_FORMAT
// Mask and flags for children address type selection.
static const int MASK_GROUP_ADDRESS_TYPE = 0xC0;
@@ -62,21 +62,16 @@ public:
static const int FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE = 0x10;
static const int FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES = 0x20;
static const int FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES = 0x30;
-#endif // NEW_DICTIONARY_FORMAT
UnigramDictionary(const uint8_t* const streamStart, int typedLetterMultipler,
int fullWordMultiplier, int maxWordLength, int maxWords, int maxProximityChars,
const bool isLatestDictVersion);
-#ifndef NEW_DICTIONARY_FORMAT
- bool isValidWord(unsigned short *word, int length);
-#else // NEW_DICTIONARY_FORMAT
bool isValidWord(const uint16_t* const inWord, const int length) const;
-#endif // NEW_DICTIONARY_FORMAT
int getBigramPosition(int pos, unsigned short *word, int offset, int length) const;
int getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
const int *ycoordinates, const int *codes, const int codesSize, const int flags,
unsigned short *outWords, int *frequencies);
- ~UnigramDictionary();
+ virtual ~UnigramDictionary();
private:
void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
@@ -99,42 +94,25 @@ private:
const int secondWordStartPos, const int secondWordLength, const bool isSpaceProximity);
bool getMissingSpaceWords(const int inputLength, const int missingSpacePos);
bool getMistypedSpaceWords(const int inputLength, const int spaceProximityPos);
- int calculateFinalFreq(const int inputIndex, const int depth, const int snr, const int skipPos,
- const int excessivePos, const int transposedPos, const int freq,
- const bool sameLength) const;
+ int calculateFinalFreq(const int inputIndex, const int depth, const int snr,
+ const int freq, const bool sameLength, CorrectionState *correctionState) const;
void onTerminal(unsigned short int* word, const int depth,
const uint8_t* const root, const uint8_t flags, const int pos,
- const int inputIndex, const int matchWeight, const int skipPos,
- const int excessivePos, const int transposedPos, const int freq, const bool sameLength,
- int *nextLetters, const int nextLettersSize);
+ const int inputIndex, const int matchWeight, const int freq, const bool sameLength,
+ int* nextLetters, const int nextLettersSize, CorrectionState *correctionState);
bool needsToSkipCurrentNode(const unsigned short c,
const int inputIndex, const int skipPos, const int depth);
// Process a node by considering proximity, missing and excessive character
bool processCurrentNode(const int initialPos, const int initialDepth,
- const int maxDepth, const bool initialTraverseAllNodes, const int snr, int inputIndex,
- const int initialDiffs, const int skipPos, const int excessivePos,
- const int transposedPos, int *nextLetters, const int nextLettersSize, int *newCount,
- int *newChildPosition, bool *newTraverseAllNodes, int *newSnr, int*newInputIndex,
- int *newDiffs, int *nextSiblingPosition, int *nextOutputIndex);
+ const int maxDepth, const bool initialTraverseAllNodes, int matchWeight, int inputIndex,
+ const int initialDiffs, int *nextLetters, const int nextLettersSize,
+ CorrectionState *correctionState, int *newCount, int *newChildPosition,
+ bool *newTraverseAllNodes, int *newMatchRate, int *newInputIndex, int *newDiffs,
+ int *nextSiblingPosition, int *nextOutputIndex);
int getMostFrequentWordLike(const int startInputIndex, const int inputLength,
unsigned short *word);
-#ifndef NEW_DICTIONARY_FORMAT
- void getWordsRec(const int childrenCount, const int pos, const int depth, const int maxDepth,
- const bool traverseAllNodes, const int snr, const int inputIndex, const int diffs,
- const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters,
- const int nextLettersSize);
- // Keep getWordsOld for comparing performance between getWords and getWordsOld
- void getWordsOld(const int initialPos, const int inputLength, const int skipPos,
- const int excessivePos, const int transposedPos, int *nextLetters,
- const int nextLettersSize);
- // Process a node by considering missing space
- bool processCurrentNodeForExactMatch(const int firstChildPos,
- const int startInputIndex, const int depth, unsigned short *word,
- int *newChildPosition, int *newCount, bool *newTerminal, int *newFreq, int *siblingPos);
-#else // NEW_DICTIONARY_FORMAT
int getMostFrequentWordLikeInner(const uint16_t* const inWord, const int length,
short unsigned int* outWord);
-#endif // NEW_DICTIONARY_FORMAT
const uint8_t* const DICT_ROOT;
const int MAX_WORD_LENGTH;
@@ -158,7 +136,8 @@ private:
int *mFrequencies;
unsigned short *mOutputChars;
- const ProximityInfo *mProximityInfo;
+ ProximityInfo *mProximityInfo;
+ CorrectionState *mCorrectionState;
int mInputLength;
// MAX_WORD_LENGTH_INTERNAL must be bigger than MAX_WORD_LENGTH
unsigned short mWord[MAX_WORD_LENGTH_INTERNAL];
diff --git a/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java b/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java
index 99bcc615e..7af566b03 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestPerformanceTests.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.latin.tests.R;
import android.content.res.AssetFileDescriptor;
+import android.content.res.Configuration;
import android.text.TextUtils;
import android.util.Slog;
@@ -38,7 +39,7 @@ public class SuggestPerformanceTests extends SuggestTestsBase {
final AssetFileDescriptor dict = openTestRawResourceFd(R.raw.test);
mHelper = new SuggestHelper(
getContext(), mTestPackageFile, dict.getStartOffset(), dict.getLength(),
- createKeyboardId(Locale.US));
+ createKeyboardId(Locale.US, Configuration.ORIENTATION_PORTRAIT));
loadString(R.raw.testtext);
}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTests.java b/tests/src/com/android/inputmethod/latin/SuggestTests.java
index 6e9a12797..cf4558090 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestTests.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.latin.tests.R;
import android.content.res.AssetFileDescriptor;
+import android.content.res.Configuration;
import java.util.Locale;
@@ -31,7 +32,7 @@ public class SuggestTests extends SuggestTestsBase {
final AssetFileDescriptor dict = openTestRawResourceFd(R.raw.test);
mHelper = new SuggestHelper(
getContext(), mTestPackageFile, dict.getStartOffset(), dict.getLength(),
- createKeyboardId(Locale.US));
+ createKeyboardId(Locale.US, Configuration.ORIENTATION_PORTRAIT));
mHelper.setCorrectionMode(Suggest.CORRECTION_FULL_BIGRAM);
}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
index 8aadee42e..058a3e7c0 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
@@ -20,6 +20,7 @@ import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.test.AndroidTestCase;
import android.text.TextUtils;
+import android.util.DisplayMetrics;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.keyboard.KeyboardId;
@@ -37,12 +38,22 @@ public class SuggestTestsBase extends AndroidTestCase {
mTestPackageFile = new File(getTestContext().getApplicationInfo().sourceDir);
}
- protected KeyboardId createKeyboardId(Locale locale) {
- final int displayWidth = getContext().getResources().getDisplayMetrics().widthPixels;
+ protected KeyboardId createKeyboardId(Locale locale, int orientation) {
+ final DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
+ final int width;
+ if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ width = Math.max(dm.widthPixels, dm.heightPixels);
+ } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+ width = Math.min(dm.widthPixels, dm.heightPixels);
+ } else {
+ fail("Orientation should be ORIENTATION_LANDSCAPE or ORIENTATION_PORTRAIT: "
+ + "orientation=" + orientation);
+ return null;
+ }
return new KeyboardId(locale.toString() + " keyboard",
- com.android.inputmethod.latin.R.xml.kbd_qwerty, locale,
- Configuration.ORIENTATION_LANDSCAPE, displayWidth, KeyboardId.MODE_TEXT,
- new EditorInfo(), false, KeyboardId.F2KEY_MODE_NONE, false, false, false, false);
+ com.android.inputmethod.latin.R.xml.kbd_qwerty, locale, orientation, width,
+ KeyboardId.MODE_TEXT, new EditorInfo(), false, KeyboardId.F2KEY_MODE_NONE,
+ false, false, false);
}
protected InputStream openTestRawResource(int resIdInTest) {
diff --git a/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java b/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java
index 9bd85385e..0b97e41fd 100644
--- a/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java
+++ b/tests/src/com/android/inputmethod/latin/UserBigramSuggestTests.java
@@ -15,9 +15,10 @@
*/
package com.android.inputmethod.latin;
-import com.android.inputmethod.latin.tests.R;
-
import android.content.res.AssetFileDescriptor;
+import android.content.res.Configuration;
+
+import com.android.inputmethod.latin.tests.R;
import java.util.Locale;
@@ -34,7 +35,8 @@ public class UserBigramSuggestTests extends SuggestTestsBase {
final AssetFileDescriptor dict = openTestRawResourceFd(R.raw.test);
mHelper = new UserBigramSuggestHelper(
getContext(), mTestPackageFile, dict.getStartOffset(), dict.getLength(),
- MAX_DATA, DELETE_DATA, createKeyboardId(Locale.US));
+ MAX_DATA, DELETE_DATA,
+ createKeyboardId(Locale.US, Configuration.ORIENTATION_PORTRAIT));
}
/************************** Tests ************************/