Merge remote branch 'goog/master' into merge
Conflicts: java/src/com/android/inputmethod/latin/Settings.java java/src/com/android/inputmethod/latin/SubtypeSwitcher.java java/src/com/android/inputmethod/voice/VoiceIMEConnector.java Change-Id: If30410c4814c3224f87698c165312494c0efca23main
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 182 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,25 @@
|
||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:startColor="#ff000000"
|
||||||
|
android:endColor="#ff000e29"
|
||||||
|
android:angle="90" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<selector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:state_window_focused="false"
|
||||||
|
android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/btn_center_default" />
|
||||||
|
<item
|
||||||
|
android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/btn_center_pressed" />
|
||||||
|
<item
|
||||||
|
android:state_focused="true"
|
||||||
|
android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/btn_center_selected" />
|
||||||
|
<item
|
||||||
|
android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/btn_center_default" />
|
||||||
|
<item
|
||||||
|
android:drawable="@drawable/btn_center_default" />
|
||||||
|
</selector>
|
After Width: | Height: | Size: 182 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 3.6 KiB |
|
@ -16,83 +16,70 @@
|
||||||
** See the License for the specific language governing permissions and
|
** See the License for the specific language governing permissions and
|
||||||
** limitations under the License.
|
** limitations under the License.
|
||||||
*/
|
*/
|
||||||
-->
|
-->
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:background="@android:color/black"
|
|
||||||
android:paddingBottom="0dip"
|
|
||||||
android:paddingLeft="0dip"
|
|
||||||
android:paddingRight="0dip"
|
|
||||||
>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/main_image"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="@drawable/voice_ime_background"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="180dip"
|
|
||||||
android:paddingBottom="2dip"
|
|
||||||
android:paddingTop="2dip"
|
|
||||||
>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/text"
|
|
||||||
android:text="@string/voice_initializing"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_marginTop="15dip"
|
|
||||||
android:textSize="28sp"
|
|
||||||
android:textColor="#ffffff"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/image"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_marginTop="20dip"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:src="@drawable/mic_slash_holo"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ProgressBar android:id="@+id/progress"
|
|
||||||
android:layout_height="60dip"
|
|
||||||
android:layout_width="60dip"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:indeterminate="true"
|
|
||||||
android:indeterminateOnly="false"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/button"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="@drawable/ok_cancel"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="42dip"
|
android:background="@drawable/background_voice">
|
||||||
android:paddingLeft="1dip"
|
<LinearLayout
|
||||||
android:paddingRight="1dip"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
>
|
android:id="@+id/popup_layout"
|
||||||
|
android:orientation="vertical"
|
||||||
<TextView android:id="@+id/button_text"
|
android:layout_height="0dip"
|
||||||
android:text="@string/cancel"
|
android:layout_width="500dip"
|
||||||
android:layout_height="wrap_content"
|
android:layout_centerInParent="true"
|
||||||
android:layout_width="wrap_content"
|
android:background="@drawable/vs_dialog_red">
|
||||||
android:layout_marginTop="7dip"
|
<TextView
|
||||||
android:textSize="19sp"
|
android:id="@+id/text"
|
||||||
android:textColor="#ffffff"
|
android:text="@string/voice_error"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_height="wrap_content"
|
||||||
/>
|
android:layout_width="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:layout_marginTop="10dip"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="invisible"/>
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_height="0dip"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_weight="1.0">
|
||||||
|
<com.android.inputmethod.voice.SoundIndicator
|
||||||
|
android:id="@+id/sound_indicator"
|
||||||
|
android:src="@drawable/mic_full"
|
||||||
|
android:background="@drawable/mic_base"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:src="@drawable/mic_slash"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:visibility="visible"/>
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:indeterminateOnly="false"
|
||||||
|
android:layout_height="60dip"
|
||||||
|
android:layout_width="60dip"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dip"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="@string/cancel"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="@drawable/btn_center"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textSize="19sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,19 @@
|
||||||
<bool name="config_enable_show_settings_key_option">false</bool>
|
<bool name="config_enable_show_settings_key_option">false</bool>
|
||||||
<bool name="config_enable_show_subtype_settings">false</bool>
|
<bool name="config_enable_show_subtype_settings">false</bool>
|
||||||
<bool name="config_enable_show_voice_key_option">false</bool>
|
<bool name="config_enable_show_voice_key_option">false</bool>
|
||||||
|
<bool name="config_enable_show_popup_on_keypress_option">false</bool>
|
||||||
|
<bool name="config_enable_show_recorrection_option">false</bool>
|
||||||
|
<bool name="config_enable_quick_fixes_option">false</bool>
|
||||||
|
<bool name="config_enable_bigram_suggestions_option">false</bool>
|
||||||
<bool name="config_candidate_highlight_font_color_enabled">false</bool>
|
<bool name="config_candidate_highlight_font_color_enabled">false</bool>
|
||||||
<bool name="config_swipe_down_dismiss_keyboard_enabled">false</bool>
|
<bool name="config_swipe_down_dismiss_keyboard_enabled">false</bool>
|
||||||
<bool name="config_sliding_key_input_enabled">false</bool>
|
<bool name="config_sliding_key_input_enabled">false</bool>
|
||||||
<bool name="config_digit_popup_characters_enabled">false</bool>
|
<bool name="config_digit_popup_characters_enabled">false</bool>
|
||||||
<!-- Whether or not Popup on key press is enabled by default -->
|
<!-- Whether or not Popup on key press is enabled by default -->
|
||||||
<bool name="config_default_popup_preview">false</bool>
|
<bool name="config_default_popup_preview">false</bool>
|
||||||
|
<bool name="config_use_spacebar_language_switcher">false</bool>
|
||||||
|
<!-- The language is never displayed if == 0, always displayed if < 0 -->
|
||||||
|
<integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer>
|
||||||
<!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
|
<!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
|
||||||
<string name="config_default_keyboard_theme_id" translatable="false">5</string>
|
<string name="config_default_keyboard_theme_id" translatable="false">5</string>
|
||||||
<string name="config_text_size_of_language_on_spacebar" translatable="false">medium</string>
|
<string name="config_text_size_of_language_on_spacebar" translatable="false">medium</string>
|
||||||
|
|
|
@ -19,5 +19,5 @@
|
||||||
-->
|
-->
|
||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<!-- Default value of the visibility of the suggestion strip -->
|
<!-- Default value of the visibility of the suggestion strip -->
|
||||||
<string name="prefs_suggestion_visibility_default_value" translatable="false">1</string>
|
<string name="prefs_suggestion_visibility_default_value" translatable="false">2</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -25,12 +25,25 @@
|
||||||
<bool name="config_enable_show_settings_key_option">true</bool>
|
<bool name="config_enable_show_settings_key_option">true</bool>
|
||||||
<bool name="config_enable_show_subtype_settings">true</bool>
|
<bool name="config_enable_show_subtype_settings">true</bool>
|
||||||
<bool name="config_enable_show_voice_key_option">true</bool>
|
<bool name="config_enable_show_voice_key_option">true</bool>
|
||||||
|
<bool name="config_enable_show_popup_on_keypress_option">true</bool>
|
||||||
|
<bool name="config_enable_show_recorrection_option">true</bool>
|
||||||
|
<bool name="config_enable_quick_fixes_option">true</bool>
|
||||||
|
<bool name="config_enable_bigram_suggestions_option">true</bool>
|
||||||
|
<bool name="config_enable_usability_study_mode_option">false</bool>
|
||||||
<bool name="config_candidate_highlight_font_color_enabled">true</bool>
|
<bool name="config_candidate_highlight_font_color_enabled">true</bool>
|
||||||
<bool name="config_swipe_down_dismiss_keyboard_enabled">true</bool>
|
<bool name="config_swipe_down_dismiss_keyboard_enabled">true</bool>
|
||||||
<bool name="config_sliding_key_input_enabled">true</bool>
|
<bool name="config_sliding_key_input_enabled">true</bool>
|
||||||
<bool name="config_digit_popup_characters_enabled">true</bool>
|
<bool name="config_digit_popup_characters_enabled">true</bool>
|
||||||
<!-- Whether or not Popup on key press is enabled by default -->
|
<!-- Whether or not Popup on key press is enabled by default -->
|
||||||
<bool name="config_default_popup_preview">true</bool>
|
<bool name="config_default_popup_preview">true</bool>
|
||||||
|
<!-- Default values for whether quick fixes and bigram suggestions are activated -->
|
||||||
|
<bool name="config_default_quick_fixes">true</bool>
|
||||||
|
<bool name="config_default_bigram_suggestions">true</bool>
|
||||||
|
<bool name="config_use_spacebar_language_switcher">true</bool>
|
||||||
|
<!-- The language is never displayed if == 0, always displayed if < 0 -->
|
||||||
|
<integer name="config_delay_before_fadeout_language_on_spacebar">-1</integer>
|
||||||
|
<integer name="config_duration_of_fadeout_language_on_spacebar">50</integer>
|
||||||
|
<integer name="config_final_fadeout_percentage_of_language_on_spacebar">15</integer>
|
||||||
<integer name="config_delay_before_preview">0</integer>
|
<integer name="config_delay_before_preview">0</integer>
|
||||||
<integer name="config_delay_after_preview">10</integer>
|
<integer name="config_delay_after_preview">10</integer>
|
||||||
<integer name="config_preview_fadein_anim_time">0</integer>
|
<integer name="config_preview_fadein_anim_time">0</integer>
|
||||||
|
|
|
@ -138,4 +138,14 @@
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
<item>5</item>
|
<item>5</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<!-- Subtype locale name exceptions -->
|
||||||
|
<string-array name="subtype_locale_exception_keys">
|
||||||
|
<item>en_US</item>
|
||||||
|
<item>en_GB</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="subtype_locale_exception_values">
|
||||||
|
<item>English (US)</item>
|
||||||
|
<item>English (UK)</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<string name="english_ime_name">Android keyboard</string>
|
<string name="english_ime_name">Android keyboard</string>
|
||||||
<!-- Title for Latin keyboard settings activity / dialog -->
|
<!-- Title for Latin keyboard settings activity / dialog -->
|
||||||
<string name="english_ime_settings">Android keyboard settings</string>
|
<string name="english_ime_settings">Android keyboard settings</string>
|
||||||
<!-- Title for Latin keyboard input options dialog -->
|
<!-- Title for Latin keyboard input options dialog [CHAR LIMIT=25] -->
|
||||||
<string name="english_ime_input_options">Input options</string>
|
<string name="english_ime_input_options">Input options</string>
|
||||||
|
|
||||||
<!-- Option to provide vibrate/haptic feedback on keypress -->
|
<!-- Option to provide vibrate/haptic feedback on keypress -->
|
||||||
|
@ -34,8 +34,11 @@
|
||||||
<!-- Option to pop up the character with a larger font above soft keyboard -->
|
<!-- Option to pop up the character with a larger font above soft keyboard -->
|
||||||
<string name="popup_on_keypress">Popup on keypress</string>
|
<string name="popup_on_keypress">Popup on keypress</string>
|
||||||
|
|
||||||
|
<!-- Category title for general settings for Android keyboard -->
|
||||||
|
<string name="general_category">General</string>
|
||||||
|
|
||||||
<!-- Category title for text prediction -->
|
<!-- Category title for text prediction -->
|
||||||
<string name="prediction_category">Word suggestion settings</string>
|
<string name="prediction_category">Text correction</string>
|
||||||
|
|
||||||
<!-- Option to enable auto capitalization of sentences -->
|
<!-- Option to enable auto capitalization of sentences -->
|
||||||
<string name="auto_cap">Auto-capitalization</string>
|
<string name="auto_cap">Auto-capitalization</string>
|
||||||
|
@ -46,7 +49,7 @@
|
||||||
<string name="quick_fixes_summary">Corrects commonly typed mistakes</string>
|
<string name="quick_fixes_summary">Corrects commonly typed mistakes</string>
|
||||||
|
|
||||||
<!-- Option to enable showing suggestions -->
|
<!-- Option to enable showing suggestions -->
|
||||||
<string name="prefs_show_suggestions">Show suggestions</string>
|
<string name="prefs_show_suggestions">Show correction suggestions</string>
|
||||||
<!-- Description for show suggestions -->
|
<!-- Description for show suggestions -->
|
||||||
<string name="prefs_show_suggestions_summary">Display suggested words while typing</string>
|
<string name="prefs_show_suggestions_summary">Display suggested words while typing</string>
|
||||||
<string name="prefs_suggestion_visibility_show_name">Always show</string>
|
<string name="prefs_suggestion_visibility_show_name">Always show</string>
|
||||||
|
@ -111,15 +114,15 @@
|
||||||
<string name="voice_warning_locale_not_supported">Voice input is not currently supported for your language, but does work in English.</string>
|
<string name="voice_warning_locale_not_supported">Voice input is not currently supported for your language, but does work in English.</string>
|
||||||
|
|
||||||
<!-- Message of the warning dialog that shows when a user initiates voice input for
|
<!-- Message of the warning dialog that shows when a user initiates voice input for
|
||||||
the first time, or turns it on in settings. -->
|
the first time, or turns it on in settings. [CHAR LIMIT=200] -->
|
||||||
<string name="voice_warning_may_not_understand">Voice input uses Google\'s speech recognition. <a href="http://m.google.com/privacy">The Mobile Privacy Policy</a> applies.</string>
|
<string name="voice_warning_may_not_understand">Voice input uses Google\'s speech recognition. <a href="http://m.google.com/privacy">The Mobile Privacy Policy</a> applies.</string>
|
||||||
|
|
||||||
<!-- An additional part of the warning dialog for voice input that only shows when the user
|
<!-- An additional part of the warning dialog for voice input that only shows when the user
|
||||||
actually initiates voice input, rather than just turning it on in settings. -->
|
actually initiates voice input, rather than just turning it on in settings. [CHAR LIMIT=200] -->
|
||||||
<string name="voice_warning_how_to_turn_off">To turn off voice input, go to input method settings.</string>
|
<string name="voice_warning_how_to_turn_off">To turn off voice input, go to input method settings.</string>
|
||||||
|
|
||||||
<!-- Message to show when user enables the voice input settings (which says
|
<!-- Message to show when user enables the voice input settings (which says
|
||||||
"Press the microphone button"). -->
|
"Press the microphone button"). [CHAR LIMIT=100] -->
|
||||||
<string name="voice_hint_dialog_message">To use voice input, press the microphone button.</string>
|
<string name="voice_hint_dialog_message">To use voice input, press the microphone button.</string>
|
||||||
|
|
||||||
<!-- Short message to tell the user the system is ready for them to speak. -->
|
<!-- Short message to tell the user the system is ready for them to speak. -->
|
||||||
|
|
|
@ -57,7 +57,6 @@
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
|
latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
|
||||||
latin:code="@integer/key_space"
|
latin:code="@integer/key_space"
|
||||||
latin:keyIcon="@drawable/sym_keyboard_space_holo"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="smileyKeyStyle"
|
latin:styleName="smileyKeyStyle"
|
||||||
|
@ -66,6 +65,12 @@
|
||||||
latin:keyHintIcon="@drawable/hint_popup_holo"
|
latin:keyHintIcon="@drawable/hint_popup_holo"
|
||||||
latin:popupCharacters="@string/alternates_for_smiley"
|
latin:popupCharacters="@string/alternates_for_smiley"
|
||||||
latin:maxPopupKeyboardColumn="5" />
|
latin:maxPopupKeyboardColumn="5" />
|
||||||
|
<key-style
|
||||||
|
latin:styleName="settingsKeyStyle"
|
||||||
|
latin:code="@integer/key_settings"
|
||||||
|
latin:keyIcon="@drawable/sym_keyboard_settings_holo"
|
||||||
|
latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="micKeyStyle"
|
latin:styleName="micKeyStyle"
|
||||||
latin:code="@integer/key_voice"
|
latin:code="@integer/key_voice"
|
||||||
|
@ -102,12 +107,10 @@
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="spaceKeyStyle"
|
latin:styleName="spaceKeyStyle"
|
||||||
latin:code="@integer/key_space"
|
latin:code="@integer/key_space"
|
||||||
latin:keyIcon="@drawable/sym_bkeyboard_space"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
|
latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
|
||||||
latin:code="@integer/key_space"
|
latin:code="@integer/key_space"
|
||||||
latin:keyIcon="@drawable/sym_bkeyboard_space"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="smileyKeyStyle"
|
latin:styleName="smileyKeyStyle"
|
||||||
|
@ -116,6 +119,12 @@
|
||||||
latin:keyHintIcon="@drawable/hint_popup_holo"
|
latin:keyHintIcon="@drawable/hint_popup_holo"
|
||||||
latin:popupCharacters="@string/alternates_for_smiley"
|
latin:popupCharacters="@string/alternates_for_smiley"
|
||||||
latin:maxPopupKeyboardColumn="5" />
|
latin:maxPopupKeyboardColumn="5" />
|
||||||
|
<key-style
|
||||||
|
latin:styleName="settingsKeyStyle"
|
||||||
|
latin:code="@integer/key_settings"
|
||||||
|
latin:keyIcon="@drawable/sym_bkeyboard_settings"
|
||||||
|
latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
|
||||||
|
latin:parentStyle="functionalKeyStyle" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="micKeyStyle"
|
latin:styleName="micKeyStyle"
|
||||||
latin:code="@integer/key_voice"
|
latin:code="@integer/key_voice"
|
||||||
|
|
|
@ -120,7 +120,10 @@
|
||||||
<!-- There is an empty area bellow the "More" key and left of the "space" key. To ignore
|
<!-- There is an empty area bellow the "More" key and left of the "space" key. To ignore
|
||||||
the touch event on the area, "space" is intentionally not marked as a left edge key. -->
|
the touch event on the area, "space" is intentionally not marked as a left edge key. -->
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="16.406%p" />
|
latin:horizontalGap="8.362%p" />
|
||||||
|
<Key
|
||||||
|
latin:keyStyle="settingsKeyStyle"
|
||||||
|
latin:keyWidth="8.042%p" />
|
||||||
<Key
|
<Key
|
||||||
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
|
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
|
||||||
latin:keyWidth="24.127%p" />
|
latin:keyWidth="24.127%p" />
|
||||||
|
|
|
@ -81,7 +81,6 @@
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="numSpaceKeyStyle"
|
latin:styleName="numSpaceKeyStyle"
|
||||||
latin:code="@integer/key_space"
|
latin:code="@integer/key_space"
|
||||||
latin:keyIcon="@drawable/sym_keyboard_space_holo"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
||||||
</case>
|
</case>
|
||||||
<case
|
<case
|
||||||
|
@ -143,7 +142,6 @@
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="numSpaceKeyStyle"
|
latin:styleName="numSpaceKeyStyle"
|
||||||
latin:code="@integer/key_space"
|
latin:code="@integer/key_space"
|
||||||
latin:keyIcon="@drawable/sym_bkeyboard_space"
|
|
||||||
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
|
||||||
</case>
|
</case>
|
||||||
</switch>
|
</switch>
|
||||||
|
|
|
@ -128,10 +128,13 @@
|
||||||
<!-- There is an empty area bellow the "More" key and left of the "space" key. To ignore
|
<!-- There is an empty area bellow the "More" key and left of the "space" key. To ignore
|
||||||
the touch event on the area, "space" is intentionally not marked as a left edge key. -->
|
the touch event on the area, "space" is intentionally not marked as a left edge key. -->
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="20.427%p" />
|
latin:horizontalGap="12.340%p" />
|
||||||
|
<Key
|
||||||
|
latin:keyStyle="settingsKeyStyle"
|
||||||
|
latin:keyWidth="8.042%p" />
|
||||||
<Key
|
<Key
|
||||||
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
|
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
|
||||||
latin:keyWidth="16.085%p" />
|
latin:keyWidth="16.084%p" />
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="8.479%p" />
|
latin:horizontalGap="8.479%p" />
|
||||||
<Key
|
<Key
|
||||||
|
|
|
@ -140,7 +140,10 @@
|
||||||
<!-- There is an empty area bellow the "More" key and left of the "space" key. To ignore
|
<!-- There is an empty area bellow the "More" key and left of the "space" key. To ignore
|
||||||
the touch event on the area, "space" is intentionally not marked as a left edge key. -->
|
the touch event on the area, "space" is intentionally not marked as a left edge key. -->
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="16.406%p" />
|
latin:horizontalGap="8.362%p" />
|
||||||
|
<Key
|
||||||
|
latin:keyStyle="settingsKeyStyle"
|
||||||
|
latin:keyWidth="8.042%p" />
|
||||||
<Key
|
<Key
|
||||||
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
|
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
|
||||||
latin:keyWidth="24.127%p" />
|
latin:keyWidth="24.127%p" />
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
latin:keyWidth="8.042%p"
|
latin:keyWidth="8.042%p"
|
||||||
>
|
>
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="16.404%p" />
|
latin:horizontalGap="8.362%p" />
|
||||||
|
<Key
|
||||||
|
latin:keyStyle="settingsKeyStyle" />
|
||||||
<switch>
|
<switch>
|
||||||
<case
|
<case
|
||||||
latin:mode="email"
|
latin:mode="email"
|
||||||
|
|
|
@ -149,7 +149,9 @@
|
||||||
latin:keyWidth="8.042%p"
|
latin:keyWidth="8.042%p"
|
||||||
>
|
>
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="16.404%p" />
|
latin:horizontalGap="8.362%p" />
|
||||||
|
<Key
|
||||||
|
latin:keyStyle="settingsKeyStyle" />
|
||||||
<Key
|
<Key
|
||||||
latin:keyLabel="/" />
|
latin:keyLabel="/" />
|
||||||
<Key
|
<Key
|
||||||
|
|
|
@ -135,7 +135,9 @@
|
||||||
latin:keyWidth="8.042%p"
|
latin:keyWidth="8.042%p"
|
||||||
>
|
>
|
||||||
<Spacer
|
<Spacer
|
||||||
latin:horizontalGap="32.488%p" />
|
latin:horizontalGap="24.446%p" />
|
||||||
|
<Key
|
||||||
|
latin:keyStyle="settingsKeyStyle" />
|
||||||
<Key
|
<Key
|
||||||
latin:keyStyle="spaceKeyStyle"
|
latin:keyStyle="spaceKeyStyle"
|
||||||
latin:keyWidth="37.454%p" />
|
latin:keyWidth="37.454%p" />
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -18,62 +18,68 @@
|
||||||
android:title="@string/english_ime_settings"
|
android:title="@string/english_ime_settings"
|
||||||
android:key="english_ime_settings">
|
android:key="english_ime_settings">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<PreferenceCategory
|
||||||
android:key="vibrate_on"
|
android:title="@string/general_category"
|
||||||
android:title="@string/vibrate_on_keypress"
|
android:key="general_settings">
|
||||||
android:persistent="true"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="sound_on"
|
android:key="auto_cap"
|
||||||
android:title="@string/sound_on_keypress"
|
android:title="@string/auto_cap"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
/>
|
android:defaultValue="true"
|
||||||
|
/>
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="popup_on"
|
android:key="vibrate_on"
|
||||||
android:title="@string/popup_on_keypress"
|
android:title="@string/vibrate_on_keypress"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:defaultValue="@bool/config_default_popup_preview"
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="recorrection_enabled"
|
android:key="sound_on"
|
||||||
android:title="@string/prefs_enable_recorrection"
|
android:title="@string/sound_on_keypress"
|
||||||
android:summary="@string/prefs_enable_recorrection_summary"
|
android:persistent="true"
|
||||||
android:persistent="true"
|
/>
|
||||||
android:defaultValue="@bool/default_recorrection_enabled"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="auto_cap"
|
android:key="popup_on"
|
||||||
android:title="@string/auto_cap"
|
android:title="@string/popup_on_keypress"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:defaultValue="true"
|
android:defaultValue="@bool/config_default_popup_preview"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ListPreference
|
<CheckBoxPreference
|
||||||
android:key="settings_key"
|
android:key="recorrection_enabled"
|
||||||
android:title="@string/prefs_settings_key"
|
android:title="@string/prefs_enable_recorrection"
|
||||||
android:persistent="true"
|
android:summary="@string/prefs_enable_recorrection_summary"
|
||||||
android:entryValues="@array/settings_key_modes_values"
|
android:persistent="true"
|
||||||
android:entries="@array/settings_key_modes"
|
android:defaultValue="@bool/default_recorrection_enabled"
|
||||||
android:defaultValue="@string/settings_key_mode_auto"
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="voice_mode"
|
android:key="settings_key"
|
||||||
android:title="@string/voice_input"
|
android:title="@string/prefs_settings_key"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:entryValues="@array/voice_input_modes_values"
|
android:entryValues="@array/settings_key_modes_values"
|
||||||
android:entries="@array/voice_input_modes"
|
android:entries="@array/settings_key_modes"
|
||||||
android:defaultValue="@string/voice_mode_main"
|
android:defaultValue="@string/settings_key_mode_auto"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PreferenceScreen
|
<ListPreference
|
||||||
android:key="subtype_settings"
|
android:key="voice_mode"
|
||||||
android:title="@string/language_selection_title"
|
android:title="@string/voice_input"
|
||||||
android:summary="@string/language_selection_summary" />
|
android:persistent="true"
|
||||||
|
android:entryValues="@array/voice_input_modes_values"
|
||||||
|
android:entries="@array/voice_input_modes"
|
||||||
|
android:defaultValue="@string/voice_mode_main"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="subtype_settings"
|
||||||
|
android:title="@string/language_selection_title"
|
||||||
|
android:summary="@string/language_selection_summary" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/prediction_category"
|
android:title="@string/prediction_category"
|
||||||
|
@ -87,16 +93,6 @@
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
android:key="show_suggestions_setting"
|
|
||||||
android:summary="@string/prefs_show_suggestions_summary"
|
|
||||||
android:title="@string/prefs_show_suggestions"
|
|
||||||
android:persistent="true"
|
|
||||||
android:entryValues="@array/prefs_suggestion_visibility_values"
|
|
||||||
android:entries="@array/prefs_suggestion_visibilities"
|
|
||||||
android:defaultValue="@string/prefs_suggestion_visibility_default_value"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="auto_correction_threshold"
|
android:key="auto_correction_threshold"
|
||||||
android:title="@string/auto_correction"
|
android:title="@string/auto_correction"
|
||||||
|
@ -107,6 +103,16 @@
|
||||||
android:defaultValue="@string/auto_correction_threshold_mode_index_modest"
|
android:defaultValue="@string/auto_correction_threshold_mode_index_modest"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="show_suggestions_setting"
|
||||||
|
android:summary="@string/prefs_show_suggestions_summary"
|
||||||
|
android:title="@string/prefs_show_suggestions"
|
||||||
|
android:persistent="true"
|
||||||
|
android:entryValues="@array/prefs_suggestion_visibility_values"
|
||||||
|
android:entries="@array/prefs_suggestion_visibilities"
|
||||||
|
android:defaultValue="@string/prefs_suggestion_visibility_default_value"
|
||||||
|
/>
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="bigram_suggestion"
|
android:key="bigram_suggestion"
|
||||||
android:title="@string/bigram_suggestion"
|
android:title="@string/bigram_suggestion"
|
||||||
|
|
|
@ -330,6 +330,10 @@ public class Keyboard {
|
||||||
return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
|
return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isManualTemporaryUpperCaseFromAuto() {
|
||||||
|
return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCaseFromAuto();
|
||||||
|
}
|
||||||
|
|
||||||
public KeyboardShiftState getKeyboardShiftState() {
|
public KeyboardShiftState getKeyboardShiftState() {
|
||||||
return mShiftState;
|
return mShiftState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,26 +24,38 @@ public class KeyboardShiftState {
|
||||||
|
|
||||||
private static final int NORMAL = 0;
|
private static final int NORMAL = 0;
|
||||||
private static final int MANUAL_SHIFTED = 1;
|
private static final int MANUAL_SHIFTED = 1;
|
||||||
private static final int SHIFT_LOCKED = 2;
|
private static final int MANUAL_SHIFTED_FROM_AUTO = 2;
|
||||||
private static final int AUTO_SHIFTED = 3;
|
private static final int AUTO_SHIFTED = 3;
|
||||||
private static final int SHIFT_LOCK_SHIFTED = 4;
|
private static final int SHIFT_LOCKED = 4;
|
||||||
|
private static final int SHIFT_LOCK_SHIFTED = 5;
|
||||||
|
|
||||||
private int mState = NORMAL;
|
private int mState = NORMAL;
|
||||||
|
|
||||||
public boolean setShifted(boolean newShiftState) {
|
public boolean setShifted(boolean newShiftState) {
|
||||||
final int oldState = mState;
|
final int oldState = mState;
|
||||||
if (newShiftState) {
|
if (newShiftState) {
|
||||||
if (oldState == NORMAL || oldState == AUTO_SHIFTED) {
|
switch (oldState) {
|
||||||
|
case NORMAL:
|
||||||
mState = MANUAL_SHIFTED;
|
mState = MANUAL_SHIFTED;
|
||||||
} else if (oldState == SHIFT_LOCKED) {
|
break;
|
||||||
|
case AUTO_SHIFTED:
|
||||||
|
mState = MANUAL_SHIFTED_FROM_AUTO;
|
||||||
|
break;
|
||||||
|
case SHIFT_LOCKED:
|
||||||
mState = SHIFT_LOCK_SHIFTED;
|
mState = SHIFT_LOCK_SHIFTED;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (oldState == MANUAL_SHIFTED || oldState == AUTO_SHIFTED) {
|
switch (oldState) {
|
||||||
|
case MANUAL_SHIFTED:
|
||||||
|
case MANUAL_SHIFTED_FROM_AUTO:
|
||||||
|
case AUTO_SHIFTED:
|
||||||
mState = NORMAL;
|
mState = NORMAL;
|
||||||
} else if (oldState == SHIFT_LOCK_SHIFTED) {
|
break;
|
||||||
|
case SHIFT_LOCK_SHIFTED:
|
||||||
mState = SHIFT_LOCKED;
|
mState = SHIFT_LOCKED;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
Log.d(TAG, "setShifted(" + newShiftState + "): " + toString(oldState) + " > " + this);
|
Log.d(TAG, "setShifted(" + newShiftState + "): " + toString(oldState) + " > " + this);
|
||||||
|
@ -53,11 +65,21 @@ public class KeyboardShiftState {
|
||||||
public void setShiftLocked(boolean newShiftLockState) {
|
public void setShiftLocked(boolean newShiftLockState) {
|
||||||
final int oldState = mState;
|
final int oldState = mState;
|
||||||
if (newShiftLockState) {
|
if (newShiftLockState) {
|
||||||
if (oldState == NORMAL || oldState == MANUAL_SHIFTED || oldState == AUTO_SHIFTED)
|
switch (oldState) {
|
||||||
|
case NORMAL:
|
||||||
|
case MANUAL_SHIFTED:
|
||||||
|
case MANUAL_SHIFTED_FROM_AUTO:
|
||||||
|
case AUTO_SHIFTED:
|
||||||
mState = SHIFT_LOCKED;
|
mState = SHIFT_LOCKED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (oldState == SHIFT_LOCKED || oldState == SHIFT_LOCK_SHIFTED)
|
switch (oldState) {
|
||||||
|
case SHIFT_LOCKED:
|
||||||
|
case SHIFT_LOCK_SHIFTED:
|
||||||
mState = NORMAL;
|
mState = NORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
Log.d(TAG, "setShiftLocked(" + newShiftLockState + "): " + toString(oldState)
|
Log.d(TAG, "setShiftLocked(" + newShiftLockState + "): " + toString(oldState)
|
||||||
|
@ -84,7 +106,12 @@ public class KeyboardShiftState {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isManualTemporaryUpperCase() {
|
public boolean isManualTemporaryUpperCase() {
|
||||||
return mState == MANUAL_SHIFTED || mState == SHIFT_LOCK_SHIFTED;
|
return mState == MANUAL_SHIFTED || mState == MANUAL_SHIFTED_FROM_AUTO
|
||||||
|
|| mState == SHIFT_LOCK_SHIFTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isManualTemporaryUpperCaseFromAuto() {
|
||||||
|
return mState == MANUAL_SHIFTED_FROM_AUTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -96,8 +123,9 @@ public class KeyboardShiftState {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case NORMAL: return "NORMAL";
|
case NORMAL: return "NORMAL";
|
||||||
case MANUAL_SHIFTED: return "MANUAL_SHIFTED";
|
case MANUAL_SHIFTED: return "MANUAL_SHIFTED";
|
||||||
case SHIFT_LOCKED: return "SHIFT_LOCKED";
|
case MANUAL_SHIFTED_FROM_AUTO: return "MANUAL_SHIFTED_FROM_AUTO";
|
||||||
case AUTO_SHIFTED: return "AUTO_SHIFTED";
|
case AUTO_SHIFTED: return "AUTO_SHIFTED";
|
||||||
|
case SHIFT_LOCKED: return "SHIFT_LOCKED";
|
||||||
case SHIFT_LOCK_SHIFTED: return "SHIFT_LOCK_SHIFTED";
|
case SHIFT_LOCK_SHIFTED: return "SHIFT_LOCK_SHIFTED";
|
||||||
default: return "UKNOWN";
|
default: return "UKNOWN";
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,15 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
boolean voiceButtonOnPrimary) {
|
boolean voiceButtonOnPrimary) {
|
||||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
|
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
|
||||||
try {
|
try {
|
||||||
|
if (mInputView == null) return;
|
||||||
|
final Keyboard oldKeyboard = mInputView.getKeyboard();
|
||||||
loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary, false);
|
loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary, false);
|
||||||
|
final Keyboard newKeyboard = mInputView.getKeyboard();
|
||||||
|
if (newKeyboard.isAlphaKeyboard()) {
|
||||||
|
final boolean localeChanged = (oldKeyboard == null)
|
||||||
|
|| !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
|
||||||
|
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
|
||||||
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
LatinImeLogger.logOnException(mode + "," + imeOptions, e);
|
LatinImeLogger.logOnException(mode + "," + imeOptions, e);
|
||||||
|
@ -167,7 +175,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
private void loadKeyboardInternal(int mode, int imeOptions, boolean voiceButtonEnabled,
|
private void loadKeyboardInternal(int mode, int imeOptions, boolean voiceButtonEnabled,
|
||||||
boolean voiceButtonOnPrimary, boolean isSymbols) {
|
boolean voiceButtonOnPrimary, boolean isSymbols) {
|
||||||
if (mInputView == null) return;
|
if (mInputView == null) return;
|
||||||
mInputView.setPreviewEnabled(mInputMethodService.getPopupOn());
|
|
||||||
|
|
||||||
mMode = mode;
|
mMode = mode;
|
||||||
mImeOptions = imeOptions;
|
mImeOptions = imeOptions;
|
||||||
|
@ -176,13 +183,16 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
mIsSymbols = isSymbols;
|
mIsSymbols = isSymbols;
|
||||||
// Update the settings key state because number of enabled IMEs could have been changed
|
// Update the settings key state because number of enabled IMEs could have been changed
|
||||||
mHasSettingsKey = getSettingsKeyMode(mPrefs, mInputMethodService);
|
mHasSettingsKey = getSettingsKeyMode(mPrefs, mInputMethodService);
|
||||||
|
final KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols);
|
||||||
|
|
||||||
|
final Keyboard oldKeyboard = mInputView.getKeyboard();
|
||||||
|
if (oldKeyboard != null && oldKeyboard.mId.equals(id))
|
||||||
|
return;
|
||||||
|
|
||||||
makeSymbolsKeyboardIds();
|
makeSymbolsKeyboardIds();
|
||||||
|
|
||||||
KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols);
|
|
||||||
LatinKeyboard keyboard = getKeyboard(id);
|
|
||||||
|
|
||||||
mCurrentId = id;
|
mCurrentId = id;
|
||||||
mInputView.setKeyboard(keyboard);
|
mInputView.setPreviewEnabled(mInputMethodService.getPopupOn());
|
||||||
|
mInputView.setKeyboard(getKeyboard(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
private LatinKeyboard getKeyboard(KeyboardId id) {
|
private LatinKeyboard getKeyboard(KeyboardId id) {
|
||||||
|
@ -210,6 +220,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
|
|
||||||
keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive);
|
keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive);
|
||||||
keyboard.setShifted(false);
|
keyboard.setShifted(false);
|
||||||
|
// If the cached keyboard had been switched to another keyboard while the language was
|
||||||
|
// displayed on its spacebar, it might have had arbitrary text fade factor. In such case,
|
||||||
|
// we should reset the text fade factor.
|
||||||
|
keyboard.setSpacebarTextFadeFactor(0.0f, null);
|
||||||
return keyboard;
|
return keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +327,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isManualTemporaryUpperCaseFromAuto() {
|
||||||
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
|
if (latinKeyboard != null)
|
||||||
|
return latinKeyboard.isManualTemporaryUpperCaseFromAuto();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void setManualTemporaryUpperCase(boolean shifted) {
|
private void setManualTemporaryUpperCase(boolean shifted) {
|
||||||
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
if (latinKeyboard != null) {
|
if (latinKeyboard != null) {
|
||||||
|
@ -468,6 +489,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()) {
|
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()) {
|
||||||
// Shift has been pressed without chording while shifted state.
|
// Shift has been pressed without chording while shifted state.
|
||||||
toggleShift();
|
toggleShift();
|
||||||
|
} else if (isManualTemporaryUpperCaseFromAuto() && shiftKeyState.isPressing()) {
|
||||||
|
// Shift has been pressed without chording while manual temporary upper case
|
||||||
|
// transited from automatic temporary upper case.
|
||||||
|
toggleShift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shiftKeyState.onRelease();
|
shiftKeyState.onRelease();
|
||||||
|
|
|
@ -298,8 +298,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
|
|
||||||
TypedArray a = context.obtainStyledAttributes(
|
TypedArray a = context.obtainStyledAttributes(
|
||||||
attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
|
attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
|
||||||
LayoutInflater inflate =
|
|
||||||
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
int previewLayout = 0;
|
int previewLayout = 0;
|
||||||
int keyTextSize = 0;
|
int keyTextSize = 0;
|
||||||
|
|
||||||
|
@ -365,7 +363,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
|
|
||||||
mPreviewPopup = new PopupWindow(context);
|
mPreviewPopup = new PopupWindow(context);
|
||||||
if (previewLayout != 0) {
|
if (previewLayout != 0) {
|
||||||
mPreviewText = (TextView) inflate.inflate(previewLayout, null);
|
mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null);
|
||||||
mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large);
|
mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large);
|
||||||
mPreviewPopup.setContentView(mPreviewText);
|
mPreviewPopup.setContentView(mPreviewText);
|
||||||
mPreviewPopup.setBackgroundDrawable(null);
|
mPreviewPopup.setBackgroundDrawable(null);
|
||||||
|
@ -912,9 +910,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
// We should re-draw popup preview when 1) we need to hide the preview, 2) we will show
|
// We should re-draw popup preview when 1) we need to hide the preview, 2) we will show
|
||||||
// the space key preview and 3) pointer moves off the space key to other letter key, we
|
// the space key preview and 3) pointer moves off the space key to other letter key, we
|
||||||
// should hide the preview of the previous key.
|
// should hide the preview of the previous key.
|
||||||
@SuppressWarnings("unused")
|
|
||||||
final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null)
|
final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null)
|
||||||
|| (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER
|
|| (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
|
||||||
&& SubtypeSwitcher.getInstance().needsToDisplayLanguage()
|
&& SubtypeSwitcher.getInstance().needsToDisplayLanguage()
|
||||||
&& (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex)));
|
&& (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex)));
|
||||||
// If key changed and preview is on or the key is space (language switch is enabled)
|
// If key changed and preview is on or the key is space (language switch is enabled)
|
||||||
|
@ -1081,9 +1078,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
|
|
||||||
private View inflateMiniKeyboardContainer(Key popupKey) {
|
private View inflateMiniKeyboardContainer(Key popupKey) {
|
||||||
int popupKeyboardResId = mKeyboard.getPopupKeyboardResId();
|
int popupKeyboardResId = mKeyboard.getPopupKeyboardResId();
|
||||||
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(
|
View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null);
|
||||||
Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
View container = inflater.inflate(mPopupLayout, null);
|
|
||||||
if (container == null)
|
if (container == null)
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
|
||||||
|
@ -1410,6 +1405,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
mBuffer = null;
|
mBuffer = null;
|
||||||
mCanvas = null;
|
mCanvas = null;
|
||||||
mMiniKeyboardCache.clear();
|
mMiniKeyboardCache.clear();
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void purgeKeyboardAndClosing() {
|
||||||
|
mKeyboard = null;
|
||||||
|
closing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,7 @@ import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Paint.Align;
|
import android.graphics.Paint.Align;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
|
@ -47,7 +48,9 @@ public class LatinKeyboard extends Keyboard {
|
||||||
private final Drawable mSpaceAutoCorrectionIndicator;
|
private final Drawable mSpaceAutoCorrectionIndicator;
|
||||||
private final Drawable mButtonArrowLeftIcon;
|
private final Drawable mButtonArrowLeftIcon;
|
||||||
private final Drawable mButtonArrowRightIcon;
|
private final Drawable mButtonArrowRightIcon;
|
||||||
private final int mSpaceBarTextShadowColor;
|
private final int mSpacebarTextColor;
|
||||||
|
private final int mSpacebarTextShadowColor;
|
||||||
|
private float mSpacebarTextFadeFactor = 0.0f;
|
||||||
private final int[] mSpaceKeyIndexArray;
|
private final int[] mSpaceKeyIndexArray;
|
||||||
private int mSpaceDragStartX;
|
private int mSpaceDragStartX;
|
||||||
private int mSpaceDragLastDiff;
|
private int mSpaceDragLastDiff;
|
||||||
|
@ -80,11 +83,12 @@ public class LatinKeyboard extends Keyboard {
|
||||||
super(context, id.getXmlId(), id);
|
super(context, id.getXmlId(), id);
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mSpacebarTextColor = res.getColor(R.color.latinkeyboard_bar_language_text);
|
||||||
if (id.mColorScheme == KeyboardView.COLOR_SCHEME_BLACK) {
|
if (id.mColorScheme == KeyboardView.COLOR_SCHEME_BLACK) {
|
||||||
mSpaceBarTextShadowColor = res.getColor(
|
mSpacebarTextShadowColor = res.getColor(
|
||||||
R.color.latinkeyboard_bar_language_shadow_black);
|
R.color.latinkeyboard_bar_language_shadow_black);
|
||||||
} else { // default color scheme is KeyboardView.COLOR_SCHEME_WHITE
|
} else { // default color scheme is KeyboardView.COLOR_SCHEME_WHITE
|
||||||
mSpaceBarTextShadowColor = res.getColor(
|
mSpacebarTextShadowColor = res.getColor(
|
||||||
R.color.latinkeyboard_bar_language_shadow_white);
|
R.color.latinkeyboard_bar_language_shadow_white);
|
||||||
}
|
}
|
||||||
mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led);
|
mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led);
|
||||||
|
@ -96,25 +100,38 @@ public class LatinKeyboard extends Keyboard {
|
||||||
mSpaceKeyIndexArray = new int[] { indexOf(CODE_SPACE) };
|
mSpaceKeyIndexArray = new int[] { indexOf(CODE_SPACE) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) {
|
||||||
|
mSpacebarTextFadeFactor = fadeFactor;
|
||||||
|
updateSpacebarForLocale(false);
|
||||||
|
if (view != null)
|
||||||
|
view.invalidateKey(mSpaceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getSpacebarTextColor(int color, float fadeFactor) {
|
||||||
|
final int newColor = Color.argb((int)(Color.alpha(color) * fadeFactor),
|
||||||
|
Color.red(color), Color.green(color), Color.blue(color));
|
||||||
|
return newColor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a key which should be invalidated.
|
* @return a key which should be invalidated.
|
||||||
*/
|
*/
|
||||||
public Key onAutoCorrectionStateChanged(boolean isAutoCorrection) {
|
public Key onAutoCorrectionStateChanged(boolean isAutoCorrection) {
|
||||||
updateSpaceBarForLocale(isAutoCorrection);
|
updateSpacebarForLocale(isAutoCorrection);
|
||||||
return mSpaceKey;
|
return mSpaceKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSpaceBarForLocale(boolean isAutoCorrection) {
|
private void updateSpacebarForLocale(boolean isAutoCorrection) {
|
||||||
final Resources res = mContext.getResources();
|
final Resources res = mContext.getResources();
|
||||||
// If application locales are explicitly selected.
|
// If application locales are explicitly selected.
|
||||||
if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) {
|
if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) {
|
||||||
mSpaceKey.setIcon(new BitmapDrawable(res,
|
mSpaceKey.setIcon(new BitmapDrawable(res,
|
||||||
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
|
drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
|
||||||
} else {
|
} else {
|
||||||
// sym_keyboard_space_led can be shared with Black and White symbol themes.
|
// sym_keyboard_space_led can be shared with Black and White symbol themes.
|
||||||
if (isAutoCorrection) {
|
if (isAutoCorrection) {
|
||||||
mSpaceKey.setIcon(new BitmapDrawable(res,
|
mSpaceKey.setIcon(new BitmapDrawable(res,
|
||||||
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
|
drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
|
||||||
} else {
|
} else {
|
||||||
mSpaceKey.setIcon(mSpaceIcon);
|
mSpaceKey.setIcon(mSpaceIcon);
|
||||||
}
|
}
|
||||||
|
@ -128,8 +145,8 @@ public class LatinKeyboard extends Keyboard {
|
||||||
return bounds.width();
|
return bounds.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout local language name and left and right arrow on space bar.
|
// Layout local language name and left and right arrow on spacebar.
|
||||||
private static String layoutSpaceBar(Paint paint, Locale locale, Drawable lArrow,
|
private static String layoutSpacebar(Paint paint, Locale locale, Drawable lArrow,
|
||||||
Drawable rArrow, int width, int height, float origTextSize,
|
Drawable rArrow, int width, int height, float origTextSize,
|
||||||
boolean allowVariableTextSize) {
|
boolean allowVariableTextSize) {
|
||||||
final float arrowWidth = lArrow.getIntrinsicWidth();
|
final float arrowWidth = lArrow.getIntrinsicWidth();
|
||||||
|
@ -138,7 +155,7 @@ public class LatinKeyboard extends Keyboard {
|
||||||
final Rect bounds = new Rect();
|
final Rect bounds = new Rect();
|
||||||
|
|
||||||
// Estimate appropriate language name text size to fit in maxTextWidth.
|
// Estimate appropriate language name text size to fit in maxTextWidth.
|
||||||
String language = SubtypeSwitcher.getDisplayLanguage(locale);
|
String language = SubtypeSwitcher.getFullDisplayName(locale, true);
|
||||||
int textWidth = getTextWidth(paint, language, origTextSize, bounds);
|
int textWidth = getTextWidth(paint, language, origTextSize, bounds);
|
||||||
// Assuming text width and text size are proportional to each other.
|
// Assuming text width and text size are proportional to each other.
|
||||||
float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
|
float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
|
||||||
|
@ -171,8 +188,7 @@ public class LatinKeyboard extends Keyboard {
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
private Bitmap drawSpacebar(int opacity, boolean isAutoCorrection) {
|
||||||
private Bitmap drawSpaceBar(int opacity, boolean isAutoCorrection) {
|
|
||||||
final int width = mSpaceKey.mWidth;
|
final int width = mSpaceKey.mWidth;
|
||||||
final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight;
|
final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight;
|
||||||
final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
|
@ -202,21 +218,25 @@ public class LatinKeyboard extends Keyboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean allowVariableTextSize = true;
|
final boolean allowVariableTextSize = true;
|
||||||
final String language = layoutSpaceBar(paint, subtypeSwitcher.getInputLocale(),
|
final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(),
|
||||||
mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
|
mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
|
||||||
getTextSizeFromTheme(textStyle, defaultTextSize),
|
getTextSizeFromTheme(textStyle, defaultTextSize),
|
||||||
allowVariableTextSize);
|
allowVariableTextSize);
|
||||||
|
|
||||||
// Draw language text with shadow
|
// Draw language text with shadow
|
||||||
final float baseline = height * SPACEBAR_LANGUAGE_BASELINE;
|
// In case there is no space icon, we will place the language text at the center of
|
||||||
|
// spacebar.
|
||||||
final float descent = paint.descent();
|
final float descent = paint.descent();
|
||||||
paint.setColor(mSpaceBarTextShadowColor);
|
final float textHeight = -paint.ascent() + descent;
|
||||||
|
final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE
|
||||||
|
: height / 2 + textHeight / 2;
|
||||||
|
paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor));
|
||||||
canvas.drawText(language, width / 2, baseline - descent - 1, paint);
|
canvas.drawText(language, width / 2, baseline - descent - 1, paint);
|
||||||
paint.setColor(res.getColor(R.color.latinkeyboard_bar_language_text));
|
paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor));
|
||||||
canvas.drawText(language, width / 2, baseline - descent, paint);
|
canvas.drawText(language, width / 2, baseline - descent, paint);
|
||||||
|
|
||||||
// Put arrows that are already layed out on either side of the text
|
// Put arrows that are already layed out on either side of the text
|
||||||
if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER
|
if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
|
||||||
&& subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
|
&& subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
|
||||||
mButtonArrowLeftIcon.draw(canvas);
|
mButtonArrowLeftIcon.draw(canvas);
|
||||||
mButtonArrowRightIcon.draw(canvas);
|
mButtonArrowRightIcon.draw(canvas);
|
||||||
|
@ -291,7 +311,6 @@ public class LatinKeyboard extends Keyboard {
|
||||||
* switching input languages.
|
* switching input languages.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unused") // SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER is constant
|
|
||||||
public boolean isInside(Key key, int pointX, int pointY) {
|
public boolean isInside(Key key, int pointX, int pointY) {
|
||||||
int x = pointX;
|
int x = pointX;
|
||||||
int y = pointY;
|
int y = pointY;
|
||||||
|
@ -302,7 +321,7 @@ public class LatinKeyboard extends Keyboard {
|
||||||
if (code == CODE_DELETE) x -= key.mWidth / 6;
|
if (code == CODE_DELETE) x -= key.mWidth / 6;
|
||||||
} else if (code == CODE_SPACE) {
|
} else if (code == CODE_SPACE) {
|
||||||
y += LatinKeyboard.sSpacebarVerticalCorrection;
|
y += LatinKeyboard.sSpacebarVerticalCorrection;
|
||||||
if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER
|
if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
|
||||||
&& SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) {
|
&& SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) {
|
||||||
if (mCurrentlyInSpace) {
|
if (mCurrentlyInSpace) {
|
||||||
int diff = x - mSpaceDragStartX;
|
int diff = x - mSpaceDragStartX;
|
||||||
|
|
|
@ -85,6 +85,14 @@ public class LatinKeyboardView extends KeyboardView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboard oldKeyboard) {
|
||||||
|
final LatinKeyboard currentKeyboard = getLatinKeyboard();
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onLongPress(Key key) {
|
protected boolean onLongPress(Key key) {
|
||||||
int primaryCode = key.mCode;
|
int primaryCode = key.mCode;
|
||||||
|
@ -197,10 +205,10 @@ public class LatinKeyboardView extends KeyboardView {
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent me) {
|
public boolean onTouchEvent(MotionEvent me) {
|
||||||
LatinKeyboard keyboard = getLatinKeyboard();
|
LatinKeyboard keyboard = getLatinKeyboard();
|
||||||
|
if (keyboard == null) return true;
|
||||||
|
|
||||||
// If there was a sudden jump, return without processing the actual motion event.
|
// If there was a sudden jump, return without processing the actual motion event.
|
||||||
if (handleSuddenJump(me))
|
if (handleSuddenJump(me)) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
// Reset any bounding box controls in the keyboard
|
// Reset any bounding box controls in the keyboard
|
||||||
if (me.getAction() == MotionEvent.ACTION_DOWN) {
|
if (me.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class MiniKeyboardBuilder {
|
||||||
for (CharSequence popupSpec : popupCharacters) {
|
for (CharSequence popupSpec : popupCharacters) {
|
||||||
final CharSequence label = PopupCharactersParser.getLabel(popupSpec.toString());
|
final CharSequence label = PopupCharactersParser.getLabel(popupSpec.toString());
|
||||||
// If the label is single letter, minKeyWidth is enough to hold the label.
|
// If the label is single letter, minKeyWidth is enough to hold the label.
|
||||||
if (label.length() > 1) {
|
if (label != null && label.length() > 1) {
|
||||||
if (paint == null) {
|
if (paint == null) {
|
||||||
paint = new Paint();
|
paint = new Paint();
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
|
|
|
@ -42,6 +42,7 @@ public class BinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
private static final int TYPED_LETTER_MULTIPLIER = 2;
|
private static final int TYPED_LETTER_MULTIPLIER = 2;
|
||||||
|
|
||||||
|
private static final BinaryDictionary sInstance = new BinaryDictionary();
|
||||||
private int mDicTypeId;
|
private int mDicTypeId;
|
||||||
private int mNativeDict;
|
private int mNativeDict;
|
||||||
private long mDictLength;
|
private long mDictLength;
|
||||||
|
@ -59,16 +60,24 @@ public class BinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BinaryDictionary() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a dictionary from a raw resource file
|
* Initialize a dictionary from a raw resource file
|
||||||
* @param context application context for reading resources
|
* @param context application context for reading resources
|
||||||
* @param resId the resource containing the raw binary dictionary
|
* @param resId the resource containing the raw binary dictionary
|
||||||
|
* @return initialized instance of BinaryDictionary
|
||||||
*/
|
*/
|
||||||
public BinaryDictionary(Context context, int resId, int dicTypeId) {
|
public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) {
|
||||||
if (resId != 0) {
|
synchronized (sInstance) {
|
||||||
loadDictionary(context, resId);
|
sInstance.closeInternal();
|
||||||
|
if (resId != 0) {
|
||||||
|
sInstance.loadDictionary(context, resId);
|
||||||
|
sInstance.mDicTypeId = dicTypeId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mDicTypeId = dicTypeId;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int openNative(String sourceDir, long dictOffset, long dictSize,
|
private native int openNative(String sourceDir, long dictOffset, long dictSize,
|
||||||
|
@ -104,6 +113,8 @@ public class BinaryDictionary extends Dictionary {
|
||||||
@Override
|
@Override
|
||||||
public void getBigrams(final WordComposer codes, final CharSequence previousWord,
|
public void getBigrams(final WordComposer codes, final CharSequence previousWord,
|
||||||
final WordCallback callback, int[] nextLettersFrequencies) {
|
final WordCallback callback, int[] nextLettersFrequencies) {
|
||||||
|
if (mNativeDict == 0) return;
|
||||||
|
|
||||||
char[] chars = previousWord.toString().toCharArray();
|
char[] chars = previousWord.toString().toCharArray();
|
||||||
Arrays.fill(mOutputChars_bigrams, (char) 0);
|
Arrays.fill(mOutputChars_bigrams, (char) 0);
|
||||||
Arrays.fill(mFrequencies_bigrams, 0);
|
Arrays.fill(mFrequencies_bigrams, 0);
|
||||||
|
@ -135,6 +146,8 @@ public class BinaryDictionary extends Dictionary {
|
||||||
@Override
|
@Override
|
||||||
public void getWords(final WordComposer codes, final WordCallback callback,
|
public void getWords(final WordComposer codes, final WordCallback callback,
|
||||||
int[] nextLettersFrequencies) {
|
int[] nextLettersFrequencies) {
|
||||||
|
if (mNativeDict == 0) return;
|
||||||
|
|
||||||
final int codesSize = codes.size();
|
final int codesSize = codes.size();
|
||||||
// Won't deal with really long words.
|
// Won't deal with really long words.
|
||||||
if (codesSize > MAX_WORD_LENGTH - 1) return;
|
if (codesSize > MAX_WORD_LENGTH - 1) return;
|
||||||
|
@ -179,6 +192,10 @@ public class BinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() {
|
public synchronized void close() {
|
||||||
|
closeInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeInternal() {
|
||||||
if (mNativeDict != 0) {
|
if (mNativeDict != 0) {
|
||||||
closeNative(mNativeDict);
|
closeNative(mNativeDict);
|
||||||
mNativeDict = 0;
|
mNativeDict = 0;
|
||||||
|
@ -188,7 +205,10 @@ public class BinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
close();
|
try {
|
||||||
super.finalize();
|
closeInternal();
|
||||||
|
} finally {
|
||||||
|
super.finalize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,23 +45,22 @@ import android.widget.TextView;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class CandidateView extends LinearLayout implements OnClickListener, OnLongClickListener {
|
public class CandidateView extends LinearLayout implements OnClickListener, OnLongClickListener {
|
||||||
private LatinIME mService;
|
|
||||||
private final ArrayList<View> mWords = new ArrayList<View>();
|
|
||||||
|
|
||||||
private final TextView mPreviewText;
|
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
|
||||||
private final PopupWindow mPreviewPopup;
|
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
|
||||||
|
|
||||||
private static final int MAX_SUGGESTIONS = 16;
|
private static final int MAX_SUGGESTIONS = 16;
|
||||||
|
|
||||||
|
private final ArrayList<View> mWords = new ArrayList<View>();
|
||||||
private final boolean mConfigCandidateHighlightFontColorEnabled;
|
private final boolean mConfigCandidateHighlightFontColorEnabled;
|
||||||
|
private final CharacterStyle mInvertedForegroundColorSpan;
|
||||||
|
private final CharacterStyle mInvertedBackgroundColorSpan;
|
||||||
private final int mColorNormal;
|
private final int mColorNormal;
|
||||||
private final int mColorRecommended;
|
private final int mColorRecommended;
|
||||||
private final int mColorOther;
|
private final int mColorOther;
|
||||||
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
|
private final PopupWindow mPreviewPopup;
|
||||||
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
|
private final TextView mPreviewText;
|
||||||
private final CharacterStyle mInvertedForegroundColorSpan;
|
|
||||||
private final CharacterStyle mInvertedBackgroundColorSpan;
|
|
||||||
|
|
||||||
|
private LatinIME mService;
|
||||||
private SuggestedWords mSuggestions = SuggestedWords.EMPTY;
|
private SuggestedWords mSuggestions = SuggestedWords.EMPTY;
|
||||||
private boolean mShowingAutoCorrectionInverted;
|
private boolean mShowingAutoCorrectionInverted;
|
||||||
private boolean mShowingAddToDictionary;
|
private boolean mShowingAddToDictionary;
|
||||||
|
@ -186,9 +185,10 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
final TextView tv = (TextView)v.findViewById(R.id.candidate_word);
|
final TextView tv = (TextView)v.findViewById(R.id.candidate_word);
|
||||||
final TextView dv = (TextView)v.findViewById(R.id.candidate_debug_info);
|
final TextView dv = (TextView)v.findViewById(R.id.candidate_debug_info);
|
||||||
tv.setTextColor(mColorNormal);
|
tv.setTextColor(mColorNormal);
|
||||||
|
// TODO: Needs safety net?
|
||||||
if (suggestions.mHasMinimalSuggestion
|
if (suggestions.mHasMinimalSuggestion
|
||||||
&& ((i == 1 && !suggestions.mTypedWordValid) ||
|
&& ((i == 1 && !suggestions.mTypedWordValid)
|
||||||
(i == 0 && suggestions.mTypedWordValid))) {
|
|| (i == 0 && suggestions.mTypedWordValid))) {
|
||||||
final CharacterStyle style;
|
final CharacterStyle style;
|
||||||
if (mConfigCandidateHighlightFontColorEnabled) {
|
if (mConfigCandidateHighlightFontColorEnabled) {
|
||||||
style = BOLD_SPAN;
|
style = BOLD_SPAN;
|
||||||
|
@ -329,7 +329,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
mService.pickSuggestionManually(index, word);
|
mService.pickSuggestionManually(index, word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromWindow() {
|
public void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class InputLanguageSelection extends PreferenceActivity {
|
||||||
res.updateConfiguration(conf, res.getDisplayMetrics());
|
res.updateConfiguration(conf, res.getDisplayMetrics());
|
||||||
|
|
||||||
int mainDicResId = LatinIME.getMainDictionaryResourceId(res);
|
int mainDicResId = LatinIME.getMainDictionaryResourceId(res);
|
||||||
BinaryDictionary bd = new BinaryDictionary(this, mainDicResId, Suggest.DIC_MAIN);
|
BinaryDictionary bd = BinaryDictionary.initDictionary(this, mainDicResId, Suggest.DIC_MAIN);
|
||||||
|
|
||||||
// Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
|
// Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
|
||||||
// 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.
|
// 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
import com.android.inputmethod.keyboard.KeyboardView;
|
import com.android.inputmethod.keyboard.KeyboardView;
|
||||||
|
import com.android.inputmethod.keyboard.LatinKeyboard;
|
||||||
import com.android.inputmethod.keyboard.LatinKeyboardView;
|
import com.android.inputmethod.keyboard.LatinKeyboardView;
|
||||||
import com.android.inputmethod.latin.Utils.RingCharBuffer;
|
import com.android.inputmethod.latin.Utils.RingCharBuffer;
|
||||||
import com.android.inputmethod.voice.VoiceIMEConnector;
|
import com.android.inputmethod.voice.VoiceIMEConnector;
|
||||||
|
@ -132,14 +133,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
private SharedPreferences mPrefs;
|
private SharedPreferences mPrefs;
|
||||||
|
|
||||||
|
// These variables are initialized according to the {@link EditorInfo#inputType}.
|
||||||
|
private boolean mAutoSpace;
|
||||||
|
private boolean mInputTypeNoAutoCorrect;
|
||||||
|
private boolean mIsSettingsSuggestionStripOn;
|
||||||
|
private boolean mApplicationSpecifiedCompletionOn;
|
||||||
|
|
||||||
private final StringBuilder mComposing = new StringBuilder();
|
private final StringBuilder mComposing = new StringBuilder();
|
||||||
private WordComposer mWord = new WordComposer();
|
private WordComposer mWord = new WordComposer();
|
||||||
private CharSequence mBestWord;
|
private CharSequence mBestWord;
|
||||||
private boolean mHasValidSuggestions;
|
private boolean mHasValidSuggestions;
|
||||||
private boolean mIsSettingsSuggestionStripOn;
|
|
||||||
private boolean mApplicationSpecifiedCompletionOn;
|
|
||||||
private boolean mHasDictionary;
|
private boolean mHasDictionary;
|
||||||
private boolean mAutoSpace;
|
|
||||||
private boolean mJustAddedAutoSpace;
|
private boolean mJustAddedAutoSpace;
|
||||||
private boolean mAutoCorrectEnabled;
|
private boolean mAutoCorrectEnabled;
|
||||||
private boolean mReCorrectionEnabled;
|
private boolean mReCorrectionEnabled;
|
||||||
|
@ -151,6 +155,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private boolean mAutoCap;
|
private boolean mAutoCap;
|
||||||
private boolean mQuickFixes;
|
private boolean mQuickFixes;
|
||||||
private boolean mConfigSwipeDownDismissKeyboardEnabled;
|
private boolean mConfigSwipeDownDismissKeyboardEnabled;
|
||||||
|
private int mConfigDelayBeforeFadeoutLanguageOnSpacebar;
|
||||||
|
private int mConfigDurationOfFadeoutLanguageOnSpacebar;
|
||||||
|
private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar;
|
||||||
|
|
||||||
private int mCorrectionMode;
|
private int mCorrectionMode;
|
||||||
private int mCommittedLength;
|
private int mCommittedLength;
|
||||||
|
@ -160,9 +167,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private int mLastSelectionEnd;
|
private int mLastSelectionEnd;
|
||||||
private SuggestedWords mSuggestPuncList;
|
private SuggestedWords mSuggestPuncList;
|
||||||
|
|
||||||
// Input type is such that we should not auto-correct
|
|
||||||
private boolean mInputTypeNoAutoCorrect;
|
|
||||||
|
|
||||||
// Indicates whether the suggestion strip is to be on in landscape
|
// Indicates whether the suggestion strip is to be on in landscape
|
||||||
private boolean mJustAccepted;
|
private boolean mJustAccepted;
|
||||||
private boolean mJustReverted;
|
private boolean mJustReverted;
|
||||||
|
@ -241,9 +245,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1;
|
private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1;
|
||||||
private static final int MSG_UPDATE_SHIFT_STATE = 2;
|
private static final int MSG_UPDATE_SHIFT_STATE = 2;
|
||||||
private static final int MSG_VOICE_RESULTS = 3;
|
private static final int MSG_VOICE_RESULTS = 3;
|
||||||
|
private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4;
|
||||||
|
private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
|
final KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||||
|
final LatinKeyboardView inputView = switcher.getInputView();
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_UPDATE_SUGGESTIONS:
|
case MSG_UPDATE_SUGGESTIONS:
|
||||||
updateSuggestions();
|
updateSuggestions();
|
||||||
|
@ -252,12 +260,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
setOldSuggestions();
|
setOldSuggestions();
|
||||||
break;
|
break;
|
||||||
case MSG_UPDATE_SHIFT_STATE:
|
case MSG_UPDATE_SHIFT_STATE:
|
||||||
mKeyboardSwitcher.updateShiftState();
|
switcher.updateShiftState();
|
||||||
break;
|
break;
|
||||||
case MSG_VOICE_RESULTS:
|
case MSG_VOICE_RESULTS:
|
||||||
mVoiceConnector.handleVoiceResults(preferCapitalization()
|
mVoiceConnector.handleVoiceResults(preferCapitalization()
|
||||||
|| (mKeyboardSwitcher.isAlphabetMode()
|
|| (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked()));
|
||||||
&& mKeyboardSwitcher.isShiftedOrShiftLocked()));
|
break;
|
||||||
|
case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR:
|
||||||
|
if (inputView != null)
|
||||||
|
inputView.setSpacebarTextFadeFactor(
|
||||||
|
(1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2,
|
||||||
|
(LatinKeyboard)msg.obj);
|
||||||
|
sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj),
|
||||||
|
mConfigDurationOfFadeoutLanguageOnSpacebar);
|
||||||
|
break;
|
||||||
|
case MSG_DISMISS_LANGUAGE_ON_SPACEBAR:
|
||||||
|
if (inputView != null)
|
||||||
|
inputView.setSpacebarTextFadeFactor(
|
||||||
|
mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,6 +317,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
public void updateVoiceResults() {
|
public void updateVoiceResults() {
|
||||||
sendMessage(obtainMessage(MSG_VOICE_RESULTS));
|
sendMessage(obtainMessage(MSG_VOICE_RESULTS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startDisplayLanguageOnSpacebar(boolean localeChanged) {
|
||||||
|
removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR);
|
||||||
|
removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR);
|
||||||
|
final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
|
||||||
|
if (inputView != null) {
|
||||||
|
final LatinKeyboard keyboard = inputView.getLatinKeyboard();
|
||||||
|
// The language is never displayed when the delay is zero.
|
||||||
|
if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0)
|
||||||
|
inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f
|
||||||
|
: mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard);
|
||||||
|
// The language is always displayed when the delay is negative.
|
||||||
|
if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) {
|
||||||
|
sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard),
|
||||||
|
mConfigDelayBeforeFadeoutLanguageOnSpacebar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -315,10 +353,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
final Resources res = getResources();
|
final Resources res = getResources();
|
||||||
mResources = res;
|
mResources = res;
|
||||||
mReCorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
|
|
||||||
res.getBoolean(R.bool.default_recorrection_enabled));
|
// If the option should not be shown, do not read the recorrection preference
|
||||||
|
// but always use the default setting defined in the resources.
|
||||||
|
if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
|
||||||
|
mReCorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
|
||||||
|
res.getBoolean(R.bool.default_recorrection_enabled));
|
||||||
|
} else {
|
||||||
|
mReCorrectionEnabled = res.getBoolean(R.bool.default_recorrection_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean(
|
mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean(
|
||||||
R.bool.config_swipe_down_dismiss_keyboard_enabled);
|
R.bool.config_swipe_down_dismiss_keyboard_enabled);
|
||||||
|
mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger(
|
||||||
|
R.integer.config_delay_before_fadeout_language_on_spacebar);
|
||||||
|
mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger(
|
||||||
|
R.integer.config_duration_of_fadeout_language_on_spacebar);
|
||||||
|
mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger(
|
||||||
|
R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f;
|
||||||
|
|
||||||
Utils.GCUtils.getInstance().reset();
|
Utils.GCUtils.getInstance().reset();
|
||||||
boolean tryGC = true;
|
boolean tryGC = true;
|
||||||
|
@ -360,7 +412,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mSuggest.close();
|
mSuggest.close();
|
||||||
}
|
}
|
||||||
final SharedPreferences prefs = mPrefs;
|
final SharedPreferences prefs = mPrefs;
|
||||||
mQuickFixes = prefs.getBoolean(Settings.PREF_QUICK_FIXES, true);
|
mQuickFixes = isQuickFixesEnabled(prefs);
|
||||||
|
|
||||||
final Resources res = mResources;
|
final Resources res = mResources;
|
||||||
int mainDicResId = getMainDictionaryResourceId(res);
|
int mainDicResId = getMainDictionaryResourceId(res);
|
||||||
|
@ -402,27 +454,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(Configuration conf) {
|
public void onConfigurationChanged(Configuration conf) {
|
||||||
mSubtypeSwitcher.onConfigurationChanged(conf);
|
mSubtypeSwitcher.onConfigurationChanged(conf);
|
||||||
if (mSubtypeSwitcher.isKeyboardMode())
|
|
||||||
onKeyboardLanguageChanged();
|
|
||||||
updateAutoTextEnabled();
|
|
||||||
|
|
||||||
// If orientation changed while predicting, commit the change
|
// If orientation changed while predicting, commit the change
|
||||||
if (conf.orientation != mOrientation) {
|
if (conf.orientation != mOrientation) {
|
||||||
InputConnection ic = getCurrentInputConnection();
|
InputConnection ic = getCurrentInputConnection();
|
||||||
commitTyped(ic);
|
commitTyped(ic);
|
||||||
if (ic != null) ic.finishComposingText(); // For voice input
|
if (ic != null) ic.finishComposingText(); // For voice input
|
||||||
mOrientation = conf.orientation;
|
mOrientation = conf.orientation;
|
||||||
final int mode = mKeyboardSwitcher.getKeyboardMode();
|
|
||||||
final EditorInfo attribute = getCurrentInputEditorInfo();
|
|
||||||
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
|
|
||||||
mKeyboardSwitcher.loadKeyboard(mode, imeOptions,
|
|
||||||
mVoiceConnector.isVoiceButtonEnabled(),
|
|
||||||
mVoiceConnector.isVoiceButtonOnPrimary());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mConfigurationChanging = true;
|
mConfigurationChanging = true;
|
||||||
super.onConfigurationChanged(conf);
|
super.onConfigurationChanged(conf);
|
||||||
mVoiceConnector.onConfigurationChanged(mConfigurationChanging);
|
mVoiceConnector.onConfigurationChanged(conf);
|
||||||
mConfigurationChanging = false;
|
mConfigurationChanging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,24 +515,62 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
if (mRefreshKeyboardRequired) {
|
if (mRefreshKeyboardRequired) {
|
||||||
mRefreshKeyboardRequired = false;
|
mRefreshKeyboardRequired = false;
|
||||||
onKeyboardLanguageChanged();
|
onRefreshKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEntryState.newSession(this);
|
TextEntryState.newSession(this);
|
||||||
|
|
||||||
// Most such things we decide below in the switch statement, but we need to know
|
// Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
|
||||||
// now whether this is a password text field, because we need to know now (before
|
// know now whether this is a password text field, because we need to know now whether we
|
||||||
// the switch statement) whether we want to enable the voice button.
|
// want to enable the voice button.
|
||||||
int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION;
|
mVoiceConnector.resetVoiceStates(isPasswordVariation(
|
||||||
mVoiceConnector.resetVoiceStates(isPasswordVariation(variation));
|
attribute.inputType & InputType.TYPE_MASK_VARIATION));
|
||||||
|
|
||||||
|
final int mode = initializeInputAttributesAndGetMode(attribute.inputType);
|
||||||
|
|
||||||
|
inputView.closing();
|
||||||
|
mEnteredText = null;
|
||||||
|
mComposing.setLength(0);
|
||||||
|
mHasValidSuggestions = false;
|
||||||
|
mDeleteCount = 0;
|
||||||
|
mJustAddedAutoSpace = false;
|
||||||
|
|
||||||
|
loadSettings(attribute);
|
||||||
|
if (mSubtypeSwitcher.isKeyboardMode()) {
|
||||||
|
switcher.loadKeyboard(mode, attribute.imeOptions,
|
||||||
|
mVoiceConnector.isVoiceButtonEnabled(),
|
||||||
|
mVoiceConnector.isVoiceButtonOnPrimary());
|
||||||
|
switcher.updateShiftState();
|
||||||
|
}
|
||||||
|
|
||||||
|
setCandidatesViewShownInternal(isCandidateStripVisible(),
|
||||||
|
false /* needsInputViewShown */ );
|
||||||
|
// Delay updating suggestions because keyboard input view may not be shown at this point.
|
||||||
|
mHandler.postUpdateSuggestions();
|
||||||
|
|
||||||
|
updateCorrectionMode();
|
||||||
|
|
||||||
|
inputView.setPreviewEnabled(mPopupOn);
|
||||||
|
inputView.setProximityCorrectionEnabled(true);
|
||||||
|
// If we just entered a text field, maybe it has some old text that requires correction
|
||||||
|
checkReCorrectionOnStart();
|
||||||
|
inputView.setForeground(true);
|
||||||
|
|
||||||
|
mVoiceConnector.onStartInputView(inputView.getWindowToken());
|
||||||
|
|
||||||
|
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
|
||||||
|
}
|
||||||
|
|
||||||
|
private int initializeInputAttributesAndGetMode(int inputType) {
|
||||||
|
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
|
||||||
|
mAutoSpace = false;
|
||||||
mInputTypeNoAutoCorrect = false;
|
mInputTypeNoAutoCorrect = false;
|
||||||
mIsSettingsSuggestionStripOn = false;
|
mIsSettingsSuggestionStripOn = false;
|
||||||
mApplicationSpecifiedCompletionOn = false;
|
mApplicationSpecifiedCompletionOn = false;
|
||||||
mApplicationSpecifiedCompletions = null;
|
mApplicationSpecifiedCompletions = null;
|
||||||
mEnteredText = null;
|
|
||||||
|
|
||||||
final int mode;
|
final int mode;
|
||||||
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
|
switch (inputType & InputType.TYPE_MASK_CLASS) {
|
||||||
case InputType.TYPE_CLASS_NUMBER:
|
case InputType.TYPE_CLASS_NUMBER:
|
||||||
case InputType.TYPE_CLASS_DATETIME:
|
case InputType.TYPE_CLASS_DATETIME:
|
||||||
mode = KeyboardId.MODE_NUMBER;
|
mode = KeyboardId.MODE_NUMBER;
|
||||||
|
@ -525,7 +605,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mode = KeyboardId.MODE_WEB;
|
mode = KeyboardId.MODE_WEB;
|
||||||
// If it's a browser edit field and auto correct is not ON explicitly, then
|
// If it's a browser edit field and auto correct is not ON explicitly, then
|
||||||
// disable auto correction, but keep suggestions on.
|
// disable auto correction, but keep suggestions on.
|
||||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
|
if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
|
||||||
mInputTypeNoAutoCorrect = true;
|
mInputTypeNoAutoCorrect = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -533,16 +613,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
|
|
||||||
// If NO_SUGGESTIONS is set, don't do prediction.
|
// If NO_SUGGESTIONS is set, don't do prediction.
|
||||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
|
if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
|
||||||
mIsSettingsSuggestionStripOn = false;
|
mIsSettingsSuggestionStripOn = false;
|
||||||
mInputTypeNoAutoCorrect = true;
|
mInputTypeNoAutoCorrect = true;
|
||||||
}
|
}
|
||||||
// If it's not multiline and the autoCorrect flag is not set, then don't correct
|
// If it's not multiline and the autoCorrect flag is not set, then don't correct
|
||||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
|
if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
|
||||||
(attribute.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
|
(inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
|
||||||
mInputTypeNoAutoCorrect = true;
|
mInputTypeNoAutoCorrect = true;
|
||||||
}
|
}
|
||||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
|
if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
|
||||||
mIsSettingsSuggestionStripOn = false;
|
mIsSettingsSuggestionStripOn = false;
|
||||||
mApplicationSpecifiedCompletionOn = isFullscreenMode();
|
mApplicationSpecifiedCompletionOn = isFullscreenMode();
|
||||||
}
|
}
|
||||||
|
@ -551,40 +631,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mode = KeyboardId.MODE_TEXT;
|
mode = KeyboardId.MODE_TEXT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
inputView.closing();
|
return mode;
|
||||||
mComposing.setLength(0);
|
|
||||||
mHasValidSuggestions = false;
|
|
||||||
mDeleteCount = 0;
|
|
||||||
mJustAddedAutoSpace = false;
|
|
||||||
|
|
||||||
loadSettings(attribute);
|
|
||||||
if (mSubtypeSwitcher.isKeyboardMode()) {
|
|
||||||
switcher.loadKeyboard(mode, attribute.imeOptions,
|
|
||||||
mVoiceConnector.isVoiceButtonEnabled(),
|
|
||||||
mVoiceConnector.isVoiceButtonOnPrimary());
|
|
||||||
switcher.updateShiftState();
|
|
||||||
}
|
|
||||||
|
|
||||||
setCandidatesViewShownInternal(isCandidateStripVisible(),
|
|
||||||
false /* needsInputViewShown */ );
|
|
||||||
// Delay updating suggestions because keyboard input view may not be shown at this point.
|
|
||||||
mHandler.postUpdateSuggestions();
|
|
||||||
|
|
||||||
// If the dictionary is not big enough, don't auto correct
|
|
||||||
mHasDictionary = mSuggest.hasMainDictionary();
|
|
||||||
|
|
||||||
updateCorrectionMode();
|
|
||||||
|
|
||||||
inputView.setPreviewEnabled(mPopupOn);
|
|
||||||
inputView.setProximityCorrectionEnabled(true);
|
|
||||||
mIsSettingsSuggestionStripOn &= (mCorrectionMode > 0 || isShowingSuggestionsStrip());
|
|
||||||
// If we just entered a text field, maybe it has some old text that requires correction
|
|
||||||
checkReCorrectionOnStart();
|
|
||||||
inputView.setForeground(true);
|
|
||||||
|
|
||||||
mVoiceConnector.onStartInputView(mKeyboardSwitcher.getInputView().getWindowToken());
|
|
||||||
|
|
||||||
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkReCorrectionOnStart() {
|
private void checkReCorrectionOnStart() {
|
||||||
|
@ -1106,14 +1153,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
private void handleBackspace() {
|
private void handleBackspace() {
|
||||||
if (mVoiceConnector.logAndRevertVoiceInput()) return;
|
if (mVoiceConnector.logAndRevertVoiceInput()) return;
|
||||||
boolean deleteChar = false;
|
|
||||||
InputConnection ic = getCurrentInputConnection();
|
|
||||||
if (ic == null) return;
|
|
||||||
|
|
||||||
|
final InputConnection ic = getCurrentInputConnection();
|
||||||
|
if (ic == null) return;
|
||||||
ic.beginBatchEdit();
|
ic.beginBatchEdit();
|
||||||
|
|
||||||
mVoiceConnector.handleBackspace();
|
mVoiceConnector.handleBackspace();
|
||||||
|
|
||||||
|
boolean deleteChar = false;
|
||||||
if (mHasValidSuggestions) {
|
if (mHasValidSuggestions) {
|
||||||
final int length = mComposing.length();
|
final int length = mComposing.length();
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
|
@ -1131,12 +1178,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
deleteChar = true;
|
deleteChar = true;
|
||||||
}
|
}
|
||||||
mHandler.postUpdateShiftKeyState();
|
mHandler.postUpdateShiftKeyState();
|
||||||
|
|
||||||
TextEntryState.backspace();
|
TextEntryState.backspace();
|
||||||
if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) {
|
if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) {
|
||||||
revertLastWord(deleteChar);
|
revertLastWord(deleteChar);
|
||||||
ic.endBatchEdit();
|
ic.endBatchEdit();
|
||||||
return;
|
return;
|
||||||
} else if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
|
}
|
||||||
|
|
||||||
|
if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
|
||||||
ic.deleteSurroundingText(mEnteredText.length(), 0);
|
ic.deleteSurroundingText(mEnteredText.length(), 0);
|
||||||
} else if (deleteChar) {
|
} else if (deleteChar) {
|
||||||
if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) {
|
if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) {
|
||||||
|
@ -1355,7 +1405,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSuggestionsRequested() {
|
private boolean isSuggestionsRequested() {
|
||||||
return mIsSettingsSuggestionStripOn;
|
return mIsSettingsSuggestionStripOn
|
||||||
|
&& (mCorrectionMode > 0 || isShowingSuggestionsStrip());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isShowingPunctuationList() {
|
private boolean isShowingPunctuationList() {
|
||||||
|
@ -1491,7 +1542,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) {
|
private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) {
|
||||||
setSuggestions(suggestedWords);
|
setSuggestions(suggestedWords);
|
||||||
if (suggestedWords.size() > 0) {
|
if (suggestedWords.size() > 0) {
|
||||||
if (suggestedWords.hasAutoCorrectionWord()) {
|
if (Utils.shouldBlockedBySafetyNetForAutoCorrection(suggestedWords)) {
|
||||||
|
mBestWord = typedWord;
|
||||||
|
} else if (suggestedWords.hasAutoCorrectionWord()) {
|
||||||
mBestWord = suggestedWords.getWord(1);
|
mBestWord = suggestedWords.getWord(1);
|
||||||
} else {
|
} else {
|
||||||
mBestWord = typedWord;
|
mBestWord = typedWord;
|
||||||
|
@ -1773,18 +1826,31 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
final int length = mComposing.length();
|
final int length = mComposing.length();
|
||||||
if (!mHasValidSuggestions && length > 0) {
|
if (!mHasValidSuggestions && length > 0) {
|
||||||
final InputConnection ic = getCurrentInputConnection();
|
final InputConnection ic = getCurrentInputConnection();
|
||||||
mHasValidSuggestions = true;
|
|
||||||
mJustReverted = true;
|
mJustReverted = true;
|
||||||
|
final CharSequence punctuation = ic.getTextBeforeCursor(1, 0);
|
||||||
if (deleteChar) ic.deleteSurroundingText(1, 0);
|
if (deleteChar) ic.deleteSurroundingText(1, 0);
|
||||||
int toDelete = mCommittedLength;
|
int toDelete = mCommittedLength;
|
||||||
CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
|
final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
|
||||||
if (toTheLeft != null && toTheLeft.length() > 0
|
if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) {
|
||||||
&& isWordSeparator(toTheLeft.charAt(0))) {
|
|
||||||
toDelete--;
|
toDelete--;
|
||||||
}
|
}
|
||||||
ic.deleteSurroundingText(toDelete, 0);
|
ic.deleteSurroundingText(toDelete, 0);
|
||||||
ic.setComposingText(mComposing, 1);
|
// Re-insert punctuation only when the deleted character was word separator and the
|
||||||
TextEntryState.backspace();
|
// composing text wasn't equal to the auto-corrected text.
|
||||||
|
if (deleteChar
|
||||||
|
&& !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0))
|
||||||
|
&& !TextUtils.equals(mComposing, toTheLeft)) {
|
||||||
|
ic.commitText(mComposing, 1);
|
||||||
|
TextEntryState.acceptedTyped(mComposing);
|
||||||
|
ic.commitText(punctuation, 1);
|
||||||
|
TextEntryState.typedCharacter(punctuation.charAt(0), true);
|
||||||
|
// Clear composing text
|
||||||
|
mComposing.setLength(0);
|
||||||
|
} else {
|
||||||
|
mHasValidSuggestions = true;
|
||||||
|
ic.setComposingText(mComposing, 1);
|
||||||
|
TextEntryState.backspace();
|
||||||
|
}
|
||||||
mHandler.postUpdateSuggestions();
|
mHandler.postUpdateSuggestions();
|
||||||
} else {
|
} else {
|
||||||
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
|
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
|
||||||
|
@ -1814,21 +1880,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
return mWord.isFirstCharCapitalized();
|
return mWord.isFirstCharCapitalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify that Language has been changed and toggleLanguage will update KeyboaredID according
|
// Notify that language or mode have been changed and toggleLanguage will update KeyboaredID
|
||||||
// to new Language.
|
// according to new language or mode.
|
||||||
public void onKeyboardLanguageChanged() {
|
public void onRefreshKeyboard() {
|
||||||
toggleLanguage(true, true);
|
toggleLanguage(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER.
|
// "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER.
|
||||||
private void toggleLanguage(boolean reset, boolean next) {
|
private void toggleLanguage(boolean reset, boolean next) {
|
||||||
if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) {
|
||||||
mSubtypeSwitcher.toggleLanguage(reset, next);
|
mSubtypeSwitcher.toggleLanguage(reset, next);
|
||||||
}
|
}
|
||||||
// Reload keyboard because the current language has been changed.
|
// Reload keyboard because the current language has been changed.
|
||||||
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||||
final int mode = switcher.getKeyboardMode();
|
|
||||||
final EditorInfo attribute = getCurrentInputEditorInfo();
|
final EditorInfo attribute = getCurrentInputEditorInfo();
|
||||||
|
final int mode = initializeInputAttributesAndGetMode((attribute != null)
|
||||||
|
? attribute.inputType : 0);
|
||||||
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
|
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
|
||||||
switcher.loadKeyboard(mode, imeOptions, mVoiceConnector.isVoiceButtonEnabled(),
|
switcher.loadKeyboard(mode, imeOptions, mVoiceConnector.isVoiceButtonEnabled(),
|
||||||
mVoiceConnector.isVoiceButtonOnPrimary());
|
mVoiceConnector.isVoiceButtonOnPrimary());
|
||||||
|
@ -2016,7 +2083,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mPopupOn = prefs.getBoolean(Settings.PREF_POPUP_ON,
|
mPopupOn = prefs.getBoolean(Settings.PREF_POPUP_ON,
|
||||||
mResources.getBoolean(R.bool.config_default_popup_preview));
|
mResources.getBoolean(R.bool.config_default_popup_preview));
|
||||||
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
|
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
|
||||||
mQuickFixes = prefs.getBoolean(Settings.PREF_QUICK_FIXES, true);
|
mQuickFixes = isQuickFixesEnabled(prefs);
|
||||||
|
|
||||||
mAutoCorrectEnabled = isAutoCorrectEnabled(prefs);
|
mAutoCorrectEnabled = isAutoCorrectEnabled(prefs);
|
||||||
mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs);
|
mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs);
|
||||||
|
@ -2065,6 +2132,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold);
|
mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isQuickFixesEnabled(SharedPreferences sp) {
|
||||||
|
final boolean showQuickFixesOption = mResources.getBoolean(
|
||||||
|
R.bool.config_enable_quick_fixes_option);
|
||||||
|
if (!showQuickFixesOption) {
|
||||||
|
return isAutoCorrectEnabled(sp);
|
||||||
|
}
|
||||||
|
return sp.getBoolean(Settings.PREF_QUICK_FIXES, mResources.getBoolean(
|
||||||
|
R.bool.config_default_quick_fixes));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isAutoCorrectEnabled(SharedPreferences sp) {
|
private boolean isAutoCorrectEnabled(SharedPreferences sp) {
|
||||||
final String currentAutoCorrectionSetting = sp.getString(
|
final String currentAutoCorrectionSetting = sp.getString(
|
||||||
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
|
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
|
||||||
|
@ -2075,8 +2152,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBigramSuggestionEnabled(SharedPreferences sp) {
|
private boolean isBigramSuggestionEnabled(SharedPreferences sp) {
|
||||||
// TODO: Define default value instead of 'true'.
|
final boolean showBigramSuggestionsOption = mResources.getBoolean(
|
||||||
return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, true);
|
R.bool.config_enable_bigram_suggestions_option);
|
||||||
|
if (!showBigramSuggestionsOption) {
|
||||||
|
return isAutoCorrectEnabled(sp);
|
||||||
|
}
|
||||||
|
return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, mResources.getBoolean(
|
||||||
|
R.bool.config_default_bigram_suggestions));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSuggestPuncList() {
|
private void initSuggestPuncList() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 The Android Open Source Project
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* 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
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
* the License at
|
* the License at
|
||||||
|
@ -48,6 +48,7 @@ public class Settings extends PreferenceActivity
|
||||||
DialogInterface.OnDismissListener, OnPreferenceClickListener {
|
DialogInterface.OnDismissListener, OnPreferenceClickListener {
|
||||||
private static final String TAG = "Settings";
|
private static final String TAG = "Settings";
|
||||||
|
|
||||||
|
public static final String PREF_GENERAL_SETTINGS_KEY = "general_settings";
|
||||||
public static final String PREF_VIBRATE_ON = "vibrate_on";
|
public static final String PREF_VIBRATE_ON = "vibrate_on";
|
||||||
public static final String PREF_SOUND_ON = "sound_on";
|
public static final String PREF_SOUND_ON = "sound_on";
|
||||||
public static final String PREF_POPUP_ON = "popup_on";
|
public static final String PREF_POPUP_ON = "popup_on";
|
||||||
|
@ -65,6 +66,8 @@ public class Settings extends PreferenceActivity
|
||||||
public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
|
public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
|
||||||
public static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion";
|
public static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion";
|
||||||
|
|
||||||
|
public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
|
||||||
|
|
||||||
// Dialog ids
|
// Dialog ids
|
||||||
private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
|
private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
|
||||||
|
|
||||||
|
@ -111,30 +114,64 @@ public class Settings extends PreferenceActivity
|
||||||
mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTIONS);
|
mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTIONS);
|
||||||
ensureConsistencyOfAutoCorrectionSettings();
|
ensureConsistencyOfAutoCorrectionSettings();
|
||||||
|
|
||||||
|
final PreferenceGroup generalSettings =
|
||||||
|
(PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS_KEY);
|
||||||
|
final PreferenceGroup textCorrectionGroup =
|
||||||
|
(PreferenceGroup) findPreference(PREF_PREDICTION_SETTINGS_KEY);
|
||||||
|
|
||||||
final boolean showSettingsKeyOption = getResources().getBoolean(
|
final boolean showSettingsKeyOption = getResources().getBoolean(
|
||||||
R.bool.config_enable_show_settings_key_option);
|
R.bool.config_enable_show_settings_key_option);
|
||||||
if (!showSettingsKeyOption) {
|
if (!showSettingsKeyOption) {
|
||||||
getPreferenceScreen().removePreference(mSettingsKeyPreference);
|
generalSettings.removePreference(mSettingsKeyPreference);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean showVoiceKeyOption = getResources().getBoolean(
|
final boolean showVoiceKeyOption = getResources().getBoolean(
|
||||||
R.bool.config_enable_show_voice_key_option);
|
R.bool.config_enable_show_voice_key_option);
|
||||||
if (!showVoiceKeyOption) {
|
if (!showVoiceKeyOption) {
|
||||||
getPreferenceScreen().removePreference(mVoicePreference);
|
generalSettings.removePreference(mVoicePreference);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
|
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
|
||||||
if (vibrator == null
|
if (vibrator == null
|
||||||
// @@@ || !vibrator.hasVibrator()
|
// @@@ || !vibrator.hasVibrator()
|
||||||
) {
|
) {
|
||||||
getPreferenceScreen().removePreference(
|
generalSettings.removePreference(findPreference(PREF_VIBRATE_ON));
|
||||||
getPreferenceScreen().findPreference(PREF_VIBRATE_ON));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean showSubtypeSettings = getResources().getBoolean(
|
final boolean showSubtypeSettings = getResources().getBoolean(
|
||||||
R.bool.config_enable_show_subtype_settings);
|
R.bool.config_enable_show_subtype_settings);
|
||||||
if (!showSubtypeSettings) {
|
if (!showSubtypeSettings) {
|
||||||
getPreferenceScreen().removePreference(findPreference(PREF_SUBTYPES));
|
generalSettings.removePreference(findPreference(PREF_SUBTYPES));
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean showPopupOption = getResources().getBoolean(
|
||||||
|
R.bool.config_enable_show_popup_on_keypress_option);
|
||||||
|
if (!showPopupOption) {
|
||||||
|
generalSettings.removePreference(findPreference(PREF_POPUP_ON));
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean showRecorrectionOption = getResources().getBoolean(
|
||||||
|
R.bool.config_enable_show_recorrection_option);
|
||||||
|
if (!showRecorrectionOption) {
|
||||||
|
generalSettings.removePreference(findPreference(PREF_RECORRECTION_ENABLED));
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean showQuickFixesOption = getResources().getBoolean(
|
||||||
|
R.bool.config_enable_quick_fixes_option);
|
||||||
|
if (!showQuickFixesOption) {
|
||||||
|
textCorrectionGroup.removePreference(findPreference(PREF_QUICK_FIXES));
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean showBigramSuggestionsOption = getResources().getBoolean(
|
||||||
|
R.bool.config_enable_bigram_suggestions_option);
|
||||||
|
if (!showBigramSuggestionsOption) {
|
||||||
|
textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_SUGGESTIONS));
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean showUsabilityModeStudyOption = getResources().getBoolean(
|
||||||
|
R.bool.config_enable_usability_study_mode_option);
|
||||||
|
if (!showUsabilityModeStudyOption) {
|
||||||
|
getPreferenceScreen().removePreference(findPreference(PREF_USABILITY_STUDY_MODE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +221,7 @@ public class Settings extends PreferenceActivity
|
||||||
if (pref == mInputLanguageSelection) {
|
if (pref == mInputLanguageSelection) {
|
||||||
final String action;
|
final String action;
|
||||||
if (android.os.Build.VERSION.SDK_INT
|
if (android.os.Build.VERSION.SDK_INT
|
||||||
>= /* android.os.Build.VERSION_CODES.HONEYCOMB */ 10) {
|
>= /* android.os.Build.VERSION_CODES.HONEYCOMB */ 11) {
|
||||||
action = "android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER";
|
action = "android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER";
|
||||||
} else {
|
} else {
|
||||||
action = "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION";
|
action = "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION";
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class SubtypeLocale {
|
||||||
|
private static String[] sExceptionKeys;
|
||||||
|
private static String[] sExceptionValues;
|
||||||
|
|
||||||
|
private SubtypeLocale() {
|
||||||
|
// Intentional empty constructor for utility class.
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init(Context context) {
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
sExceptionKeys = res.getStringArray(R.array.subtype_locale_exception_keys);
|
||||||
|
sExceptionValues = res.getStringArray(R.array.subtype_locale_exception_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFullDisplayName(Locale locale) {
|
||||||
|
String localeCode = locale.toString();
|
||||||
|
for (int index = 0; index < sExceptionKeys.length; index++) {
|
||||||
|
if (sExceptionKeys[index].equals(localeCode))
|
||||||
|
return sExceptionValues[index];
|
||||||
|
}
|
||||||
|
return locale.getDisplayName(locale);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import com.android.inputmethod.compat.InputMethodSubtype;
|
||||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
import com.android.inputmethod.voice.SettingsUtil;
|
import com.android.inputmethod.voice.SettingsUtil;
|
||||||
import com.android.inputmethod.voice.VoiceIMEConnector;
|
import com.android.inputmethod.voice.VoiceIMEConnector;
|
||||||
|
@ -40,11 +41,6 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class SubtypeSwitcher {
|
public class SubtypeSwitcher {
|
||||||
// TODO: This should be configurable by resource
|
|
||||||
// This flag indicates if we support language switching by swipe on space bar.
|
|
||||||
// We may or may not draw the current language on space bar regardless of this flag.
|
|
||||||
// @@@
|
|
||||||
public static final boolean USE_SPACEBAR_LANGUAGE_SWITCHER = true;
|
|
||||||
private static final boolean DBG = false;
|
private static final boolean DBG = false;
|
||||||
private static final String TAG = "SubtypeSwitcher";
|
private static final String TAG = "SubtypeSwitcher";
|
||||||
|
|
||||||
|
@ -63,6 +59,8 @@ public class SubtypeSwitcher {
|
||||||
new ArrayList<InputMethodSubtype>();
|
new ArrayList<InputMethodSubtype>();
|
||||||
private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>();
|
private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>();
|
||||||
|
|
||||||
|
private boolean mConfigUseSpacebarLanguageSwitcher;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
// Variants which should be changed only by reload functions.
|
// Variants which should be changed only by reload functions.
|
||||||
private boolean mNeedsToDisplayLanguage;
|
private boolean mNeedsToDisplayLanguage;
|
||||||
|
@ -84,11 +82,9 @@ public class SubtypeSwitcher {
|
||||||
public static void init(LatinIME service, SharedPreferences prefs) {
|
public static void init(LatinIME service, SharedPreferences prefs) {
|
||||||
sInstance.mPrefs = prefs;
|
sInstance.mPrefs = prefs;
|
||||||
sInstance.resetParams(service);
|
sInstance.resetParams(service);
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
|
||||||
sInstance.initLanguageSwitcher(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
sInstance.updateAllParameters();
|
sInstance.updateAllParameters();
|
||||||
|
|
||||||
|
SubtypeLocale.init(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SubtypeSwitcher() {
|
private SubtypeSwitcher() {
|
||||||
|
@ -109,6 +105,10 @@ public class SubtypeSwitcher {
|
||||||
mAllEnabledSubtypesOfCurrentInputMethod = null;
|
mAllEnabledSubtypesOfCurrentInputMethod = null;
|
||||||
// TODO: Voice input should be created here
|
// TODO: Voice input should be created here
|
||||||
mVoiceInput = null;
|
mVoiceInput = null;
|
||||||
|
mConfigUseSpacebarLanguageSwitcher = mResources.getBoolean(
|
||||||
|
R.bool.config_use_spacebar_language_switcher);
|
||||||
|
if (mConfigUseSpacebarLanguageSwitcher)
|
||||||
|
initLanguageSwitcher(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all parameters stored in SubtypeSwitcher.
|
// Update all parameters stored in SubtypeSwitcher.
|
||||||
|
@ -122,8 +122,8 @@ public class SubtypeSwitcher {
|
||||||
// Update parameters which are changed outside LatinIME. This parameters affect UI so they
|
// Update parameters which are changed outside LatinIME. This parameters affect UI so they
|
||||||
// should be updated every time onStartInputview.
|
// should be updated every time onStartInputview.
|
||||||
public void updateParametersOnStartInputView() {
|
public void updateParametersOnStartInputView() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
updateForSpaceBarLanguageSwitch();
|
updateForSpacebarLanguageSwitch();
|
||||||
} else {
|
} else {
|
||||||
updateEnabledSubtypes();
|
updateEnabledSubtypes();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ public class SubtypeSwitcher {
|
||||||
private void updateEnabledSubtypes() {
|
private void updateEnabledSubtypes() {
|
||||||
boolean foundCurrentSubtypeBecameDisabled = true;
|
boolean foundCurrentSubtypeBecameDisabled = true;
|
||||||
// @@@ mAllEnabledSubtypesOfCurrentInputMethod = mImm.getEnabledInputMethodSubtypeList(
|
// @@@ mAllEnabledSubtypesOfCurrentInputMethod = mImm.getEnabledInputMethodSubtypeList(
|
||||||
//null, false);
|
// null, true);
|
||||||
mEnabledLanguagesOfCurrentInputMethod.clear();
|
mEnabledLanguagesOfCurrentInputMethod.clear();
|
||||||
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear();
|
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear();
|
||||||
for (InputMethodSubtype ims: mAllEnabledSubtypesOfCurrentInputMethod) {
|
for (InputMethodSubtype ims: mAllEnabledSubtypesOfCurrentInputMethod) {
|
||||||
|
@ -155,6 +155,7 @@ public class SubtypeSwitcher {
|
||||||
&& mIsSystemLanguageSameAsInputLanguage);
|
&& mIsSystemLanguageSameAsInputLanguage);
|
||||||
if (foundCurrentSubtypeBecameDisabled) {
|
if (foundCurrentSubtypeBecameDisabled) {
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
|
Log.w(TAG, "Current subtype: " + mInputLocaleStr + ", " + mMode);
|
||||||
Log.w(TAG, "Last subtype was disabled. Update to the current one.");
|
Log.w(TAG, "Last subtype was disabled. Update to the current one.");
|
||||||
}
|
}
|
||||||
// @@@ updateSubtype(mImm.getCurrentInputMethodSubtype());
|
// @@@ updateSubtype(mImm.getCurrentInputMethodSubtype());
|
||||||
|
@ -188,7 +189,7 @@ public class SubtypeSwitcher {
|
||||||
// fallback to the default locale and mode.
|
// fallback to the default locale and mode.
|
||||||
Log.w(TAG, "Couldn't get the current subtype.");
|
Log.w(TAG, "Couldn't get the current subtype.");
|
||||||
newLocale = "en_US";
|
newLocale = "en_US";
|
||||||
newMode =KEYBOARD_MODE;
|
newMode = KEYBOARD_MODE;
|
||||||
} else {
|
} else {
|
||||||
newLocale = newSubtype.getLocale();
|
newLocale = newSubtype.getLocale();
|
||||||
newMode = newSubtype.getMode();
|
newMode = newSubtype.getMode();
|
||||||
|
@ -218,8 +219,8 @@ public class SubtypeSwitcher {
|
||||||
mVoiceInput.cancel();
|
mVoiceInput.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (languageChanged) {
|
if (modeChanged || languageChanged) {
|
||||||
mService.onKeyboardLanguageChanged();
|
mService.onRefreshKeyboard();
|
||||||
}
|
}
|
||||||
} else if (isVoiceMode()) {
|
} else if (isVoiceMode()) {
|
||||||
// If needsToShowWarningDialog is true, voice input need to show warning before
|
// If needsToShowWarningDialog is true, voice input need to show warning before
|
||||||
|
@ -311,19 +312,23 @@ public class SubtypeSwitcher {
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|
||||||
public int getEnabledKeyboardLocaleCount() {
|
public int getEnabledKeyboardLocaleCount() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return mLanguageSwitcher.getLocaleCount();
|
return mLanguageSwitcher.getLocaleCount();
|
||||||
} else {
|
} else {
|
||||||
return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
|
return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean useSpacebarLanguageSwitcher() {
|
||||||
|
return mConfigUseSpacebarLanguageSwitcher;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean needsToDisplayLanguage() {
|
public boolean needsToDisplayLanguage() {
|
||||||
return mNeedsToDisplayLanguage;
|
return mNeedsToDisplayLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Locale getInputLocale() {
|
public Locale getInputLocale() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return mLanguageSwitcher.getInputLocale();
|
return mLanguageSwitcher.getInputLocale();
|
||||||
} else {
|
} else {
|
||||||
return mInputLocale;
|
return mInputLocale;
|
||||||
|
@ -331,7 +336,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInputLocaleStr() {
|
public String getInputLocaleStr() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
String inputLanguage = null;
|
String inputLanguage = null;
|
||||||
inputLanguage = mLanguageSwitcher.getInputLanguage();
|
inputLanguage = mLanguageSwitcher.getInputLanguage();
|
||||||
// Should return system locale if there is no Language available.
|
// Should return system locale if there is no Language available.
|
||||||
|
@ -345,7 +350,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getEnabledLanguages() {
|
public String[] getEnabledLanguages() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return mLanguageSwitcher.getEnabledLanguages();
|
return mLanguageSwitcher.getEnabledLanguages();
|
||||||
} else {
|
} else {
|
||||||
return mEnabledLanguagesOfCurrentInputMethod.toArray(
|
return mEnabledLanguagesOfCurrentInputMethod.toArray(
|
||||||
|
@ -354,7 +359,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Locale getSystemLocale() {
|
public Locale getSystemLocale() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return mLanguageSwitcher.getSystemLocale();
|
return mLanguageSwitcher.getSystemLocale();
|
||||||
} else {
|
} else {
|
||||||
return mSystemLocale;
|
return mSystemLocale;
|
||||||
|
@ -362,7 +367,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSystemLanguageSameAsInputLanguage() {
|
public boolean isSystemLanguageSameAsInputLanguage() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return getSystemLocale().getLanguage().equalsIgnoreCase(
|
return getSystemLocale().getLanguage().equalsIgnoreCase(
|
||||||
getInputLocaleStr().substring(0, 2));
|
getInputLocaleStr().substring(0, 2));
|
||||||
} else {
|
} else {
|
||||||
|
@ -374,7 +379,7 @@ public class SubtypeSwitcher {
|
||||||
final Locale systemLocale = conf.locale;
|
final Locale systemLocale = conf.locale;
|
||||||
// If system configuration was changed, update all parameters.
|
// If system configuration was changed, update all parameters.
|
||||||
if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) {
|
if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
// If the system locale changes and is different from the saved
|
// If the system locale changes and is different from the saved
|
||||||
// locale (mSystemLocale), then reload the input locale list from the
|
// locale (mSystemLocale), then reload the input locale list from the
|
||||||
// latin ime settings (shared prefs) and reset the input locale
|
// latin ime settings (shared prefs) and reset the input locale
|
||||||
|
@ -388,7 +393,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) {
|
if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) {
|
||||||
mLanguageSwitcher.loadLocales(sharedPreferences);
|
mLanguageSwitcher.loadLocales(sharedPreferences);
|
||||||
}
|
}
|
||||||
|
@ -438,18 +443,18 @@ public class SubtypeSwitcher {
|
||||||
private void triggerVoiceIME() {
|
private void triggerVoiceIME() {
|
||||||
if (!mService.isInputViewShown()) return;
|
if (!mService.isInputViewShown()) return;
|
||||||
VoiceIMEConnector.getInstance().startListening(false,
|
VoiceIMEConnector.getInstance().startListening(false,
|
||||||
KeyboardSwitcher.getInstance().getInputView().getWindowToken(), false);
|
KeyboardSwitcher.getInstance().getInputView().getWindowToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
// SpaceBar Language Switch support //
|
// Spacebar Language Switch support //
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
private LanguageSwitcher mLanguageSwitcher;
|
private LanguageSwitcher mLanguageSwitcher;
|
||||||
|
|
||||||
public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) {
|
public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) {
|
||||||
if (returnsNameInThisLocale) {
|
if (returnsNameInThisLocale) {
|
||||||
return toTitleCase(locale.getDisplayName(locale));
|
return toTitleCase(SubtypeLocale.getFullDisplayName(locale));
|
||||||
} else {
|
} else {
|
||||||
return toTitleCase(locale.getDisplayName());
|
return toTitleCase(locale.getDisplayName());
|
||||||
}
|
}
|
||||||
|
@ -470,7 +475,7 @@ public class SubtypeSwitcher {
|
||||||
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateForSpaceBarLanguageSwitch() {
|
private void updateForSpacebarLanguageSwitch() {
|
||||||
// We need to update mNeedsToDisplayLanguage in onStartInputView because
|
// We need to update mNeedsToDisplayLanguage in onStartInputView because
|
||||||
// getEnabledKeyboardLocaleCount could have been changed.
|
// getEnabledKeyboardLocaleCount could have been changed.
|
||||||
mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1
|
mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1
|
||||||
|
@ -483,7 +488,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNextInputLanguageName() {
|
public String getNextInputLanguageName() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale());
|
return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale());
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
@ -491,7 +496,7 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPreviousInputLanguageName() {
|
public String getPreviousInputLanguageName() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale());
|
return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale());
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
@ -528,13 +533,13 @@ public class SubtypeSwitcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadSettings() {
|
public void loadSettings() {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
mLanguageSwitcher.loadLocales(mPrefs);
|
mLanguageSwitcher.loadLocales(mPrefs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toggleLanguage(boolean reset, boolean next) {
|
public void toggleLanguage(boolean reset, boolean next) {
|
||||||
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
|
if (mConfigUseSpacebarLanguageSwitcher) {
|
||||||
if (reset) {
|
if (reset) {
|
||||||
mLanguageSwitcher.reset();
|
mLanguageSwitcher.reset();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.util.Arrays;
|
||||||
*/
|
*/
|
||||||
public class Suggest implements Dictionary.WordCallback {
|
public class Suggest implements Dictionary.WordCallback {
|
||||||
|
|
||||||
public static final String TAG = "Suggest";
|
public static final String TAG = Suggest.class.getSimpleName();
|
||||||
|
|
||||||
public static final int APPROX_MAX_WORD_LENGTH = 32;
|
public static final int APPROX_MAX_WORD_LENGTH = 32;
|
||||||
|
|
||||||
|
@ -64,6 +64,8 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
|
|
||||||
static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
|
static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
|
||||||
|
|
||||||
|
private static boolean DBG = LatinImeLogger.sDBG;
|
||||||
|
|
||||||
private BinaryDictionary mMainDict;
|
private BinaryDictionary mMainDict;
|
||||||
|
|
||||||
private Dictionary mUserDictionary;
|
private Dictionary mUserDictionary;
|
||||||
|
@ -93,7 +95,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
|
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
|
||||||
ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
|
ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
|
||||||
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
|
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
|
||||||
private boolean mHaveCorrection;
|
private boolean mHaveAutoCorrection;
|
||||||
private String mLowerOriginalWord;
|
private String mLowerOriginalWord;
|
||||||
|
|
||||||
// TODO: Remove these member variables by passing more context to addWord() callback method
|
// TODO: Remove these member variables by passing more context to addWord() callback method
|
||||||
|
@ -103,7 +105,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
private int mCorrectionMode = CORRECTION_BASIC;
|
private int mCorrectionMode = CORRECTION_BASIC;
|
||||||
|
|
||||||
public Suggest(Context context, int dictionaryResId) {
|
public Suggest(Context context, int dictionaryResId) {
|
||||||
mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN);
|
mMainDict = BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN);
|
||||||
initPool();
|
initPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +129,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasMainDictionary() {
|
public boolean hasMainDictionary() {
|
||||||
return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
|
return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getApproxMaxWordLength() {
|
public int getApproxMaxWordLength() {
|
||||||
|
@ -198,7 +200,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
public SuggestedWords.Builder getSuggestedWordBuilder(View view, WordComposer wordComposer,
|
public SuggestedWords.Builder getSuggestedWordBuilder(View view, WordComposer wordComposer,
|
||||||
CharSequence prevWordForBigram) {
|
CharSequence prevWordForBigram) {
|
||||||
LatinImeLogger.onStartSuggestion(prevWordForBigram);
|
LatinImeLogger.onStartSuggestion(prevWordForBigram);
|
||||||
mHaveCorrection = false;
|
mHaveAutoCorrection = false;
|
||||||
mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
|
mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
|
||||||
mIsAllUpperCase = wordComposer.isAllUpperCase();
|
mIsAllUpperCase = wordComposer.isAllUpperCase();
|
||||||
collectGarbage(mSuggestions, mPrefMaxSuggestions);
|
collectGarbage(mSuggestions, mPrefMaxSuggestions);
|
||||||
|
@ -273,10 +275,13 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
if (mSuggestions.size() > 0 && isValidWord(typedWord)
|
if (mSuggestions.size() > 0 && isValidWord(typedWord)
|
||||||
&& (mCorrectionMode == CORRECTION_FULL
|
&& (mCorrectionMode == CORRECTION_FULL
|
||||||
|| mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
|
|| mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
|
||||||
mHaveCorrection = true;
|
if (DBG) {
|
||||||
|
Log.d(TAG, "Auto corrected by CORRECTION_FULL.");
|
||||||
|
}
|
||||||
|
mHaveAutoCorrection = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
|
if (mMainDict != null) mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
|
||||||
if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
|
if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
|
||||||
&& mSuggestions.size() > 0 && mPriorities.length > 0) {
|
&& mSuggestions.size() > 0 && mPriorities.length > 0) {
|
||||||
// TODO: when the normalized score of the first suggestion is nearly equals to
|
// TODO: when the normalized score of the first suggestion is nearly equals to
|
||||||
|
@ -289,7 +294,10 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
+ "(" + mAutoCorrectionThreshold + ")");
|
+ "(" + mAutoCorrectionThreshold + ")");
|
||||||
}
|
}
|
||||||
if (normalizedScore >= mAutoCorrectionThreshold) {
|
if (normalizedScore >= mAutoCorrectionThreshold) {
|
||||||
mHaveCorrection = true;
|
if (DBG) {
|
||||||
|
Log.d(TAG, "Auto corrected by S-threthhold.");
|
||||||
|
}
|
||||||
|
mHaveAutoCorrection = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +339,10 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1));
|
canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1));
|
||||||
}
|
}
|
||||||
if (canAdd) {
|
if (canAdd) {
|
||||||
mHaveCorrection = true;
|
if (DBG) {
|
||||||
|
Log.d(TAG, "Auto corrected by AUTOTEXT.");
|
||||||
|
}
|
||||||
|
mHaveAutoCorrection = true;
|
||||||
mSuggestions.add(i + 1, autoText);
|
mSuggestions.add(i + 1, autoText);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -374,7 +385,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasMinimalCorrection() {
|
public boolean hasMinimalCorrection() {
|
||||||
return mHaveCorrection;
|
return mHaveAutoCorrection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean compareCaseInsensitive(final String mLowerOriginalWord,
|
private boolean compareCaseInsensitive(final String mLowerOriginalWord,
|
||||||
|
@ -496,7 +507,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValidWord(final CharSequence word) {
|
public boolean isValidWord(final CharSequence word) {
|
||||||
if (word == null || word.length() == 0) {
|
if (word == null || word.length() == 0 || mMainDict == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return mMainDict.isValidWord(word)
|
return mMainDict.isValidWord(word)
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class SuggestedWords {
|
||||||
addWord(previousSuggestions.getWord(pos));
|
addWord(previousSuggestions.getWord(pos));
|
||||||
mIsCompletions = false;
|
mIsCompletions = false;
|
||||||
mTypedWordValid = false;
|
mTypedWordValid = false;
|
||||||
mHasMinimalSuggestion = (previousSize > 1);
|
mHasMinimalSuggestion = false;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
private static final String TAG = Utils.class.getSimpleName();
|
||||||
|
private static boolean DBG = LatinImeLogger.sDBG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel an {@link AsyncTask}.
|
* Cancel an {@link AsyncTask}.
|
||||||
|
@ -96,6 +98,29 @@ public class Utils {
|
||||||
// || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
|
// || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean shouldBlockedBySafetyNetForAutoCorrection(SuggestedWords suggestions) {
|
||||||
|
// Safety net for auto correction.
|
||||||
|
// Actually if we hit this safety net, it's actually a bug.
|
||||||
|
if (suggestions.size() <= 1 || suggestions.mTypedWordValid) return false;
|
||||||
|
CharSequence typedWord = suggestions.getWord(0);
|
||||||
|
CharSequence candidateWord = suggestions.getWord(1);
|
||||||
|
final int typedWordLength = typedWord.length();
|
||||||
|
final int maxEditDistanceOfNativeDictionary = typedWordLength < 5 ? 2 : typedWordLength / 2;
|
||||||
|
final int distance = Utils.editDistance(typedWord, candidateWord);
|
||||||
|
if (DBG) {
|
||||||
|
Log.d(TAG, "Autocorrected edit distance = " + distance
|
||||||
|
+ ", " + maxEditDistanceOfNativeDictionary);
|
||||||
|
}
|
||||||
|
if (distance > maxEditDistanceOfNativeDictionary) {
|
||||||
|
Log.w(TAG, "(Error) The edit distance of this correction exceeds limit. "
|
||||||
|
+ "Turning off auto-correction.");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* package */ static class RingCharBuffer {
|
/* package */ static class RingCharBuffer {
|
||||||
private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
|
private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
|
||||||
private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
|
private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
|
|
||||||
package com.android.inputmethod.voice;
|
package com.android.inputmethod.voice;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.R;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
@ -29,20 +26,21 @@ import android.graphics.Path;
|
||||||
import android.graphics.PathEffect;
|
import android.graphics.PathEffect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.TypedValue;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup.MarginLayoutParams;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.R;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,81 +56,55 @@ public class RecognitionView {
|
||||||
private View mView;
|
private View mView;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
private ImageView mImage;
|
|
||||||
private TextView mText;
|
private TextView mText;
|
||||||
private View mButton;
|
private ImageView mImage;
|
||||||
private TextView mButtonText;
|
|
||||||
private View mProgress;
|
private View mProgress;
|
||||||
|
private SoundIndicator mSoundIndicator;
|
||||||
|
private Button mButton;
|
||||||
|
|
||||||
private Drawable mInitializing;
|
private Drawable mInitializing;
|
||||||
private Drawable mError;
|
private Drawable mError;
|
||||||
private List<Drawable> mSpeakNow;
|
|
||||||
|
|
||||||
private float mVolume = 0.0f;
|
private static final int INIT = 0;
|
||||||
private int mLevel = 0;
|
private static final int LISTENING = 1;
|
||||||
|
private static final int WORKING = 2;
|
||||||
|
private static final int READY = 3;
|
||||||
|
|
||||||
|
private int mState = INIT;
|
||||||
|
|
||||||
private enum State {LISTENING, WORKING, READY}
|
private final View mPopupLayout;
|
||||||
private State mState = State.READY;
|
|
||||||
|
|
||||||
private float mMinMicrophoneLevel;
|
private final Drawable mListeningBorder;
|
||||||
private float mMaxMicrophoneLevel;
|
private final Drawable mWorkingBorder;
|
||||||
|
private final Drawable mErrorBorder;
|
||||||
/** Updates the microphone icon to show user their volume.*/
|
|
||||||
private Runnable mUpdateVolumeRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mState != State.LISTENING) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final float min = mMinMicrophoneLevel;
|
|
||||||
final float max = mMaxMicrophoneLevel;
|
|
||||||
final int maxLevel = mSpeakNow.size() - 1;
|
|
||||||
|
|
||||||
int index = (int) ((mVolume - min) / (max - min) * maxLevel);
|
|
||||||
final int level = Math.min(Math.max(0, index), maxLevel);
|
|
||||||
|
|
||||||
if (level != mLevel) {
|
|
||||||
mImage.setImageDrawable(mSpeakNow.get(level));
|
|
||||||
mLevel = level;
|
|
||||||
}
|
|
||||||
mUiHandler.postDelayed(mUpdateVolumeRunnable, 50);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public RecognitionView(Context context, OnClickListener clickListener) {
|
public RecognitionView(Context context, OnClickListener clickListener) {
|
||||||
mUiHandler = new Handler();
|
mUiHandler = new Handler();
|
||||||
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
|
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
|
||||||
Context.LAYOUT_INFLATER_SERVICE);
|
Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
mView = inflater.inflate(R.layout.recognition_status, null);
|
mView = inflater.inflate(R.layout.recognition_status, null);
|
||||||
ContentResolver cr = context.getContentResolver();
|
|
||||||
mMinMicrophoneLevel = SettingsUtil.getSettingsFloat(
|
mPopupLayout= mView.findViewById(R.id.popup_layout);
|
||||||
cr, SettingsUtil.LATIN_IME_MIN_MICROPHONE_LEVEL, 15.f);
|
|
||||||
mMaxMicrophoneLevel = SettingsUtil.getSettingsFloat(
|
|
||||||
cr, SettingsUtil.LATIN_IME_MAX_MICROPHONE_LEVEL, 30.f);
|
|
||||||
|
|
||||||
// Pre-load volume level images
|
// Pre-load volume level images
|
||||||
Resources r = context.getResources();
|
Resources r = context.getResources();
|
||||||
|
|
||||||
mSpeakNow = new ArrayList<Drawable>();
|
mListeningBorder = r.getDrawable(R.drawable.vs_dialog_red);
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level0));
|
mWorkingBorder = r.getDrawable(R.drawable.vs_dialog_blue);
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level1));
|
mErrorBorder = r.getDrawable(R.drawable.vs_dialog_yellow);
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level2));
|
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level3));
|
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level4));
|
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level5));
|
|
||||||
mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level6));
|
|
||||||
|
|
||||||
mInitializing = r.getDrawable(R.drawable.mic_slash);
|
mInitializing = r.getDrawable(R.drawable.mic_slash);
|
||||||
mError = r.getDrawable(R.drawable.caution);
|
mError = r.getDrawable(R.drawable.caution);
|
||||||
|
|
||||||
mImage = (ImageView) mView.findViewById(R.id.image);
|
mImage = (ImageView) mView.findViewById(R.id.image);
|
||||||
mButton = mView.findViewById(R.id.button);
|
mProgress = mView.findViewById(R.id.progress);
|
||||||
|
mSoundIndicator = (SoundIndicator) mView.findViewById(R.id.sound_indicator);
|
||||||
|
|
||||||
|
mButton = (Button) mView.findViewById(R.id.button);
|
||||||
mButton.setOnClickListener(clickListener);
|
mButton.setOnClickListener(clickListener);
|
||||||
mText = (TextView) mView.findViewById(R.id.text);
|
mText = (TextView) mView.findViewById(R.id.text);
|
||||||
mButtonText = (TextView) mView.findViewById(R.id.button_text);
|
|
||||||
mProgress = mView.findViewById(R.id.progress);
|
|
||||||
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
@ -146,9 +118,9 @@ public class RecognitionView {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Restart the spinner
|
// Restart the spinner
|
||||||
if (mState == State.WORKING) {
|
if (mState == WORKING) {
|
||||||
((ProgressBar)mProgress).setIndeterminate(false);
|
((ProgressBar) mProgress).setIndeterminate(false);
|
||||||
((ProgressBar)mProgress).setIndeterminate(true);
|
((ProgressBar) mProgress).setIndeterminate(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -158,48 +130,48 @@ public class RecognitionView {
|
||||||
mUiHandler.post(new Runnable() {
|
mUiHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
prepareDialog(false, mContext.getText(R.string.voice_initializing), mInitializing,
|
mState = INIT;
|
||||||
mContext.getText(R.string.cancel));
|
prepareDialog(mContext.getText(R.string.voice_initializing), mInitializing,
|
||||||
|
mContext.getText(R.string.cancel));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showListening() {
|
public void showListening() {
|
||||||
|
Log.d(TAG, "#showListening");
|
||||||
mUiHandler.post(new Runnable() {
|
mUiHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mState = State.LISTENING;
|
mState = LISTENING;
|
||||||
prepareDialog(false, mContext.getText(R.string.voice_listening), mSpeakNow.get(0),
|
prepareDialog(mContext.getText(R.string.voice_listening), null,
|
||||||
mContext.getText(R.string.cancel));
|
mContext.getText(R.string.cancel));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mUiHandler.postDelayed(mUpdateVolumeRunnable, 50);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateVoiceMeter(final float rmsdB) {
|
public void updateVoiceMeter(float rmsdB) {
|
||||||
mVolume = rmsdB;
|
mSoundIndicator.setRmsdB(rmsdB);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showError(final String message) {
|
public void showError(final String message) {
|
||||||
mUiHandler.post(new Runnable() {
|
mUiHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mState = State.READY;
|
mState = READY;
|
||||||
prepareDialog(false, message, mError, mContext.getText(R.string.ok));
|
prepareDialog(message, mError, mContext.getText(R.string.ok));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showWorking(
|
public void showWorking(
|
||||||
final ByteArrayOutputStream waveBuffer,
|
final ByteArrayOutputStream waveBuffer,
|
||||||
final int speechStartPosition,
|
final int speechStartPosition,
|
||||||
final int speechEndPosition) {
|
final int speechEndPosition) {
|
||||||
|
|
||||||
mUiHandler.post(new Runnable() {
|
mUiHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mState = State.WORKING;
|
mState = WORKING;
|
||||||
prepareDialog(true, mContext.getText(R.string.voice_working), null, mContext
|
prepareDialog(mContext.getText(R.string.voice_working), null, mContext
|
||||||
.getText(R.string.cancel));
|
.getText(R.string.cancel));
|
||||||
final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()).order(
|
final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()).order(
|
||||||
ByteOrder.nativeOrder()).asShortBuffer();
|
ByteOrder.nativeOrder()).asShortBuffer();
|
||||||
|
@ -207,21 +179,71 @@ public class RecognitionView {
|
||||||
waveBuffer.reset();
|
waveBuffer.reset();
|
||||||
showWave(buf, speechStartPosition / 2, speechEndPosition / 2);
|
showWave(buf, speechStartPosition / 2, speechEndPosition / 2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareDialog(boolean spinVisible, CharSequence text, Drawable image,
|
private void prepareDialog(CharSequence text, Drawable image,
|
||||||
CharSequence btnTxt) {
|
CharSequence btnTxt) {
|
||||||
if (spinVisible) {
|
switch (mState) {
|
||||||
mProgress.setVisibility(View.VISIBLE);
|
case INIT:
|
||||||
mImage.setVisibility(View.GONE);
|
mText.setVisibility(View.GONE);
|
||||||
} else {
|
|
||||||
mProgress.setVisibility(View.GONE);
|
mProgress.setVisibility(View.GONE);
|
||||||
mImage.setImageDrawable(image);
|
|
||||||
mImage.setVisibility(View.VISIBLE);
|
mImage.setVisibility(View.VISIBLE);
|
||||||
|
mImage.setImageResource(R.drawable.mic_slash);
|
||||||
|
|
||||||
|
mSoundIndicator.setVisibility(View.GONE);
|
||||||
|
mSoundIndicator.stop();
|
||||||
|
|
||||||
|
mPopupLayout.setBackgroundDrawable(mListeningBorder);
|
||||||
|
break;
|
||||||
|
case LISTENING:
|
||||||
|
mText.setVisibility(View.VISIBLE);
|
||||||
|
mText.setText(text);
|
||||||
|
|
||||||
|
mProgress.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mImage.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mSoundIndicator.setVisibility(View.VISIBLE);
|
||||||
|
mSoundIndicator.start();
|
||||||
|
|
||||||
|
mPopupLayout.setBackgroundDrawable(mListeningBorder);
|
||||||
|
break;
|
||||||
|
case WORKING:
|
||||||
|
|
||||||
|
mText.setVisibility(View.VISIBLE);
|
||||||
|
mText.setText(text);
|
||||||
|
|
||||||
|
mProgress.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
mImage.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
mSoundIndicator.setVisibility(View.GONE);
|
||||||
|
mSoundIndicator.stop();
|
||||||
|
|
||||||
|
mPopupLayout.setBackgroundDrawable(mWorkingBorder);
|
||||||
|
break;
|
||||||
|
case READY:
|
||||||
|
mText.setVisibility(View.VISIBLE);
|
||||||
|
mText.setText(text);
|
||||||
|
|
||||||
|
mProgress.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mImage.setVisibility(View.VISIBLE);
|
||||||
|
mImage.setImageResource(R.drawable.caution);
|
||||||
|
|
||||||
|
mSoundIndicator.setVisibility(View.GONE);
|
||||||
|
mSoundIndicator.stop();
|
||||||
|
|
||||||
|
mPopupLayout.setBackgroundDrawable(mErrorBorder);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.w(TAG, "Unknown state " + mState);
|
||||||
}
|
}
|
||||||
mText.setText(text);
|
mPopupLayout.requestLayout();
|
||||||
mButtonText.setText(btnTxt);
|
mButton.setText(btnTxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -248,7 +270,7 @@ public class RecognitionView {
|
||||||
*/
|
*/
|
||||||
private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) {
|
private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) {
|
||||||
final int w = ((View) mImage.getParent()).getWidth();
|
final int w = ((View) mImage.getParent()).getWidth();
|
||||||
final int h = mImage.getHeight();
|
final int h = ((View) mImage.getParent()).getHeight();
|
||||||
if (w <= 0 || h <= 0) {
|
if (w <= 0 || h <= 0) {
|
||||||
// view is not visible this time. Skip drawing.
|
// view is not visible this time. Skip drawing.
|
||||||
return;
|
return;
|
||||||
|
@ -259,7 +281,7 @@ public class RecognitionView {
|
||||||
paint.setColor(0xFFFFFFFF); // 0xAARRGGBB
|
paint.setColor(0xFFFFFFFF); // 0xAARRGGBB
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
paint.setAlpha(0x90);
|
paint.setAlpha(80);
|
||||||
|
|
||||||
final PathEffect effect = new CornerPathEffect(3);
|
final PathEffect effect = new CornerPathEffect(3);
|
||||||
paint.setPathEffect(effect);
|
paint.setPathEffect(effect);
|
||||||
|
@ -281,7 +303,7 @@ public class RecognitionView {
|
||||||
|
|
||||||
final int count = (endIndex - startIndex) / numSamplePerWave;
|
final int count = (endIndex - startIndex) / numSamplePerWave;
|
||||||
final float deltaX = 1.0f * w / count;
|
final float deltaX = 1.0f * w / count;
|
||||||
int yMax = h / 2 - 8;
|
int yMax = h / 2;
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
c.translate(0, yMax);
|
c.translate(0, yMax);
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
@ -295,37 +317,20 @@ public class RecognitionView {
|
||||||
path.lineTo(x, y);
|
path.lineTo(x, y);
|
||||||
}
|
}
|
||||||
if (deltaX > 4) {
|
if (deltaX > 4) {
|
||||||
paint.setStrokeWidth(3);
|
paint.setStrokeWidth(2);
|
||||||
} else {
|
} else {
|
||||||
paint.setStrokeWidth(Math.max(1, (int) (deltaX -.05)));
|
paint.setStrokeWidth(Math.max(0, (int) (deltaX -.05)));
|
||||||
}
|
}
|
||||||
c.drawPath(path, paint);
|
c.drawPath(path, paint);
|
||||||
mImage.setImageBitmap(b);
|
mImage.setImageBitmap(b);
|
||||||
mImage.setVisibility(View.VISIBLE);
|
|
||||||
MarginLayoutParams mProgressParams = (MarginLayoutParams)mProgress.getLayoutParams();
|
|
||||||
mProgressParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
|
|
||||||
-h , mContext.getResources().getDisplayMetrics());
|
|
||||||
|
|
||||||
// Tweak the padding manually to fill out the whole view horizontally.
|
|
||||||
// TODO: Do this in the xml layout instead.
|
|
||||||
((View) mImage.getParent()).setPadding(4, ((View) mImage.getParent()).getPaddingTop(), 3,
|
|
||||||
((View) mImage.getParent()).getPaddingBottom());
|
|
||||||
mProgress.setLayoutParams(mProgressParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void finish() {
|
public void finish() {
|
||||||
mUiHandler.post(new Runnable() {
|
mUiHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mState = State.READY;
|
mSoundIndicator.stop();
|
||||||
exitWorking();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
private void exitWorking() {
|
|
||||||
mProgress.setVisibility(View.GONE);
|
|
||||||
mImage.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.inputmethod.voice;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Bitmap.Config;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A widget which shows the volume of audio using a microphone icon
|
||||||
|
*/
|
||||||
|
public class SoundIndicator extends ImageView {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static final String TAG = "SoundIndicator";
|
||||||
|
|
||||||
|
private static final float UP_SMOOTHING_FACTOR = 0.9f;
|
||||||
|
private static final float DOWN_SMOOTHING_FACTOR = 0.4f;
|
||||||
|
|
||||||
|
private static final float AUDIO_METER_MIN_DB = 7.0f;
|
||||||
|
private static final float AUDIO_METER_DB_RANGE = 20.0f;
|
||||||
|
|
||||||
|
private static final long FRAME_DELAY = 50;
|
||||||
|
|
||||||
|
private Bitmap mDrawingBuffer;
|
||||||
|
private Canvas mBufferCanvas;
|
||||||
|
private Bitmap mEdgeBitmap;
|
||||||
|
private float mLevel = 0.0f;
|
||||||
|
private Drawable mFrontDrawable;
|
||||||
|
private Paint mClearPaint;
|
||||||
|
private Paint mMultPaint;
|
||||||
|
private int mEdgeBitmapOffset;
|
||||||
|
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
|
private Runnable mDrawFrame = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
invalidate();
|
||||||
|
mHandler.postDelayed(mDrawFrame, FRAME_DELAY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public SoundIndicator(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundIndicator(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
mFrontDrawable = getDrawable();
|
||||||
|
BitmapDrawable edgeDrawable =
|
||||||
|
(BitmapDrawable) context.getResources().getDrawable(R.drawable.vs_popup_mic_edge);
|
||||||
|
mEdgeBitmap = edgeDrawable.getBitmap();
|
||||||
|
mEdgeBitmapOffset = mEdgeBitmap.getHeight() / 2;
|
||||||
|
|
||||||
|
mDrawingBuffer =
|
||||||
|
Bitmap.createBitmap(mFrontDrawable.getIntrinsicWidth(),
|
||||||
|
mFrontDrawable.getIntrinsicHeight(), Config.ARGB_8888);
|
||||||
|
|
||||||
|
mBufferCanvas = new Canvas(mDrawingBuffer);
|
||||||
|
|
||||||
|
// Initialize Paints.
|
||||||
|
mClearPaint = new Paint();
|
||||||
|
mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||||
|
|
||||||
|
mMultPaint = new Paint();
|
||||||
|
mMultPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
|
||||||
|
|
||||||
|
mHandler = new Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(Canvas canvas) {
|
||||||
|
//super.onDraw(canvas);
|
||||||
|
|
||||||
|
float w = getWidth();
|
||||||
|
float h = getHeight();
|
||||||
|
|
||||||
|
// Clear the buffer canvas
|
||||||
|
mBufferCanvas.drawRect(0, 0, w, h, mClearPaint);
|
||||||
|
|
||||||
|
// Set its clip so we don't draw the front image all the way to the top
|
||||||
|
Rect clip = new Rect(0,
|
||||||
|
(int) ((1.0 - mLevel) * (h + mEdgeBitmapOffset)) - mEdgeBitmapOffset,
|
||||||
|
(int) w,
|
||||||
|
(int) h);
|
||||||
|
|
||||||
|
mBufferCanvas.save();
|
||||||
|
mBufferCanvas.clipRect(clip);
|
||||||
|
|
||||||
|
// Draw the front image
|
||||||
|
mFrontDrawable.setBounds(new Rect(0, 0, (int) w, (int) h));
|
||||||
|
mFrontDrawable.draw(mBufferCanvas);
|
||||||
|
|
||||||
|
mBufferCanvas.restore();
|
||||||
|
|
||||||
|
// Draw the edge image on top of the buffer image with a multiply mode
|
||||||
|
mBufferCanvas.drawBitmap(mEdgeBitmap, 0, clip.top, mMultPaint);
|
||||||
|
|
||||||
|
// Draw the buffer image (on top of the background image)
|
||||||
|
canvas.drawBitmap(mDrawingBuffer, 0, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the sound level
|
||||||
|
*
|
||||||
|
* @param rmsdB The level of the sound, in dB.
|
||||||
|
*/
|
||||||
|
public void setRmsdB(float rmsdB) {
|
||||||
|
float level = ((rmsdB - AUDIO_METER_MIN_DB) / AUDIO_METER_DB_RANGE);
|
||||||
|
|
||||||
|
level = Math.min(Math.max(0.0f, level), 1.0f);
|
||||||
|
|
||||||
|
// We smooth towards the new level
|
||||||
|
if (level > mLevel) {
|
||||||
|
mLevel = (level - mLevel) * UP_SMOOTHING_FACTOR + mLevel;
|
||||||
|
} else {
|
||||||
|
mLevel = (level - mLevel) * DOWN_SMOOTHING_FACTOR + mLevel;
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
mHandler.post(mDrawFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
mHandler.removeCallbacks(mDrawFrame);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package com.android.inputmethod.voice;
|
package com.android.inputmethod.voice;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
import com.android.inputmethod.latin.EditingUtils;
|
import com.android.inputmethod.latin.EditingUtils;
|
||||||
import com.android.inputmethod.latin.LatinIME;
|
import com.android.inputmethod.latin.LatinIME;
|
||||||
import com.android.inputmethod.latin.LatinIME.UIHandler;
|
import com.android.inputmethod.latin.LatinIME.UIHandler;
|
||||||
|
@ -29,6 +30,7 @@ import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
@ -77,6 +79,9 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
// dialog is already showing a voice search button.
|
// dialog is already showing a voice search button.
|
||||||
private static final String IME_OPTION_NO_MICROPHONE = "nm";
|
private static final String IME_OPTION_NO_MICROPHONE = "nm";
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static final String TAG = "VoiceIMEConnector";
|
||||||
|
|
||||||
private boolean mAfterVoiceInput;
|
private boolean mAfterVoiceInput;
|
||||||
private boolean mHasUsedVoiceInput;
|
private boolean mHasUsedVoiceInput;
|
||||||
private boolean mHasUsedVoiceInputUnsupportedLocale;
|
private boolean mHasUsedVoiceInputUnsupportedLocale;
|
||||||
|
@ -91,7 +96,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
private boolean mVoiceInputHighlighted;
|
private boolean mVoiceInputHighlighted;
|
||||||
|
|
||||||
private InputMethodManager mImm;
|
private InputMethodManager mImm;
|
||||||
private LatinIME mContext;
|
private LatinIME mService;
|
||||||
private AlertDialog mVoiceWarningDialog;
|
private AlertDialog mVoiceWarningDialog;
|
||||||
private VoiceInput mVoiceInput;
|
private VoiceInput mVoiceInput;
|
||||||
private final VoiceResults mVoiceResults = new VoiceResults();
|
private final VoiceResults mVoiceResults = new VoiceResults();
|
||||||
|
@ -111,21 +116,19 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initInternal(LatinIME context, SharedPreferences prefs, UIHandler h) {
|
private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) {
|
||||||
mContext = context;
|
mService = service;
|
||||||
mHandler = h;
|
mHandler = h;
|
||||||
mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
|
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
|
||||||
if (VOICE_INSTALLED) {
|
if (VOICE_INSTALLED) {
|
||||||
mVoiceInput = new VoiceInput(context, this);
|
mVoiceInput = new VoiceInput(service, this);
|
||||||
mHints = new Hints(context, prefs, new Hints.Display() {
|
mHints = new Hints(service, prefs, new Hints.Display() {
|
||||||
@Override
|
@Override
|
||||||
public void showHint(int viewResource) {
|
public void showHint(int viewResource) {
|
||||||
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
|
View view = LayoutInflater.from(mService).inflate(viewResource, null);
|
||||||
Context.LAYOUT_INFLATER_SERVICE);
|
mService.setCandidatesView(view);
|
||||||
View view = inflater.inflate(viewResource, null);
|
mService.setCandidatesViewShown(true);
|
||||||
mContext.setCandidatesView(view);
|
|
||||||
mContext.setCandidatesViewShown(true);
|
|
||||||
mIsShowingHint = true;
|
mIsShowingHint = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -161,23 +164,22 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
mVoiceInput.flushAllTextModificationCounters();
|
mVoiceInput.flushAllTextModificationCounters();
|
||||||
// send this intent AFTER logging any prior aggregated edits.
|
// send this intent AFTER logging any prior aggregated edits.
|
||||||
mVoiceInput.logTextModifiedByChooseSuggestion(suggestion.toString(), index,
|
mVoiceInput.logTextModifiedByChooseSuggestion(suggestion.toString(), index,
|
||||||
wordSeparators, mContext.getCurrentInputConnection());
|
wordSeparators, mService.getCurrentInputConnection());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showVoiceWarningDialog(final boolean swipe, IBinder token,
|
private void showVoiceWarningDialog(final boolean swipe, IBinder token) {
|
||||||
final boolean configurationChanging) {
|
|
||||||
if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) {
|
if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
AlertDialog.Builder builder = new AlertDialog.Builder(mService);
|
||||||
builder.setCancelable(true);
|
builder.setCancelable(true);
|
||||||
builder.setIcon(R.drawable.ic_mic_dialog);
|
builder.setIcon(R.drawable.ic_mic_dialog);
|
||||||
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
mVoiceInput.logKeyboardWarningDialogOk();
|
mVoiceInput.logKeyboardWarningDialogOk();
|
||||||
reallyStartListening(swipe, configurationChanging);
|
reallyStartListening(swipe);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@ -199,13 +201,13 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
final CharSequence message;
|
final CharSequence message;
|
||||||
if (mLocaleSupportedForVoiceInput) {
|
if (mLocaleSupportedForVoiceInput) {
|
||||||
message = TextUtils.concat(
|
message = TextUtils.concat(
|
||||||
mContext.getText(R.string.voice_warning_may_not_understand), "\n\n",
|
mService.getText(R.string.voice_warning_may_not_understand), "\n\n",
|
||||||
mContext.getText(R.string.voice_warning_how_to_turn_off));
|
mService.getText(R.string.voice_warning_how_to_turn_off));
|
||||||
} else {
|
} else {
|
||||||
message = TextUtils.concat(
|
message = TextUtils.concat(
|
||||||
mContext.getText(R.string.voice_warning_locale_not_supported), "\n\n",
|
mService.getText(R.string.voice_warning_locale_not_supported), "\n\n",
|
||||||
mContext.getText(R.string.voice_warning_may_not_understand), "\n\n",
|
mService.getText(R.string.voice_warning_may_not_understand), "\n\n",
|
||||||
mContext.getText(R.string.voice_warning_how_to_turn_off));
|
mService.getText(R.string.voice_warning_how_to_turn_off));
|
||||||
}
|
}
|
||||||
builder.setMessage(message);
|
builder.setMessage(message);
|
||||||
|
|
||||||
|
@ -296,7 +298,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showPunctuationHintIfNecessary() {
|
public void showPunctuationHintIfNecessary() {
|
||||||
InputConnection ic = mContext.getCurrentInputConnection();
|
InputConnection ic = mService.getCurrentInputConnection();
|
||||||
if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) {
|
if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) {
|
||||||
if (mHints.showPunctuationHintIfNecessary(ic)) {
|
if (mHints.showPunctuationHintIfNecessary(ic)) {
|
||||||
mVoiceInput.logPunctuationHintDisplayed();
|
mVoiceInput.logPunctuationHintDisplayed();
|
||||||
|
@ -364,17 +366,17 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void revertVoiceInput() {
|
private void revertVoiceInput() {
|
||||||
InputConnection ic = mContext.getCurrentInputConnection();
|
InputConnection ic = mService.getCurrentInputConnection();
|
||||||
if (ic != null) ic.commitText("", 1);
|
if (ic != null) ic.commitText("", 1);
|
||||||
mContext.updateSuggestions();
|
mService.updateSuggestions();
|
||||||
mVoiceInputHighlighted = false;
|
mVoiceInputHighlighted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void commitVoiceInput() {
|
public void commitVoiceInput() {
|
||||||
if (VOICE_INSTALLED && mVoiceInputHighlighted) {
|
if (VOICE_INSTALLED && mVoiceInputHighlighted) {
|
||||||
InputConnection ic = mContext.getCurrentInputConnection();
|
InputConnection ic = mService.getCurrentInputConnection();
|
||||||
if (ic != null) ic.finishComposingText();
|
if (ic != null) ic.finishComposingText();
|
||||||
mContext.updateSuggestions();
|
mService.updateSuggestions();
|
||||||
mVoiceInputHighlighted = false;
|
mVoiceInputHighlighted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,7 +396,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
if (mShowingVoiceSuggestions) {
|
if (mShowingVoiceSuggestions) {
|
||||||
// Retain the replaced word in the alternatives array.
|
// Retain the replaced word in the alternatives array.
|
||||||
String wordToBeReplaced = EditingUtils.getWordAtCursor(
|
String wordToBeReplaced = EditingUtils.getWordAtCursor(
|
||||||
mContext.getCurrentInputConnection(), wordSeparators);
|
mService.getCurrentInputConnection(), wordSeparators);
|
||||||
if (!mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
if (!mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
||||||
wordToBeReplaced = wordToBeReplaced.toLowerCase();
|
wordToBeReplaced = wordToBeReplaced.toLowerCase();
|
||||||
}
|
}
|
||||||
|
@ -438,8 +440,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
builder.addWords(suggestions);
|
builder.addWords(suggestions);
|
||||||
}
|
}
|
||||||
builder.setTypedWordValid(true).setHasMinimalSuggestion(true);
|
builder.setTypedWordValid(true).setHasMinimalSuggestion(true);
|
||||||
mContext.setSuggestions(builder.build());
|
mService.setSuggestions(builder.build());
|
||||||
mContext.setCandidatesViewShown(true);
|
mService.setCandidatesViewShown(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -486,15 +488,15 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
mAfterVoiceInput = true;
|
mAfterVoiceInput = true;
|
||||||
mImmediatelyAfterVoiceInput = true;
|
mImmediatelyAfterVoiceInput = true;
|
||||||
|
|
||||||
InputConnection ic = mContext.getCurrentInputConnection();
|
InputConnection ic = mService.getCurrentInputConnection();
|
||||||
if (!mContext.isFullscreenMode()) {
|
if (!mService.isFullscreenMode()) {
|
||||||
// Start listening for updates to the text from typing, etc.
|
// Start listening for updates to the text from typing, etc.
|
||||||
if (ic != null) {
|
if (ic != null) {
|
||||||
ExtractedTextRequest req = new ExtractedTextRequest();
|
ExtractedTextRequest req = new ExtractedTextRequest();
|
||||||
ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
|
ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mContext.vibrate();
|
mService.vibrate();
|
||||||
|
|
||||||
final List<CharSequence> nBest = new ArrayList<CharSequence>();
|
final List<CharSequence> nBest = new ArrayList<CharSequence>();
|
||||||
for (String c : mVoiceResults.candidates) {
|
for (String c : mVoiceResults.candidates) {
|
||||||
|
@ -511,7 +513,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
mHints.registerVoiceResult(bestResult);
|
mHints.registerVoiceResult(bestResult);
|
||||||
|
|
||||||
if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text
|
if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text
|
||||||
mContext.commitTyped(ic);
|
mService.commitTyped(ic);
|
||||||
EditingUtils.appendText(ic, bestResult);
|
EditingUtils.appendText(ic, bestResult);
|
||||||
if (ic != null) ic.endBatchEdit();
|
if (ic != null) ic.endBatchEdit();
|
||||||
|
|
||||||
|
@ -520,22 +522,38 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
onCancelVoice();
|
onCancelVoice();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void switchToRecognitionStatusView(final boolean configurationChanging) {
|
public void switchToRecognitionStatusView(final Configuration configuration) {
|
||||||
final boolean configChanged = configurationChanging;
|
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mContext.setCandidatesViewShown(false);
|
mService.setCandidatesViewShown(false);
|
||||||
mRecognizing = true;
|
mRecognizing = true;
|
||||||
|
mVoiceInput.newView();
|
||||||
View v = mVoiceInput.getView();
|
View v = mVoiceInput.getView();
|
||||||
|
|
||||||
ViewParent p = v.getParent();
|
ViewParent p = v.getParent();
|
||||||
if (p != null && p instanceof ViewGroup) {
|
if (p != null && p instanceof ViewGroup) {
|
||||||
((ViewGroup)p).removeView(v);
|
((ViewGroup) p).removeView(v);
|
||||||
}
|
}
|
||||||
mContext.setInputView(v);
|
|
||||||
mContext.updateInputViewShown();
|
View keyboardView = KeyboardSwitcher.getInstance().getInputView();
|
||||||
if (configChanged) {
|
|
||||||
mVoiceInput.onConfigurationChanged();
|
// The full height of the keyboard is difficult to calculate
|
||||||
|
// as the dimension is expressed in "mm" and not in "pixel"
|
||||||
|
// As we add mm, we don't know how the rounding is going to work
|
||||||
|
// thus we may end up with few pixels extra (or less).
|
||||||
|
if (keyboardView != null) {
|
||||||
|
int h = keyboardView.getHeight();
|
||||||
|
if (h > 0) {
|
||||||
|
View popupLayout = v.findViewById(R.id.popup_layout);
|
||||||
|
popupLayout.getLayoutParams().height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mService.setInputView(v);
|
||||||
|
mService.updateInputViewShown();
|
||||||
|
|
||||||
|
if (configuration != null) {
|
||||||
|
mVoiceInput.onConfigurationChanged(configuration);
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
@ -547,7 +565,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reallyStartListening(boolean swipe, final boolean configurationChanging) {
|
private void reallyStartListening(boolean swipe) {
|
||||||
if (!VOICE_INSTALLED) {
|
if (!VOICE_INSTALLED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +573,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
// The user has started a voice input, so remember that in the
|
// The user has started a voice input, so remember that in the
|
||||||
// future (so we don't show the warning dialog after the first run).
|
// future (so we don't show the warning dialog after the first run).
|
||||||
SharedPreferences.Editor editor =
|
SharedPreferences.Editor editor =
|
||||||
PreferenceManager.getDefaultSharedPreferences(mContext).edit();
|
PreferenceManager.getDefaultSharedPreferences(mService).edit();
|
||||||
editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true);
|
editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true);
|
||||||
SharedPreferencesCompat.apply(editor);
|
SharedPreferencesCompat.apply(editor);
|
||||||
mHasUsedVoiceInput = true;
|
mHasUsedVoiceInput = true;
|
||||||
|
@ -565,34 +583,32 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
// The user has started a voice input from an unsupported locale, so remember that
|
// The user has started a voice input from an unsupported locale, so remember that
|
||||||
// in the future (so we don't show the warning dialog the next time they do this).
|
// in the future (so we don't show the warning dialog the next time they do this).
|
||||||
SharedPreferences.Editor editor =
|
SharedPreferences.Editor editor =
|
||||||
PreferenceManager.getDefaultSharedPreferences(mContext).edit();
|
PreferenceManager.getDefaultSharedPreferences(mService).edit();
|
||||||
editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, true);
|
editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, true);
|
||||||
SharedPreferencesCompat.apply(editor);
|
SharedPreferencesCompat.apply(editor);
|
||||||
mHasUsedVoiceInputUnsupportedLocale = true;
|
mHasUsedVoiceInputUnsupportedLocale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear N-best suggestions
|
// Clear N-best suggestions
|
||||||
mContext.clearSuggestions();
|
mService.clearSuggestions();
|
||||||
|
|
||||||
FieldContext context = makeFieldContext();
|
FieldContext context = makeFieldContext();
|
||||||
mVoiceInput.startListening(context, swipe);
|
mVoiceInput.startListening(context, swipe);
|
||||||
switchToRecognitionStatusView(configurationChanging);
|
switchToRecognitionStatusView(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startListening(final boolean swipe, IBinder token,
|
public void startListening(final boolean swipe, IBinder token) {
|
||||||
final boolean configurationChanging) {
|
|
||||||
// TODO: remove swipe which is no longer used.
|
// TODO: remove swipe which is no longer used.
|
||||||
if (VOICE_INSTALLED) {
|
if (VOICE_INSTALLED) {
|
||||||
if (needsToShowWarningDialog()) {
|
if (needsToShowWarningDialog()) {
|
||||||
// Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel.
|
// Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel.
|
||||||
showVoiceWarningDialog(swipe, token, configurationChanging);
|
showVoiceWarningDialog(swipe, token);
|
||||||
} else {
|
} else {
|
||||||
reallyStartListening(swipe, configurationChanging);
|
reallyStartListening(swipe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean fieldCanDoVoice(FieldContext fieldContext) {
|
private boolean fieldCanDoVoice(FieldContext fieldContext) {
|
||||||
return !mPasswordText
|
return !mPasswordText
|
||||||
&& mVoiceInput != null
|
&& mVoiceInput != null
|
||||||
|
@ -603,7 +619,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext)
|
return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext)
|
||||||
&& !(attribute != null
|
&& !(attribute != null
|
||||||
&& IME_OPTION_NO_MICROPHONE.equals(attribute.privateImeOptions))
|
&& IME_OPTION_NO_MICROPHONE.equals(attribute.privateImeOptions))
|
||||||
&& SpeechRecognizer.isRecognitionAvailable(mContext);
|
&& SpeechRecognizer.isRecognitionAvailable(mService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadSettings(EditorInfo attribute, SharedPreferences sp) {
|
public void loadSettings(EditorInfo attribute, SharedPreferences sp) {
|
||||||
|
@ -616,10 +632,10 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
|
|
||||||
if (VOICE_INSTALLED) {
|
if (VOICE_INSTALLED) {
|
||||||
final String voiceMode = sp.getString(PREF_VOICE_MODE,
|
final String voiceMode = sp.getString(PREF_VOICE_MODE,
|
||||||
mContext.getString(R.string.voice_mode_main));
|
mService.getString(R.string.voice_mode_main));
|
||||||
mVoiceButtonEnabled = !voiceMode.equals(mContext.getString(R.string.voice_mode_off))
|
mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off))
|
||||||
&& shouldShowVoiceButton(makeFieldContext(), attribute);
|
&& shouldShowVoiceButton(makeFieldContext(), attribute);
|
||||||
mVoiceButtonOnPrimary = voiceMode.equals(mContext.getString(R.string.voice_mode_main));
|
mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,9 +648,14 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
public void onStartInputView(IBinder token) {
|
public void onStartInputView(IBinder token) {
|
||||||
// If IME is in voice mode, but still needs to show the voice warning dialog,
|
// If IME is in voice mode, but still needs to show the voice warning dialog,
|
||||||
// keep showing the warning.
|
// keep showing the warning.
|
||||||
if (mSubtypeSwitcher.isVoiceMode() && needsToShowWarningDialog() && token != null) {
|
if (mSubtypeSwitcher.isVoiceMode() && token != null) {
|
||||||
showVoiceWarningDialog(false, token, false);
|
// Close keyboard view if it is been shown.
|
||||||
|
if (KeyboardSwitcher.getInstance().isInputViewShown())
|
||||||
|
KeyboardSwitcher.getInstance().getInputView().purgeKeyboardAndClosing();
|
||||||
|
startListening(false, token);
|
||||||
}
|
}
|
||||||
|
// If we have no token, onAttachedToWindow will take care of showing dialog and start
|
||||||
|
// listening.
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAttachedToWindow() {
|
public void onAttachedToWindow() {
|
||||||
|
@ -643,9 +664,9 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
mSubtypeSwitcher.setVoiceInput(mVoiceInput);
|
mSubtypeSwitcher.setVoiceInput(mVoiceInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onConfigurationChanged(boolean configurationChanging) {
|
public void onConfigurationChanged(Configuration configuration) {
|
||||||
if (mRecognizing) {
|
if (mRecognizing) {
|
||||||
switchToRecognitionStatusView(configurationChanging);
|
switchToRecognitionStatusView(configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,7 +685,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
// onCurrentInputMethodSubtypeChanged() will be called first. LatinIME will know
|
// onCurrentInputMethodSubtypeChanged() will be called first. LatinIME will know
|
||||||
// that it's in keyboard mode and SubtypeSwitcher will call onCancelVoice().
|
// that it's in keyboard mode and SubtypeSwitcher will call onCancelVoice().
|
||||||
mRecognizing = false;
|
mRecognizing = false;
|
||||||
mContext.switchToKeyboardView();
|
mService.switchToKeyboardView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,8 +703,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
||||||
|
|
||||||
public FieldContext makeFieldContext() {
|
public FieldContext makeFieldContext() {
|
||||||
SubtypeSwitcher switcher = SubtypeSwitcher.getInstance();
|
SubtypeSwitcher switcher = SubtypeSwitcher.getInstance();
|
||||||
return new FieldContext(mContext.getCurrentInputConnection(),
|
return new FieldContext(mService.getCurrentInputConnection(),
|
||||||
mContext.getCurrentInputEditorInfo(), switcher.getInputLocaleStr(),
|
mService.getCurrentInputEditorInfo(), switcher.getInputLocaleStr(),
|
||||||
switcher.getEnabledLanguages());
|
switcher.getEnabledLanguages());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.android.inputmethod.latin.R;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -129,12 +130,17 @@ public class VoiceInput implements OnClickListener {
|
||||||
|
|
||||||
private final static int MSG_CLOSE_ERROR_DIALOG = 1;
|
private final static int MSG_CLOSE_ERROR_DIALOG = 1;
|
||||||
|
|
||||||
|
private final static int MSG_RESET = 2;
|
||||||
|
|
||||||
private final Handler mHandler = new Handler() {
|
private final Handler mHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
if (msg.what == MSG_CLOSE_ERROR_DIALOG) {
|
if (msg.what == MSG_RESET || msg.what == MSG_CLOSE_ERROR_DIALOG) {
|
||||||
mState = DEFAULT;
|
mState = DEFAULT;
|
||||||
mRecognitionView.finish();
|
mRecognitionView.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.what == MSG_CLOSE_ERROR_DIALOG) {
|
||||||
mUiListener.onCancelVoice();
|
mUiListener.onCancelVoice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,8 +283,9 @@ public class VoiceInput implements OnClickListener {
|
||||||
* The configuration of the IME changed and may have caused the views to be layed out
|
* The configuration of the IME changed and may have caused the views to be layed out
|
||||||
* again. Restore the state of the recognition view.
|
* again. Restore the state of the recognition view.
|
||||||
*/
|
*/
|
||||||
public void onConfigurationChanged() {
|
public void onConfigurationChanged(Configuration configuration) {
|
||||||
mRecognitionView.restoreState();
|
mRecognitionView.restoreState();
|
||||||
|
mRecognitionView.getView().dispatchConfigurationChanged(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -509,7 +516,7 @@ public class VoiceInput implements OnClickListener {
|
||||||
mState = DEFAULT;
|
mState = DEFAULT;
|
||||||
|
|
||||||
// Remove all pending tasks (e.g., timers to cancel voice input)
|
// Remove all pending tasks (e.g., timers to cancel voice input)
|
||||||
mHandler.removeMessages(MSG_CLOSE_ERROR_DIALOG);
|
mHandler.removeMessages(MSG_RESET);
|
||||||
|
|
||||||
mSpeechRecognizer.cancel();
|
mSpeechRecognizer.cancel();
|
||||||
mUiListener.onCancelVoice();
|
mUiListener.onCancelVoice();
|
||||||
|
|
|
@ -89,7 +89,7 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dictBuf = malloc(sizeof(char) * dictSize);
|
dictBuf = malloc(sizeof(char) * dictSize);
|
||||||
if (dictBuf == NULL) {
|
if (!dictBuf) {
|
||||||
LOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno);
|
LOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
import android.view.inputmethod.InputMethodInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class SubtypeLocaleTests extends AndroidTestCase {
|
||||||
|
private static final String PACKAGE = LatinIME.class.getPackage().getName();
|
||||||
|
|
||||||
|
private Resources mRes;
|
||||||
|
private List<InputMethodSubtype> mKeyboardSubtypes;
|
||||||
|
|
||||||
|
public interface Predicator<T> {
|
||||||
|
public boolean evaluate(T object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> List<T> filter(List<T> source, Predicator<? super T> predicator) {
|
||||||
|
final ArrayList<T> filtered = new ArrayList<T>();
|
||||||
|
for (final T element : source) {
|
||||||
|
if (predicator.evaluate(element))
|
||||||
|
filtered.add(element);
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
final Context context = getContext();
|
||||||
|
mRes = context.getResources();
|
||||||
|
|
||||||
|
SubtypeLocale.init(context);
|
||||||
|
|
||||||
|
final InputMethodManager imm = (InputMethodManager) context.getSystemService(
|
||||||
|
Context.INPUT_METHOD_SERVICE);
|
||||||
|
for (final InputMethodInfo imi : imm.getInputMethodList()) {
|
||||||
|
if (imi.getPackageName().equals(PACKAGE)) {
|
||||||
|
mKeyboardSubtypes = filter(imi.getSubtypes(),
|
||||||
|
new Predicator<InputMethodSubtype>() {
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(InputMethodSubtype ims) {
|
||||||
|
return ims.getMode().equals("keyboard");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertNotNull("Can not find input method " + PACKAGE, mKeyboardSubtypes);
|
||||||
|
assertTrue("Can not find keyboard subtype", mKeyboardSubtypes.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copied from {@link java.junit.Assert#format(String, Object, Object)}
|
||||||
|
private static String format(String message, Object expected, Object actual) {
|
||||||
|
return message + " expected:<" + expected + "> but was:<" + actual + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringWithLocale(int resId, Locale locale) {
|
||||||
|
final Locale savedLocale = Locale.getDefault();
|
||||||
|
try {
|
||||||
|
Locale.setDefault(locale);
|
||||||
|
return mRes.getString(resId);
|
||||||
|
} finally {
|
||||||
|
Locale.setDefault(savedLocale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSubtypeLocale() {
|
||||||
|
for (final InputMethodSubtype subtype : mKeyboardSubtypes) {
|
||||||
|
final String localeCode = subtype.getLocale();
|
||||||
|
final Locale locale = new Locale(localeCode);
|
||||||
|
// The locale name which will be displayed on spacebar. For example 'English (US)' or
|
||||||
|
// 'Francais (Canada)'. (c=\u008d)
|
||||||
|
final String displayName = SubtypeLocale.getFullDisplayName(locale);
|
||||||
|
// The subtype name in its locale. For example 'English (US) Keyboard' or
|
||||||
|
// 'Clavier Francais (Canada)'. (c=\u008d)
|
||||||
|
final String subtypeName = getStringWithLocale(subtype.getNameResId(), locale);
|
||||||
|
assertTrue(
|
||||||
|
format("subtype display name of " + localeCode + ":", subtypeName, displayName),
|
||||||
|
subtypeName.contains(displayName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|