diff options
Diffstat (limited to 'java')
233 files changed, 7915 insertions, 6717 deletions
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml index e0eecfc7d..2fbf4c2be 100644 --- a/java/AndroidManifest.xml +++ b/java/AndroidManifest.xml @@ -33,7 +33,7 @@ </intent-filter> </activity> - <activity android:name="InputLanguageSelection" + <activity android:name="com.android.inputmethod.deprecated.languageswitcher.InputLanguageSelection" android:label="@string/language_selection_title"> <intent-filter> <action android:name="android.intent.action.MAIN"/> diff --git a/java/proguard.flags b/java/proguard.flags index 729f4ad61..914bd7595 100644 --- a/java/proguard.flags +++ b/java/proguard.flags @@ -18,3 +18,7 @@ -keep class com.android.inputmethod.latin.AutoCorrection { java.lang.CharSequence getAutoCorrectionWord(); } + +-keep class com.android.inputmethod.latin.Utils { + boolean equalsIgnoreCase(...); +} diff --git a/java/res/anim/key_preview_fadein.xml b/java/res/anim/key_preview_fadein.xml deleted file mode 100644 index 9fad7b9a7..000000000 --- a/java/res/anim/key_preview_fadein.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2010, 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. -*/ ---> - -<set - xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/decelerate_interpolator" -> - <alpha - android:fromAlpha="0.5" - android:toAlpha="1.0" - android:duration="@integer/config_preview_fadein_anim_time" /> -</set> diff --git a/java/res/anim/key_preview_fadeout.xml b/java/res/anim/key_preview_fadeout.xml deleted file mode 100644 index 7de5123cd..000000000 --- a/java/res/anim/key_preview_fadeout.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2010, 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. -*/ ---> - -<set - xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/accelerate_interpolator" -> - <alpha - android:fromAlpha="1.0" - android:toAlpha="0.0" - android:duration="@integer/config_preview_fadeout_anim_time" /> -</set> diff --git a/java/res/anim/mini_keyboard_fadein.xml b/java/res/anim/mini_keyboard_fadein.xml index 9fad7b9a7..f80e8b8de 100644 --- a/java/res/anim/mini_keyboard_fadein.xml +++ b/java/res/anim/mini_keyboard_fadein.xml @@ -25,5 +25,5 @@ <alpha android:fromAlpha="0.5" android:toAlpha="1.0" - android:duration="@integer/config_preview_fadein_anim_time" /> + android:duration="@integer/config_mini_keyboard_fadein_anim_time" /> </set> diff --git a/java/res/anim/mini_keyboard_fadeout.xml b/java/res/anim/mini_keyboard_fadeout.xml index 7de5123cd..535b100ae 100644 --- a/java/res/anim/mini_keyboard_fadeout.xml +++ b/java/res/anim/mini_keyboard_fadeout.xml @@ -25,5 +25,5 @@ <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:duration="@integer/config_preview_fadeout_anim_time" /> + android:duration="@integer/config_mini_keyboard_fadeout_anim_time" /> </set> diff --git a/java/res/drawable-hdpi/btn_center_default.9.png b/java/res/drawable-hdpi/btn_center_default.9.png Binary files differindex d5ec36ba4..d5ec36ba4 100755..100644 --- a/java/res/drawable-hdpi/btn_center_default.9.png +++ b/java/res/drawable-hdpi/btn_center_default.9.png diff --git a/java/res/drawable-hdpi/btn_center_pressed.9.png b/java/res/drawable-hdpi/btn_center_pressed.9.png Binary files differindex 593a679d0..593a679d0 100755..100644 --- a/java/res/drawable-hdpi/btn_center_pressed.9.png +++ b/java/res/drawable-hdpi/btn_center_pressed.9.png diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-hdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index a8e5f7d5e..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png Binary files differindex 603bf0e15..603bf0e15 100755..100644 --- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png Binary files differindex 6ddd516e7..6ddd516e7 100755..100644 --- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png Binary files differindex 65fdeb353..65fdeb353 100755..100644 --- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png Binary files differindex 7ec915fe8..7ec915fe8 100755..100644 --- a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png Binary files differindex 439271723..439271723 100755..100644 --- a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png Binary files differindex c2cc32044..c2cc32044 100755..100644 --- a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png +++ b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png diff --git a/java/res/drawable-mdpi/btn_center_default.9.png b/java/res/drawable-mdpi/btn_center_default.9.png Binary files differindex d5ec36ba4..d5ec36ba4 100755..100644 --- a/java/res/drawable-mdpi/btn_center_default.9.png +++ b/java/res/drawable-mdpi/btn_center_default.9.png diff --git a/java/res/drawable-mdpi/btn_center_pressed.9.png b/java/res/drawable-mdpi/btn_center_pressed.9.png Binary files differindex 593a679d0..593a679d0 100755..100644 --- a/java/res/drawable-mdpi/btn_center_pressed.9.png +++ b/java/res/drawable-mdpi/btn_center_pressed.9.png diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-mdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 25e655d96..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/layout-large/candidate.xml b/java/res/layout-large/candidate.xml deleted file mode 100644 index e672707a1..000000000 --- a/java/res/layout-large/candidate.xml +++ /dev/null @@ -1,60 +0,0 @@ -<?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. -*/ ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:orientation="horizontal" - android:paddingRight="@dimen/candidate_padding" -> - <ImageView - android:id="@+id/candidate_divider" - android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" - android:visibility="gone" - android:focusable="false" - android:clickable="false" - android:src="@drawable/keyboard_suggest_strip_divider" - android:gravity="center_vertical|center_horizontal" /> - <Button - android:id="@+id/candidate_word" - android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" - android:minWidth="@dimen/candidate_min_width" - android:textSize="@dimen/candidate_text_size" - android:textColor="@color/candidate_normal" - android:background="@drawable/btn_candidate_holo" - android:focusable="true" - android:clickable="true" - android:gravity="center_vertical|center_horizontal" - android:paddingLeft="@dimen/candidate_padding" /> - <TextView - android:id="@+id/candidate_debug_info" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:visibility="gone" - android:textSize="10dip" - android:textColor="#ff808080" - android:focusable="false" - android:clickable="false" - android:gravity="bottom" - android:paddingLeft="4dip" /> -</LinearLayout> diff --git a/java/res/layout-large/candidate_preview.xml b/java/res/layout-large/candidate_preview.xml deleted file mode 100644 index 3ef2e6ed4..000000000 --- a/java/res/layout-large/candidate_preview.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?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. -*/ ---> - -<TextView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="18sp" - android:textColor="?android:attr/textColorPrimaryInverse" - android:minWidth="32dip" - android:gravity="center" - android:background="@drawable/keyboard_popup_panel_background_holo" /> diff --git a/java/res/layout-large/candidates.xml b/java/res/layout-large/candidates.xml deleted file mode 100644 index 26d6822e9..000000000 --- a/java/res/layout-large/candidates.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?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. -*/ ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip_holo" - android:paddingRight="@dimen/candidate_strip_padding" - android:paddingLeft="@dimen/candidate_strip_padding" -> - <HorizontalScrollView - android:id="@+id/candidates_scroll_view" - android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" - android:fadingEdge="horizontal" - android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" - android:scrollbars="none" - > - <com.android.inputmethod.latin.CandidateView - android:id="@+id/candidates" - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip_holo" /> - </HorizontalScrollView> -</LinearLayout> diff --git a/java/res/layout-large/keyboard_popup_honeycomb.xml b/java/res/layout-large/keyboard_popup_honeycomb.xml deleted file mode 100644 index 49eb936d6..000000000 --- a/java/res/layout-large/keyboard_popup_honeycomb.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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. -*/ ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:background="@drawable/keyboard_popup_panel_background_holo" - android:paddingLeft="40dip" - android:paddingRight="40dip" - > - <com.android.inputmethod.keyboard.KeyboardView - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/KeyboardView" - android:layout_alignParentBottom="true" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@color/latinkeyboard_transparent" - - latin:keyBackground="@drawable/btn_keyboard_key_honeycomb_popup" - latin:keyHysteresisDistance="0dip" - latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction" - /> -</LinearLayout> diff --git a/java/res/layout-xlarge/candidate.xml b/java/res/layout-xlarge/candidate.xml index 74532a1e2..582e64261 100644 --- a/java/res/layout-xlarge/candidate.xml +++ b/java/res/layout-xlarge/candidate.xml @@ -20,41 +20,40 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" + android:layout_width="wrap_content" + android:layout_height="match_parent" android:orientation="horizontal" - android:paddingRight="@dimen/candidate_padding" > <ImageView android:id="@+id/candidate_divider" android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" - android:visibility="gone" + android:layout_height="match_parent" + android:src="@drawable/keyboard_suggest_strip_divider" + android:paddingRight="@dimen/candidate_padding" + android:paddingLeft="@dimen/candidate_padding" + android:visibility="invisible" android:focusable="false" android:clickable="false" - android:src="@drawable/keyboard_suggest_strip_divider" android:gravity="center_vertical|center_horizontal" /> <Button android:id="@+id/candidate_word" android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" + android:layout_height="match_parent" android:minWidth="@dimen/candidate_min_width" android:textSize="@dimen/candidate_text_size" android:textColor="@color/candidate_normal" android:background="@drawable/btn_candidate_holo" android:focusable="true" android:clickable="true" - android:gravity="center_vertical|center_horizontal" - android:paddingLeft="@dimen/candidate_padding" /> + android:gravity="center_vertical|center_horizontal" /> <TextView android:id="@+id/candidate_debug_info" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:visibility="gone" android:textSize="10dip" android:textColor="#ff808080" android:focusable="false" android:clickable="false" - android:gravity="bottom" - android:paddingLeft="4dip" /> + android:gravity="bottom" /> </LinearLayout> diff --git a/java/res/layout-xlarge/candidates.xml b/java/res/layout-xlarge/candidates.xml index e2ddb84b1..e111acd5b 100644 --- a/java/res/layout-xlarge/candidates.xml +++ b/java/res/layout-xlarge/candidates.xml @@ -20,26 +20,36 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/candidates_container" android:orientation="horizontal" + android:gravity="bottom" android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip_holo" - android:paddingRight="@dimen/candidate_strip_padding" - android:paddingLeft="@dimen/candidate_strip_padding" + android:layout_height="wrap_content" + android:minHeight="@dimen/candidate_strip_minimum_height" > - <HorizontalScrollView - android:id="@+id/candidates_scroll_view" - android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" - android:fadingEdge="horizontal" - android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" - android:scrollbars="none" + <!-- On tablets, the candidate strip is centered with horizontal paddings on both sides because + width of the landscape mode is too long for the candidate strip. This LinearLayout is + required to hold the paddings. --> + <LinearLayout + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/keyboard_suggest_strip_holo" + android:paddingRight="@dimen/candidate_strip_padding" + android:paddingLeft="@dimen/candidate_strip_padding" > - <com.android.inputmethod.latin.CandidateView - android:id="@+id/candidates" - android:orientation="horizontal" + <HorizontalScrollView android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip_holo" /> - </HorizontalScrollView> + android:layout_height="wrap_content" + android:fadingEdge="horizontal" + android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" + android:scrollbars="none" + > + <com.android.inputmethod.latin.CandidateView + android:id="@+id/candidates" + android:layout_width="match_parent" + android:layout_height="@dimen/candidate_strip_height" + android:gravity="center_vertical" /> + </HorizontalScrollView> + </LinearLayout> </LinearLayout> diff --git a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml b/java/res/layout-xlarge/keyboard_popup_honeycomb.xml deleted file mode 100644 index 0b8229ca5..000000000 --- a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2010, 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. -*/ ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:background="@drawable/keyboard_popup_panel_background_holo" - android:paddingLeft="40dip" - android:paddingRight="40dip" - > - <com.android.inputmethod.keyboard.KeyboardView - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/KeyboardView" - android:layout_alignParentBottom="true" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@color/latinkeyboard_transparent" - - latin:keyBackground="@drawable/btn_keyboard_key_honeycomb_popup" - latin:keyHysteresisDistance="0dip" - latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction" - /> -</LinearLayout> diff --git a/java/res/layout-xlarge/recognition_status.xml b/java/res/layout-xlarge/recognition_status.xml new file mode 100644 index 000000000..40bc09823 --- /dev/null +++ b/java/res/layout-xlarge/recognition_status.xml @@ -0,0 +1,101 @@ +<?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. +*/ +--> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:background="@drawable/background_voice"> + <LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/popup_layout" + android:orientation="vertical" + android:layout_height="371dip" + android:layout_width="500dip" + android:layout_centerInParent="true" + android:background="@drawable/vs_dialog_red"> + <TextView + android:id="@+id/text" + android:text="@string/voice_error" + 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.deprecated.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> + <!-- + The text is set by the code. We specify a random text (voice_error), so the + text view does not have a zero height. This is necessary to keep the slash + mic and the recording mic is the same position + --> + <TextView + android:id="@+id/language" + android:text="@string/voice_error" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:singleLine="true" + android:textSize="14sp" + android:layout_marginBottom="3dip" + android:layout_gravity="center" + android:textColor="#ffffff" + android:visibility="invisible"/> + <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> +</RelativeLayout> diff --git a/java/res/layout/candidate.xml b/java/res/layout/candidate.xml index f2c4126b3..5472a1dd1 100644 --- a/java/res/layout/candidate.xml +++ b/java/res/layout/candidate.xml @@ -20,41 +20,40 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" + android:layout_width="wrap_content" + android:layout_height="match_parent" android:orientation="horizontal" - android:paddingRight="@dimen/candidate_padding" > <ImageView android:id="@+id/candidate_divider" android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" - android:visibility="gone" + android:layout_height="match_parent" + android:src="@drawable/keyboard_suggest_strip_divider" + android:paddingRight="@dimen/candidate_padding" + android:paddingLeft="@dimen/candidate_padding" + android:visibility="invisible" android:focusable="false" android:clickable="false" - android:src="@drawable/keyboard_suggest_strip_divider" android:gravity="center_vertical|center_horizontal" /> <Button android:id="@+id/candidate_word" android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" + android:layout_height="match_parent" android:minWidth="@dimen/candidate_min_width" android:textSize="@dimen/candidate_text_size" android:textColor="@color/candidate_normal" android:background="@drawable/btn_candidate" android:focusable="true" android:clickable="true" - android:gravity="center_vertical|center_horizontal" - android:paddingLeft="@dimen/candidate_padding" /> + android:gravity="center_vertical|center_horizontal" /> <TextView android:id="@+id/candidate_debug_info" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:visibility="gone" android:textSize="10dip" android:textColor="#ff808080" android:focusable="false" android:clickable="false" - android:gravity="bottom" - android:paddingLeft="4dip" /> + android:gravity="bottom" /> </LinearLayout> diff --git a/java/res/layout/candidates.xml b/java/res/layout/candidates.xml index 1b8d04183..5c29f737f 100644 --- a/java/res/layout/candidates.xml +++ b/java/res/layout/candidates.xml @@ -20,26 +20,27 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/candidates_container" android:orientation="horizontal" + android:gravity="bottom" android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip" + android:layout_height="wrap_content" + android:minHeight="@dimen/candidate_strip_minimum_height" android:paddingRight="@dimen/candidate_strip_padding" android:paddingLeft="@dimen/candidate_strip_padding" > <HorizontalScrollView - android:id="@+id/candidates_scroll_view" - android:layout_width="wrap_content" - android:layout_height="@dimen/candidate_strip_height" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/keyboard_suggest_strip" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" android:scrollbars="none" > <com.android.inputmethod.latin.CandidateView android:id="@+id/candidates" - android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip" /> + android:gravity="center_vertical" /> </HorizontalScrollView> </LinearLayout> diff --git a/java/res/layout/input_basic.xml b/java/res/layout/input_basic.xml index 7b85bae94..ec2f60e9c 100644 --- a/java/res/layout/input_basic.xml +++ b/java/res/layout/input_basic.xml @@ -18,14 +18,21 @@ */ --> -<com.android.inputmethod.keyboard.LatinKeyboardView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/LatinkeyboardBaseView" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <include + layout="@layout/candidates" /> + <com.android.inputmethod.keyboard.LatinKeyboardView + android:id="@+id/latin_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" + android:padding="0dip" android:background="@drawable/keyboard_background" - - latin:keyBackground="@drawable/btn_keyboard_key" - /> + latin:keyBackground="@drawable/btn_keyboard_key" /> +</LinearLayout> diff --git a/java/res/layout/input_basic_highcontrast.xml b/java/res/layout/input_basic_highcontrast.xml index d9200fd5e..0a34b1fd7 100644 --- a/java/res/layout/input_basic_highcontrast.xml +++ b/java/res/layout/input_basic_highcontrast.xml @@ -18,15 +18,21 @@ */ --> -<com.android.inputmethod.keyboard.LatinKeyboardView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - - android:id="@+id/LatinkeyboardBaseView" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <include + layout="@layout/candidates" /> + <com.android.inputmethod.keyboard.LatinKeyboardView + android:id="@+id/latin_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" + android:padding="0dip" android:background="@android:color/black" - - latin:keyBackground="@drawable/btn_keyboard_key3" - /> + latin:keyBackground="@drawable/btn_keyboard_key3" /> +</LinearLayout> diff --git a/java/res/layout/input_gingerbread.xml b/java/res/layout/input_gingerbread.xml index 6233e6dc6..f620151cf 100644 --- a/java/res/layout/input_gingerbread.xml +++ b/java/res/layout/input_gingerbread.xml @@ -18,17 +18,22 @@ */ --> -<com.android.inputmethod.keyboard.LatinKeyboardView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/LatinkeyboardBaseView" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <include + layout="@layout/candidates" /> + <com.android.inputmethod.keyboard.LatinKeyboardView + android:id="@+id/latin_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="@dimen/keyboard_top_padding" - android:paddingBottom="@dimen/keyboard_bottom_padding" + android:padding="0dip" android:background="@drawable/keyboard_dark_background" - latin:keyBackground="@drawable/btn_keyboard_key_gingerbread" - latin:keyLetterStyle="bold" - /> + latin:keyLetterStyle="bold" /> +</LinearLayout> diff --git a/java/res/layout/input_honeycomb.xml b/java/res/layout/input_honeycomb.xml index 6ccc63c2b..5a7dcb034 100644 --- a/java/res/layout/input_honeycomb.xml +++ b/java/res/layout/input_honeycomb.xml @@ -18,22 +18,29 @@ */ --> -<com.android.inputmethod.keyboard.LatinKeyboardView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/LatinkeyboardBaseView" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <include + layout="@layout/candidates" /> + <com.android.inputmethod.keyboard.LatinKeyboardView + android:id="@+id/latin_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="@dimen/keyboard_top_padding" - android:paddingBottom="@dimen/keyboard_bottom_padding" + android:padding="0dip" android:background="@drawable/keyboard_background_holo" - latin:keyBackground="@drawable/btn_keyboard_key_honeycomb" latin:keyPreviewLayout="@layout/key_preview_honeycomb" + latin:keyPreviewHeight="@dimen/key_preview_height_holo" + latin:keyPreviewOffset="@dimen/key_preview_offset_holo" latin:popupLayout="@layout/keyboard_popup_honeycomb" latin:keyTextColorDisabled="#FF63666D" latin:keyLetterStyle="bold" latin:shadowColor="#00000000" - latin:shadowRadius="0.0" - /> + latin:shadowRadius="0.0" /> +</LinearLayout> diff --git a/java/res/layout/input_stone_bold.xml b/java/res/layout/input_stone_bold.xml index 6fdc93855..ca0794cef 100644 --- a/java/res/layout/input_stone_bold.xml +++ b/java/res/layout/input_stone_bold.xml @@ -18,20 +18,27 @@ */ --> -<com.android.inputmethod.keyboard.LatinKeyboardView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/LatinkeyboardBaseView" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <include + layout="@layout/candidates" /> + <com.android.inputmethod.keyboard.LatinKeyboardView + android:id="@+id/latin_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" + android:padding="0dip" android:background="@drawable/keyboard_background" - latin:keyBackground="@drawable/btn_keyboard_key_stone" latin:keyTextColor="@color/latinkeyboard_key_color_black" latin:keyTextColorDisabled="#FF808080" latin:shadowColor="@color/latinkeyboard_key_color_white" latin:keyLetterStyle="bold" latin:colorScheme="black" - latin:popupLayout="@layout/input_stone_popup" - /> + latin:popupLayout="@layout/keyboard_popup_stone" /> +</LinearLayout> diff --git a/java/res/layout/input_stone_normal.xml b/java/res/layout/input_stone_normal.xml index 6ae9aed55..9d5afb68b 100644 --- a/java/res/layout/input_stone_normal.xml +++ b/java/res/layout/input_stone_normal.xml @@ -18,19 +18,26 @@ */ --> -<com.android.inputmethod.keyboard.LatinKeyboardView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/LatinkeyboardBaseView" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" +> + <include + layout="@layout/candidates" /> + <com.android.inputmethod.keyboard.LatinKeyboardView + android:id="@+id/latin_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" + android:padding="0dip" android:background="@drawable/keyboard_background" - latin:keyBackground="@drawable/btn_keyboard_key_stone" latin:keyTextColor="@color/latinkeyboard_key_color_black" latin:keyTextColorDisabled="#FF808080" latin:shadowColor="@color/latinkeyboard_key_color_white" latin:colorScheme="black" - latin:popupLayout="@layout/input_stone_popup" - /> + latin:popupLayout="@layout/keyboard_popup_stone" /> +</LinearLayout> diff --git a/java/res/layout/key_preview_honeycomb.xml b/java/res/layout/key_preview_honeycomb.xml index a90fe5588..2fbfbb517 100644 --- a/java/res/layout/key_preview_honeycomb.xml +++ b/java/res/layout/key_preview_honeycomb.xml @@ -23,7 +23,7 @@ android:layout_height="80sp" android:textSize="40sp" android:textColor="@color/latinkeyboard_key_color_white" - android:minWidth="24dip" + android:minWidth="32dip" android:gravity="center" android:background="@drawable/keyboard_key_feedback_honeycomb" /> diff --git a/java/res/layout/keyboard_popup.xml b/java/res/layout/keyboard_popup.xml index ac8134bfb..0317d8deb 100644 --- a/java/res/layout/keyboard_popup.xml +++ b/java/res/layout/keyboard_popup.xml @@ -19,20 +19,19 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@drawable/keyboard_popup_panel_background" - android:paddingLeft="16dip" - android:paddingRight="16dip" + android:paddingLeft="@dimen/mini_keyboard_horizontal_padding" + android:paddingRight="@dimen/mini_keyboard_horizontal_padding" > - <com.android.inputmethod.keyboard.KeyboardView + <com.android.inputmethod.keyboard.PopupMiniKeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/KeyboardView" + android:id="@+id/mini_keyboard_view" android:layout_alignParentBottom="true" - android:layout_width="match_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@color/latinkeyboard_transparent" latin:keyBackground="@drawable/btn_keyboard_key_gingerbread_popup" latin:keyHysteresisDistance="0dip" diff --git a/java/res/layout/keyboard_popup_honeycomb.xml b/java/res/layout/keyboard_popup_honeycomb.xml index e5fcbd44c..2ddcbdc0c 100644 --- a/java/res/layout/keyboard_popup_honeycomb.xml +++ b/java/res/layout/keyboard_popup_honeycomb.xml @@ -19,20 +19,19 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@drawable/keyboard_popup_panel_background_holo" - android:paddingLeft="24dip" - android:paddingRight="24dip" + android:paddingLeft="@dimen/mini_keyboard_horizontal_padding_holo" + android:paddingRight="@dimen/mini_keyboard_horizontal_padding_holo" > - <com.android.inputmethod.keyboard.KeyboardView + <com.android.inputmethod.keyboard.PopupMiniKeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/KeyboardView" + android:id="@+id/mini_keyboard_view" android:layout_alignParentBottom="true" - android:layout_width="match_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@color/latinkeyboard_transparent" latin:keyBackground="@drawable/btn_keyboard_key_honeycomb_popup" latin:keyHysteresisDistance="0dip" diff --git a/java/res/layout/input_stone_popup.xml b/java/res/layout/keyboard_popup_stone.xml index b4da04536..94176b244 100644 --- a/java/res/layout/input_stone_popup.xml +++ b/java/res/layout/keyboard_popup_stone.xml @@ -25,9 +25,9 @@ android:orientation="horizontal" android:background="@drawable/keyboard_popup_panel_background" > - <com.android.inputmethod.keyboard.KeyboardView + <com.android.inputmethod.keyboard.PopupMiniKeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/KeyboardView" + android:id="@+id/mini_keyboard_view" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -36,6 +36,5 @@ latin:keyBackground="@drawable/btn_keyboard_key_stone" latin:keyTextColor="@color/latinkeyboard_key_color_black" latin:shadowColor="@color/latinkeyboard_key_color_white" - latin:popupLayout="@layout/input_stone_popup" /> </LinearLayout> diff --git a/java/res/layout/recognition_status.xml b/java/res/layout/recognition_status.xml index 9474d6f58..a2ddb7c50 100644 --- a/java/res/layout/recognition_status.xml +++ b/java/res/layout/recognition_status.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2009, 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 +** 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 +** 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 +** 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. */ --> @@ -37,7 +37,7 @@ android:layout_width="wrap_content" android:singleLine="true" android:layout_marginTop="10dip" - android:textSize="28sp" + android:textSize="20sp" android:textColor="#ffffff" android:layout_gravity="center" android:visibility="invisible"/> @@ -45,7 +45,7 @@ android:layout_height="0dip" android:layout_width="match_parent" android:layout_weight="1.0"> - <com.android.inputmethod.voice.SoundIndicator + <com.android.inputmethod.deprecated.voice.SoundIndicator android:id="@+id/sound_indicator" android:src="@drawable/mic_full" android:background="@drawable/mic_base" @@ -81,7 +81,8 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:singleLine="true" - android:textSize="14sp" + android:textSize="15sp" + android:layout_marginTop="3dip" android:layout_marginBottom="3dip" android:layout_gravity="center" android:textColor="#ffffff" @@ -89,13 +90,13 @@ <Button android:id="@+id/button" android:layout_width="match_parent" - android:layout_height="54dip" + android:layout_height="30dip" 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" /> + android:textSize="15sp" /> </LinearLayout> </RelativeLayout> diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml index f4bc3cac9..45e87aada 100644 --- a/java/res/values-ar/strings.xml +++ b/java/res/values-ar/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"صوت عند الضغط على مفتاح"</string> <string name="popup_on_keypress" msgid="123894815723512944">"انبثاق عند الضغط على المفاتيح"</string> <string name="general_category" msgid="1859088467017573195">"عام"</string> - <string name="prediction_category" msgid="6361242011806282176">"تصحيح النص"</string> + <string name="correction_category" msgid="2236750915056607613">"تصحيح النص"</string> + <string name="ngram_category" msgid="5337109164339320257">"الاقتراحات بناءً على الكلمات السابقة"</string> + <string name="misc_category" msgid="6894192814868233453">"خيارات أخرى"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"استخدام الأحرف الكبيرة تلقائيًا"</string> <string name="quick_fixes" msgid="5353213327680897927">"إصلاحات سريعة"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"تصحيح الأخطاء المكتوبة الشائعة"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"عرض دومًا"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"عرض في وضع رأسي"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"إخفاء دومًا"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"استخدام مفتاح المسافة لتبديل اللغة"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"عرض مفتاح الإعدادات"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"تلقائي"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"إظهار بشكل دائم"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"إيقاف"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"معتدل"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"حاد"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"اقتراحات ثنائية"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"اقتراحات ثنائية"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"استخدام الكلمة السابقة لتحسين الاقتراح"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"التنبؤ الثنائي"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"استخدام الكلمة السابقة أيضًا للتنبؤ"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الحفظ"</string> <string name="label_go_key" msgid="1635148082137219148">"تنفيذ"</string> <string name="label_next_key" msgid="362972844525672568">"التالي"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"المزيد"</string> <string name="label_pause_key" msgid="181098308428035340">"توقف مؤقت"</string> <string name="label_wait_key" msgid="6402152600878093134">"انتظار"</string> - <string name="description_delete_key" msgid="5586406298531883960">"حذف"</string> - <string name="description_return_key" msgid="8750044000806461678">"رجوع"</string> - <string name="description_settings_key" msgid="7484527796782969219">"الإعدادات"</string> - <string name="description_shift_key" msgid="346906866277787836">"العالي"</string> - <string name="description_space_key" msgid="8512130111575878517">"مسافة"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"الرموز"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"الإدخال الصوتي"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"تشغيل الرموز"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"إيقاف الرموز"</string> - <string name="description_shift_on" msgid="6983188949895971587">"تشغيل العالي"</string> - <string name="description_shift_off" msgid="8553265474523069034">"إيقاف العالي"</string> <string name="voice_warning_title" msgid="4419354150908395008">"الإدخال الصوتي"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"الإدخال الصوتي غير معتمد حاليًا للغتك، ولكنه يعمل باللغة الإنجليزية."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"يستخدم الإدخال الصوتي خاصية التعرف على الكلام من Google. تنطبق "<a href="http://m.google.com/privacy">"سياسة خصوصية الجوال"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"المس الكلمات التي تم إدخالها لتصحيحها، وذلك فقط عندما تكون الاقتراحات مرئية."</string> <string name="keyboard_layout" msgid="437433231038683666">"مظهر لوحة المفاتيح"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"لوحة مفاتيح تشيكية"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"لوحة المفاتيح العربية"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"لوحة مفاتيح دانماركية"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"لوحة مفاتيح ألمانية"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"لوحة مفاتيح إنجليزية (بريطانيا)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"لوحة مفاتيح فرنسية"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"لوحة مفاتيح فرنسية (كندا)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"لوحة مفاتيح فرنسية (سويسرا)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"لوحة المفاتيح العبرية"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"لوحة مفاتيح إيطالية"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"لوحة مفاتيح نرويجية"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"لوحة مفاتيح بولندية"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"لوحة المفاتيح البولندية"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"لوحة مفاتيح روسية"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"لوحة مفاتيح صربية"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"لوحة مفاتيح سويدية"</string> diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml index 939fd75c8..585272621 100644 --- a/java/res/values-bg/strings.xml +++ b/java/res/values-bg/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натискане на клавиш"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Изскачащ прозорец при натискане на клавиш"</string> <string name="general_category" msgid="1859088467017573195">"Общи"</string> - <string name="prediction_category" msgid="6361242011806282176">"Корекция на текста"</string> + <string name="correction_category" msgid="2236750915056607613">"Корекция на текста"</string> + <string name="ngram_category" msgid="5337109164339320257">"Предложения въз основа на предишни думи"</string> + <string name="misc_category" msgid="6894192814868233453">"Други опции"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string> <string name="quick_fixes" msgid="5353213327680897927">"Бързи корекции"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Коригира най-честите грешки при въвеждане"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Винаги да се показва"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Показване с вертикална ориентация"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Винаги да се скрива"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Смяна на езика с клавиша за интервал"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Показване на клавиша за настройки"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматично"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Да се показва винаги"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Изкл."</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агресивно"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Предложения за биграми"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Предложения за биграми"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Използване на предишната дума за подобряване на предложението"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Предвиждане за биграми"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Използване на предишната дума и за предвиждане"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string> <string name="label_go_key" msgid="1635148082137219148">"Старт"</string> <string name="label_next_key" msgid="362972844525672568">"Напред"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Още"</string> <string name="label_pause_key" msgid="181098308428035340">"Пауза"</string> <string name="label_wait_key" msgid="6402152600878093134">"Чака"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Изтриване"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Настройки"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Интервал"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Символи"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Гласово въвеждане"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Символите са включени"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Символите са изключени"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift е включен"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift е изключен"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Гласово въвеждане"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"За вашия език понастоящем не се поддържа гласово въвеждане, но можете да го използвате на английски."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Гласовото въвеждане използва функцията на Google за разпознаване на говор. В сила е "<a href="http://m.google.com/privacy">"Декларацията за поверителност за мобилни устройства"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Докоснете въведените думи, за да ги поправите – само когато предложенията са видими"</string> <string name="keyboard_layout" msgid="437433231038683666">"Тема на клавиатурата"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"чешка клавиатура"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"клавиатура на арабски"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"датска клавиатура"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"немска клавиатура"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"английска (Великобрит.) клавиатура"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"френска клавиатура"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"френска (Канада) клавиатура"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"френска (Швейцария) клавиатура"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"клавиатура на иврит"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"италианска клавиатура"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"норвежка клавиатура"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"нидерландска клавиатура"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Полска клавиатура"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"руска клавиатура"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"сръбска клавиатура"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"шведска клавиатура"</string> diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml index f596a37af..4bd8f3895 100644 --- a/java/res/values-ca/strings.xml +++ b/java/res/values-ca/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"So en prémer una tecla"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Finestra emergent en prémer un botó"</string> <string name="general_category" msgid="1859088467017573195">"General"</string> - <string name="prediction_category" msgid="6361242011806282176">"Correcció de text"</string> + <string name="correction_category" msgid="2236750915056607613">"Correcció de text"</string> + <string name="ngram_category" msgid="5337109164339320257">"Suggeriments basats en paraules anteriors"</string> + <string name="misc_category" msgid="6894192814868233453">"Altres opcions"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</string> <string name="quick_fixes" msgid="5353213327680897927">"Correccions ràpides"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corregeix els errors d\'ortografia habituals"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostra sempre"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostra en mode vertical"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Amaga sempre"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Canvi d\'idioma amb la barra espaiadora"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Mostra la tecla de configuració"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automàtic"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostra sempre"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactiva"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Suggeriments Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Suggeriments Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilitza la paraula anterior per millorar el suggeriment"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Predicció Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilitza també la paraula anterior per a la predicció"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: desada"</string> <string name="label_go_key" msgid="1635148082137219148">"Vés"</string> <string name="label_next_key" msgid="362972844525672568">"Següent"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Més"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Espera"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Suprimeix"</string> - <string name="description_return_key" msgid="8750044000806461678">"Retorn"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Configuració"</string> - <string name="description_shift_key" msgid="346906866277787836">"Majúscules"</string> - <string name="description_space_key" msgid="8512130111575878517">"Espai"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbols"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulador"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Entrada de veu"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Símbols activats"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Símbols desactivats"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Majúscules activades"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Majúscules desactivades"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de veu"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualment, l\'entrada de veu no és compatible amb el vostre idioma, però funciona en anglès."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"L\'entrada de veu utilitza el reconeixement de veu de Google. S\'hi aplica la "<a href="http://m.google.com/privacy">"Política de privadesa de Google Mobile"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toca les paraules introduïdes per corregir-les, només quan els suggeriments siguin visibles"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema del teclat"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclat txec"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclat àrab"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclat danès"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclat alemany"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclat anglès (Regne Unit)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclat francès"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclat francès (Canadà)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclat francès (Suïssa)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclat hebreu"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclat italià"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclat noruec"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclat holandès"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclat polonès"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclat rus"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclat serbi"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclat suec"</string> diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml index a8091bb57..79e8abdff 100644 --- a/java/res/values-cs/strings.xml +++ b/java/res/values-cs/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk při stisku klávesy"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Zobrazit znaky při stisku klávesy"</string> <string name="general_category" msgid="1859088467017573195">"Obecné"</string> - <string name="prediction_category" msgid="6361242011806282176">"Oprava textu"</string> + <string name="correction_category" msgid="2236750915056607613">"Oprava textu"</string> + <string name="ngram_category" msgid="5337109164339320257">"Návrhy na základě předchozích slov"</string> + <string name="misc_category" msgid="6894192814868233453">"Další možnosti"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</string> <string name="quick_fixes" msgid="5353213327680897927">"Rychlé opravy"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje nejčastější chyby při psaní"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vždy zobrazovat"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Zobrazit v režimu na výšku"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vždy skrývat"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Přepínání jazyků mezerníkem"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Zobrazit klávesu Nastavení"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaticky"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vždy zobrazovat"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Vypnuto"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mírné"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivní"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Návrh Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Návrhy Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Použít předchozí slovo ke zlepšení návrhu"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Odhady Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Použít předchozí slovo také pro odhad"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Uloženo"</string> <string name="label_go_key" msgid="1635148082137219148">"Přejít"</string> <string name="label_next_key" msgid="362972844525672568">"Další"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Další"</string> <string name="label_pause_key" msgid="181098308428035340">"Pauza"</string> <string name="label_wait_key" msgid="6402152600878093134">"Čekat"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Smazat"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Nastavení"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"mezera"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboly"</string> - <string name="description_tab_key" msgid="828186583738307137">"Karta"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Hlasový vstup"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symboly jsou zapnuty"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symboly jsou vypnuty"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Režim Shift je zapnutý"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Režim Shift je vypnutý"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pro váš jazyk aktuálně není hlasový vstup podporován, ale funguje v angličtině."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Hlasový vstup používá rozpoznávání hlasu Google a vztahují se na něj "<a href="http://m.google.com/privacy">"Zásady ochrany osobních údajů pro mobilní služby"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Klepnutím na zadaná slova tato slova opravíte, musí však být viditelné návrhy."</string> <string name="keyboard_layout" msgid="437433231038683666">"Motiv klávesnice"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Klávesnice – čeština"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Klávesnice – arabština"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Klávesnice – dánština"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Klávesnice – němčina"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Klávesnice – angličtina (VB)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Klávesnice – francouzština"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Klávesnice – francouzština (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Klávesnice – francouzština (Švýc.)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Klávesnice – hebrejština"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Klávesnice – italština"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Klávesnice – norština"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Klávesnice – holandština"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polská klávesnice"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Klávesnice – ruština"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Klávesnice – srbština"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Klávesnice – švédština"</string> diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml index 5c23ccf5f..13ea6fa9e 100644 --- a/java/res/values-da/strings.xml +++ b/java/res/values-da/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetryk"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Popup ved tastetryk"</string> <string name="general_category" msgid="1859088467017573195">"Generelt"</string> - <string name="prediction_category" msgid="6361242011806282176">"Tekstkorrigering"</string> + <string name="correction_category" msgid="2236750915056607613">"Tekstkorrigering"</string> + <string name="ngram_category" msgid="5337109164339320257">"Forslag baseret på tidligere ord"</string> + <string name="misc_category" msgid="6894192814868233453">"Andre valgmuligheder"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string> <string name="quick_fixes" msgid="5353213327680897927">"Hurtige løsninger"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Retter almindelige stavefejl"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vis altid"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Vis i portrættilstand"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Skjul altid"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Brug mellemrumst. som sprogskifter"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Vis indstillingsnøgle"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisk"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vis altid"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Fra"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Beskeden"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-forslag"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-forslag"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Brug forrige ord for at forbedre forslag"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram-forudsigelse"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Brug også tidligere ord til forudsigelse"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string> <string name="label_go_key" msgid="1635148082137219148">"Gå"</string> <string name="label_next_key" msgid="362972844525672568">"Næste"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mere"</string> <string name="label_pause_key" msgid="181098308428035340">"Pause"</string> <string name="label_wait_key" msgid="6402152600878093134">"Vent"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Slet"</string> - <string name="description_return_key" msgid="8750044000806461678">"Tilbage"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Indstillinger"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Mellemrum"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboler"</string> - <string name="description_tab_key" msgid="828186583738307137">"Fane"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Stemmeinput"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symboler: Til"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symboler: Fra"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift: Til"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift: Fra"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Stemmeinput"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer på engelsk."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Stemmeinput anvender Googles stemmegenkendelse. "<a href="http://m.google.com/privacy">"Fortrolighedspolitikken for mobilenheder"</a>" gælder."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tryk på de indtastede ord for at rette dem. Kun når der er synlige forslag."</string> <string name="keyboard_layout" msgid="437433231038683666">"Tastaturtema"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tjekkisk tastatur"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabisk tastatur"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dansk tastatur"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tysk tastatur"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelsk tastatur (Storbritannien)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Fransk tastatur"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Fransk tastatur (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Fransk tastatur (Schweiz)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebraisk tastatur"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiensk tastatur"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norsk tastatur"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Hollandsk tastatur"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polsk tastatur"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russisk tastatur"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbisk tastatur"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svensk tastatur"</string> diff --git a/java/res/values-large/donottranslate.xml b/java/res/values-de/config.xml index 6d94c2811..272ff326f 100644 --- a/java/res/values-large/donottranslate.xml +++ b/java/res/values-de/config.xml @@ -17,7 +17,7 @@ ** limitations under the License. */ --> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Default value of the visibility of the suggestion strip --> - <string name="prefs_suggestion_visibility_default_value" translatable="false">1</string> + +<resources> + <bool name="config_require_umlaut_processing">true</bool> </resources> diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml index 23eeb5b91..b84c0fd5b 100644 --- a/java/res/values-de/strings.xml +++ b/java/res/values-de/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Ton bei Tastendruck"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bei Tastendruck"</string> <string name="general_category" msgid="1859088467017573195">"Allgemein"</string> - <string name="prediction_category" msgid="6361242011806282176">"Textkorrektur"</string> + <string name="correction_category" msgid="2236750915056607613">"Textkorrektur"</string> + <string name="ngram_category" msgid="5337109164339320257">"Vorschläge basieren auf bisherigen Wörtern"</string> + <string name="misc_category" msgid="6894192814868233453">"Sonstige Optionen"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschr."</string> <string name="quick_fixes" msgid="5353213327680897927">"Quick Fixes"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Korrigiert gängige Tippfehler"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Immer anzeigen"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Im Hochformat anzeigen"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Immer ausblenden"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Sprache mit Leertaste ändern"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Einstellungstaste anz."</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisch"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Immer anzeigen"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Aus"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mäßig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Stark"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramm-Vorschläge"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramm-Vorschläge"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Zur Verbesserung des Vorschlags vorheriges Wort verwenden"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigramm-Vervollständigung"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Vorheriges Wort auch für Vervollständigung verwenden"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: gespeichert"</string> <string name="label_go_key" msgid="1635148082137219148">"Los"</string> <string name="label_next_key" msgid="362972844525672568">"Weiter"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mehr"</string> <string name="label_pause_key" msgid="181098308428035340">"Pause"</string> <string name="label_wait_key" msgid="6402152600878093134">"Warten"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Löschen"</string> - <string name="description_return_key" msgid="8750044000806461678">"Eingabe"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Einstellungen"</string> - <string name="description_shift_key" msgid="346906866277787836">"Umschalt"</string> - <string name="description_space_key" msgid="8512130111575878517">"Leerzeichen"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbole"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Spracheingabe"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symbole an"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symbole aus"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Umschalt an"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Umschalt aus"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Spracheingabe"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spracheingaben werden derzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Die Spracheingabe verwendet die Spracherkennung von Google. Es gelten die "<a href="http://m.google.com/privacy">"Google Mobile-Datenschutzbestimmungen"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tippen Sie zum Korrigieren auf eingegebene Wörter (nur, wenn Vorschläge angezeigt werden)."</string> <string name="keyboard_layout" msgid="437433231038683666">"Tastaturdesign"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tschechische Tastatur"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabische Tastatur"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dänische Tastatur"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Deutsche Tastatur"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Englische Tastatur (GB)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Französische Tastatur"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Französische Tastatur (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Französische Tastatur (Schweiz)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebräische Tastatur"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italienische Tastatur"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norwegische Tastatur"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Niederländische Tastatur"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polnische Tastatur"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russische Tastatur"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbische Tastatur"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Schwedische Tastatur"</string> diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml index 355d7a3c6..c1c4bc98d 100644 --- a/java/res/values-el/strings.xml +++ b/java/res/values-el/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Ήχος κατά το πάτημα πλήκτρων"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Εμφάνιση με το πάτημα πλήκτρου"</string> <string name="general_category" msgid="1859088467017573195">"Γενικά"</string> - <string name="prediction_category" msgid="6361242011806282176">"Διόρθωση κειμένου"</string> + <string name="correction_category" msgid="2236750915056607613">"Διόρθωση κειμένου"</string> + <string name="ngram_category" msgid="5337109164339320257">"Προτάσεις που βασίζονται σε προηγούμενες λέξεις"</string> + <string name="misc_category" msgid="6894192814868233453">"Άλλες επιλογές"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string> <string name="quick_fixes" msgid="5353213327680897927">"Γρήγορες διορθώσεις"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Διορθώνει συνηθισμένα λάθη πληκτρολόγησης"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Να εμφανίζεται πάντα"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Εμφάνιση σε λειτουργία κατακόρυφης προβολής"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Πάντα απόκρυψη"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Χρησιμοποιήστε τη δυνατότητα εναλλαγής γλώσσας του πλήκτρου διαστήματος"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Εμφάνιση πλήκτρου ρυθμίσεων"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Αυτόματο"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Να εμφανίζεται πάντα"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Απενεργοποίηση"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Μέτρια"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Υψηλή"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Προτάσεις bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Προτάσεις bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Χρήση προηγούμενης λέξης για τη βελτίωση πρότασης"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Πρόβλεψη bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Χρησιμοποιήστε, επίσης, την προηγούμενη λέξη για πρόβλεψη"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Αποθηκεύτηκε"</string> <string name="label_go_key" msgid="1635148082137219148">"Μετ."</string> <string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Περισσότερα"</string> <string name="label_pause_key" msgid="181098308428035340">"Παύση"</string> <string name="label_wait_key" msgid="6402152600878093134">"Αναμ."</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Ρυθμίσεις"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Κενό"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Σύμβολα"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Φωνητική εντολή"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Σύμβολα ενεργά"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Σύμβολα ανενεργά"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift ενεργό"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift ανενεργό"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Φωνητική είσοδος"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Οι φωνητικές εντολές χρησιμοποιούν την τεχνολογία αναγνώρισης φωνής της Google. Ισχύει "<a href="http://m.google.com/privacy">"η Πολιτική Απορρήτου για κινητά"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Αγγίξτε τις λέξες για να τις διορθώσετε, μόνο όταν οι προτάσεις είναι ορατές"</string> <string name="keyboard_layout" msgid="437433231038683666">"Θέμα πληκτρολογίου"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Τσεχικό πληκτρολόγιο"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Πληκτρολόγιο με αραβική γραφή"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Δανικό πληκτρολόγιο"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Γερμανικό πληκτρολόγιο"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Αγγλικό (ΗΒ) πληκτρολόγιο"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Γαλλικό πληκτρολόγιο"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Γαλλικό (Καναδάς) πληκτρολόγιο"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Γαλλικό (Ελβετία) πληκτρολόγιο"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Πληκτρολόγιο με εβραϊκή γραφή"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Ιταλικό πληκτρολόγιο"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Νορβηγικό πληκτρολόγιο"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Ολλανδικό πληκτρολόγιο"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Πληκτρολόγιο με πολωνικούς χαρακτήρες"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ρωσικό πληκτρολόγιο"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Σερβικό πληκτρολόγιο"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Σουηδικό πληκτρολόγιο"</string> diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml index 89a6a2e78..3aa37c975 100644 --- a/java/res/values-en-rGB/strings.xml +++ b/java/res/values-en-rGB/strings.xml @@ -27,7 +27,14 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Sound on key-press"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up on key press"</string> <string name="general_category" msgid="1859088467017573195">"General"</string> - <string name="prediction_category" msgid="6361242011806282176">"Text correction"</string> + <string name="correction_category" msgid="2236750915056607613">"Text correction"</string> + <string name="ngram_category" msgid="5337109164339320257">"Suggestions based on previous words"</string> + <string name="misc_category" msgid="6894192814868233453">"Other Options"</string> + <string name="advanced_settings" msgid="362895144495591463">"Advanced settings"</string> + <string name="advanced_settings_summary" msgid="5193513161106637254">"Options for expert users"</string> + <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Key pop-up dismiss delay"</string> + <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"No delay"</string> + <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string> <string name="quick_fixes" msgid="5353213327680897927">"Quick fixes"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrects commonly typed mistakes"</string> @@ -36,6 +43,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Always show"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Show on portrait mode"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Always hide"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Use the spacebar language switcher"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Show settings key"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatic"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Always show"</string> @@ -45,8 +53,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Off"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressive"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram Suggestions"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram Suggestions"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Use previous word to improve suggestion"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram prediction"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use previous word also for prediction"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string> <string name="label_go_key" msgid="1635148082137219148">"Go"</string> <string name="label_next_key" msgid="362972844525672568">"Next"</string> @@ -56,18 +66,6 @@ <string name="label_more_key" msgid="3760239494604948502">"More"</string> <string name="label_pause_key" msgid="181098308428035340">"Pause"</string> <string name="label_wait_key" msgid="6402152600878093134">"Wait"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Settings"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Space"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbols"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Voice Input"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symbols on"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symbols off"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift on"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift off"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Voice input"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Voice input is not currently supported for your language, but does work in English."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Voice input uses Google\'s speech recognition. "<a href="http://m.google.com/privacy">"The Mobile Privacy Policy"</a>" applies."</string> @@ -106,6 +104,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Touch words entered to correct them, only when suggestions are visible"</string> <string name="keyboard_layout" msgid="437433231038683666">"Keyboard Theme"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Czech Keyboard"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabic Keyboard"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danish Keyboard"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"German Keyboard"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"English (UK) Keyboard"</string> @@ -114,9 +113,12 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"French Keyboard"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"French (Canada) Keyboard"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"French (Switzerland) Keyboard"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrew Keyboard"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italian Keyboard"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norwegian Keyboard"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Dutch Keyboard"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polish keyboard"</string> + <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portuguese Keyboard"</string> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russian Keyboard"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbian Keyboard"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Swedish Keyboard"</string> diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml index 9a45219b0..07b55c309 100644 --- a/java/res/values-es-rUS/strings.xml +++ b/java/res/values-es-rUS/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Sonar al pulsar las teclas"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Aviso emergente al pulsar tecla"</string> <string name="general_category" msgid="1859088467017573195">"General"</string> - <string name="prediction_category" msgid="6361242011806282176">"Corrección de texto"</string> + <string name="correction_category" msgid="2236750915056607613">"Corrección de texto"</string> + <string name="ngram_category" msgid="5337109164339320257">"Sugerencias sobre la base de palabras anteriores"</string> + <string name="misc_category" msgid="6894192814868233453">"Otras opciones"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string> <string name="quick_fixes" msgid="5353213327680897927">"Arreglos rápidos"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige errores de escritura comunes"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar siempre"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar en modo retrato"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar siempre"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Usa select. de id. de barra espac."</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de configuración"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar siempre"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactivado"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Sugerencias de Vigoran"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Sugerencias de bigramas"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utiliza la palabra anterior para mejorar la sugerencia"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Predicción de biagramas"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usar la palabra anterior también para predicción."</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Siguiente"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Más"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Espera"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Eliminar"</string> - <string name="description_return_key" msgid="8750044000806461678">"Volver"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Configuración"</string> - <string name="description_shift_key" msgid="346906866277787836">"Mayús"</string> - <string name="description_space_key" msgid="8512130111575878517">"Espacio"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Entrada de voz"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos activados"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desactivados"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Mayús activado"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Mayús desactivado"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Entrada por voz"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La entrada por voz no está admitida en tu idioma, pero sí funciona en inglés."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La entrada de voz usa el reconocimiento de voz de Google. "<a href="http://m.google.com/privacy">"Se aplica la política de privacidad para"</a>" celulares."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toca las palabras ingresadas que desees corregir solo cuando las sugerencias estén visibles."</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema del teclado"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado en checo"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado en danés"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado en alemán"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado en inglés (Reino Unido)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado en francés"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado en francés (Canadá)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado en francés (Suiza)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebreo"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado en italiano"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado en noruego"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado en holandés"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado polaco"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado en ruso"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado en serbio"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado en sueco"</string> diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml index 1e72a0c37..f72c49c63 100644 --- a/java/res/values-es/strings.xml +++ b/java/res/values-es/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Sonido al pulsar tecla"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Popup al pulsar tecla"</string> <string name="general_category" msgid="1859088467017573195">"General"</string> - <string name="prediction_category" msgid="6361242011806282176">"Corrección ortográfica"</string> + <string name="correction_category" msgid="2236750915056607613">"Corrección ortográfica"</string> + <string name="ngram_category" msgid="5337109164339320257">"Sugerencias basadas en palabras anteriores"</string> + <string name="misc_category" msgid="6894192814868233453">"Otras opciones"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string> <string name="quick_fixes" msgid="5353213327680897927">"Correcciones rápidas"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige los errores tipográficos que se cometen con más frecuencia."</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar siempre"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar en modo vertical"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar siempre"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Utilizar espacio para cambiar idioma"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de ajustes"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automáticamente"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar siempre"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactivada"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Parcial"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Sugerencias de bigramas"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Sugerencias de bigramas"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palabra anterior para mejorar sugerencias"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Predicción de bigramas"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar también la palabra anterior para realizar la predicción"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Sig."</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Más"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Espera"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Eliminar"</string> - <string name="description_return_key" msgid="8750044000806461678">"Retroceso"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Ajustes"</string> - <string name="description_shift_key" msgid="346906866277787836">"Mayús"</string> - <string name="description_space_key" msgid="8512130111575878517">"Espacio"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulador"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Entrada de voz"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos activados"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desactivados"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Mayús activadas"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Mayús desactivadas"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Introducción de voz"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La entrada de voz utiliza el reconocimiento de voz de Google. Se aplica la "<a href="http://m.google.com/privacy">"Política de privacidad de Google para móviles"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toca las palabras introducidas para corregirlas, solo cuando las sugerencias sean visibles."</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema de teclado"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado checo"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado danés"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado alemán"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado inglés (Reino Unido)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado francés"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado francés (Canadá)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado francés (Suiza)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebreo"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado italiano"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado noruego"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado holandés"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado polaco"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado ruso"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado serbio"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado sueco"</string> diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml index ceeee52d9..10a119606 100644 --- a/java/res/values-fa/strings.xml +++ b/java/res/values-fa/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"صدا با فشار کلید"</string> <string name="popup_on_keypress" msgid="123894815723512944">"بازشو با فشار کلید"</string> <string name="general_category" msgid="1859088467017573195">"کلی"</string> - <string name="prediction_category" msgid="6361242011806282176">"تصحیح متن"</string> + <string name="correction_category" msgid="2236750915056607613">"تصحیح متن"</string> + <string name="ngram_category" msgid="5337109164339320257">"پیشنهادهایی بر اساس کلمه های قبلی"</string> + <string name="misc_category" msgid="6894192814868233453">"سایر گزینه ها"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"نوشتن با حروف بزرگ خودکار"</string> <string name="quick_fixes" msgid="5353213327680897927">"راه حل های سریع"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"تصحیح خطاهای تایپی رایج"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"همیشه نمایش داده شود"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"نمایش در حالت عمودی"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"همیشه پنهان شود"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"از ویژگی تعویض زبان کلید فاصله استفاده شود"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"نمایش کلید تنظیمات"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"خودکار"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"همیشه نمایش"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"خاموش"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"متوسط"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"فعال"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"توضیحات بیگرام"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"پیشنهادهای Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"برای بهبود پیشنهاد از کلمه قبلی استفاده شود"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"پیش بینی Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"استفاده از کلمه قبلی برای پیش بینی"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string> <string name="label_go_key" msgid="1635148082137219148">"برو"</string> <string name="label_next_key" msgid="362972844525672568">"بعدی"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"بیشتر"</string> <string name="label_pause_key" msgid="181098308428035340">"توقف موقت"</string> <string name="label_wait_key" msgid="6402152600878093134">"منتظر بمانید"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"تنظیمات"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"فاصله"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"نمادها"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"ورودی صوتی"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"نمادها روشن"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"نمادها خاموش"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift روشن"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift خاموش"</string> <string name="voice_warning_title" msgid="4419354150908395008">"ورودی صوتی"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ورودی صوتی در حال حاضر برای زبان شما پشتیبانی نمی شود اما برای زبان انگلیسی فعال است."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ورودی صوتی از تشخیص صدای Google استفاده می کند. "<a href="http://m.google.com/privacy">"خط مشی رازداری Mobile "</a>" اعمال می شود."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"فقط هنگامی که پیشنهادات قابل مشاهده هستند، برای تصحیح کلمات وارد شده آنها را لمس کنید"</string> <string name="keyboard_layout" msgid="437433231038683666">"طرح زمینه صفحه کلید"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"صفحه کلید چک"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"صفحه کلید عربی"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"صفحه کلید دانمارکی"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"صفحه کلید آلمانی"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"صفحه کلید انگلیسی (بریتانیایی)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"صفحه کلید فرانسوی"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"صفحه کلید فرانسوی (کانادایی)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"صفحه کلید فرانسوی (سوئیس)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"صفحه کلید عبری"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"صفحه کلید ایتالیایی"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"صفحه کلید نروژی"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"صفحه کلید هلندی"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"صفحه کلید لهستانی"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"صفحه کلید روسی"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"صفحه کلید صربی"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"صفحه کلید سوئدی"</string> diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml index ee49c998f..0e7e7d15e 100644 --- a/java/res/values-fi/strings.xml +++ b/java/res/values-fi/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Toista ääni näppäimiä painettaessa"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Ponnahdusikkuna painalluksella"</string> <string name="general_category" msgid="1859088467017573195">"Yleinen"</string> - <string name="prediction_category" msgid="6361242011806282176">"Tekstin korjaus"</string> + <string name="correction_category" msgid="2236750915056607613">"Tekstin korjaus"</string> + <string name="ngram_category" msgid="5337109164339320257">"Aiempiin sanoihin perustuvat ehdotukset"</string> + <string name="misc_category" msgid="6894192814868233453">"Muut vaihtoehdot"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string> <string name="quick_fixes" msgid="5353213327680897927">"Pikakorjaukset"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Korjaa yleiset kirjoitusvirheet"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Näytä aina"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Näytä pystysuunnassa"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Piilota aina"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Vaihda kieli välil."</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Näytä asetukset-näppäin"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaattinen"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Näytä aina"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Älä käytä"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Osittainen"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Täysi"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-ehdotukset"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-ehdotukset"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Paranna ehdotusta aiemman sanan avulla"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram-ennakointi"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Käytä edellistä sanaa myös ennakointiin"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Tallennettu"</string> <string name="label_go_key" msgid="1635148082137219148">"Siirry"</string> <string name="label_next_key" msgid="362972844525672568">"Seuraava"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Lisää"</string> <string name="label_pause_key" msgid="181098308428035340">"Tauko"</string> <string name="label_wait_key" msgid="6402152600878093134">"Odota"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Poista"</string> - <string name="description_return_key" msgid="8750044000806461678">"Rivinvaihto"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Asetukset"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Välilyönti"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbolit"</string> - <string name="description_tab_key" msgid="828186583738307137">"Sarkain"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Äänisyöte"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symbolit käytössä"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symbolit pois käytöstä"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift käytössä"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift pois käytöstä"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Äänisyöte"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Äänisyötettä ei vielä tueta kielelläsi, mutta voit käyttää sitä englanniksi."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Äänisyöte käyttää Googlen puheentunnistusta. "<a href="http://m.google.com/privacy">"Mobile-tietosuojakäytäntö"</a>" on voimassa."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Korjaa annetut sanat napauttamalla. (Vain, kun ehdotuksia on näkyvillä.)"</string> <string name="keyboard_layout" msgid="437433231038683666">"Näppäimistön teema"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Näppäimistö: tšekki"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabiankielinen näppäimistö"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Näppäimistö: tanska"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Näppäimistö: saksa"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Näppäimistö: englanti (UK)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Näppäimistö: ranska"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Näppäimistö: ranska (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Näppäimistö: ranska (Sveitsi)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hepreankielinen näppäimistö"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Näppäimistö: italia"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Näppäimistö: norja"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Näppäimistö: hollanti"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Näppäimistö: puola"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Näppäimistö: venäjä"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Näppäimistö: serbia"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Näppäimistö: ruotsi"</string> diff --git a/java/res/values-fr/donottranslate-altchars.xml b/java/res/values-fr/donottranslate-altchars.xml index e01f63f14..ae9292f91 100644 --- a/java/res/values-fr/donottranslate-altchars.xml +++ b/java/res/values-fr/donottranslate-altchars.xml @@ -18,11 +18,11 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="alternates_for_a">1,à,â,æ,á,ä,ã,å,ā,ª</string> - <string name="alternates_for_e">3,é,è,ê,ë,ę,ė,ē</string> - <string name="alternates_for_i">8,î,ï,ì,í,į,ī</string> - <string name="alternates_for_o">9,ô,œ,ö,ò,ó,õ,ø,ō,º</string> - <string name="alternates_for_u">7,û,ù,ü,ú,ū</string> + <string name="alternates_for_a">à,â,1,æ,á,ä,ã,å,ā,ª</string> + <string name="alternates_for_e">é,è,ê,ë,3,ę,ė,ē</string> + <string name="alternates_for_i">î,8,ï,ì,í,į,ī</string> + <string name="alternates_for_o">ô,œ,9,ö,ò,ó,õ,ø,ō,º</string> + <string name="alternates_for_u">ù,û,7,ü,ú,ū</string> <string name="alternates_for_c">ç,ć,č</string> <string name="alternates_for_y">6,ÿ</string> <string name="alternates_for_q"></string> diff --git a/java/res/values-fr/donottranslate.xml b/java/res/values-fr/donottranslate.xml index 6c3536210..09c37e31a 100644 --- a/java/res/values-fr/donottranslate.xml +++ b/java/res/values-fr/donottranslate.xml @@ -18,8 +18,12 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Symbols that are commonly considered word separators in this language --> - <string name="word_separators">.\u0009\u0020,;:!?\n()[]*&@{}/<>_+=|\u0022</string> - <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. --> - <string name="sentence_separators">.,</string> + <!-- Symbols that should be swapped with a magic space --> + <string name="magic_space_swapping_symbols">.,\u0022)]}</string> + <!-- Symbols that should strip a magic space --> + <string name="magic_space_stripping_symbols">\u0009\u0020\u0027\n-/_</string> + <!-- Symbols that should promote magic spaces into real space --> + <string name="magic_space_promoting_symbols">;:!?([*&@{<>+=|</string> + <!-- Symbols that do NOT separate words --> + <string name="non_word_separator_symbols">\u0027</string> </resources> diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml index 59a1387cf..377cfe539 100644 --- a/java/res/values-fr/strings.xml +++ b/java/res/values-fr/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Son à chaque touche"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Agrandir les caractères"</string> <string name="general_category" msgid="1859088467017573195">"Général"</string> - <string name="prediction_category" msgid="6361242011806282176">"Correction du texte"</string> + <string name="correction_category" msgid="2236750915056607613">"Correction du texte"</string> + <string name="ngram_category" msgid="5337109164339320257">"Suggestions basées sur les mots précédents"</string> + <string name="misc_category" msgid="6894192814868233453">"Autres options"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string> <string name="quick_fixes" msgid="5353213327680897927">"Corrections rapides"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige les fautes de frappe courantes"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Toujours afficher"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Afficher en mode Portrait"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Toujours masquer"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Barre d\'espace pour changer langue"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Afficher touche param."</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatique"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Toujours afficher"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Désactiver"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Simple"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Proactive"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Suggestions de type bigramme"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Suggestions de type bigramme"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Améliorer la suggestion en fonction du mot précédent"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Prédiction bigramme"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utiliser le mot précédent pour la prédiction"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"Suivant"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Plus"</string> <string name="label_pause_key" msgid="181098308428035340">"Pause"</string> <string name="label_wait_key" msgid="6402152600878093134">"Attente"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Supprimer"</string> - <string name="description_return_key" msgid="8750044000806461678">"Entrée"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Paramètres"</string> - <string name="description_shift_key" msgid="346906866277787836">"Maj"</string> - <string name="description_space_key" msgid="8512130111575878517">"Espace"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboles"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulation"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Saisie vocale"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symboles activés"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symboles désactivés"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Maj activée"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Maj désactivée"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Saisie vocale"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La saisie vocale fait appel à la reconnaissance vocale de Google. Les "<a href="http://m.google.com/privacy">"Règles de confidentialité Google Mobile"</a>" s\'appliquent."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Appuyer sur les mots saisis pour les corriger, uniquement lorsque des suggestions sont visibles"</string> <string name="keyboard_layout" msgid="437433231038683666">"Thème du clavier"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Clavier tchèque"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Clavier arabe"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Clavier danois"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Clavier allemand"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Clavier anglais (Royaume-Uni)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Clavier français"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Clavier français (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Clavier français (Suisse)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Clavier hébreu"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Clavier italien"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Clavier norvégien"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Clavier néerlandais"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Clavier polonais"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Clavier russe"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Clavier serbe"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Clavier suédois"</string> diff --git a/java/res/xml-large-land/kbd_popup_template.xml b/java/res/values-hdpi/config.xml index 2c1d1902e..7333e9449 100644 --- a/java/res/xml-large-land/kbd_popup_template.xml +++ b/java/res/values-hdpi/config.xml @@ -18,10 +18,7 @@ */ --> -<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyWidth="5%p" - latin:horizontalGap="0px" - latin:verticalGap="0px" - latin:rowHeight="@dimen/popup_key_height" - > -</Keyboard> +<resources> + <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" --> + <integer name="log_screen_metrics">1</integer> +</resources> diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml index 34476d4c6..82bfb1447 100644 --- a/java/res/values-hr/strings.xml +++ b/java/res/values-hr/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk pri pritisku tipke"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Povećanja na pritisak tipke"</string> <string name="general_category" msgid="1859088467017573195">"Općenito"</string> - <string name="prediction_category" msgid="6361242011806282176">"Ispravak teksta"</string> + <string name="correction_category" msgid="2236750915056607613">"Ispravak teksta"</string> + <string name="ngram_category" msgid="5337109164339320257">"Prijedlozi na temelju prethodnih riječi"</string> + <string name="misc_category" msgid="6894192814868233453">"Ostale opcije"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string> <string name="quick_fixes" msgid="5353213327680897927">"Brzi popravci"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Ispravlja uobičajene pogreške u pisanju"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Uvijek prikaži"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Prikaži u portretnom načinu"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Uvijek sakrij"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Upotrijebite razmaknicu za prebacivanje jezika"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Prikaži tipku postavki"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatski"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Uvijek prikaži"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Isključeno"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Skromno"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivno"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram prijedlozi"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram prijedlozi"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Upotrijebi prethodnu riječ radi poboljšanja prijedloga"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram predviđanje"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Upotrijebite prethodnu riječ i za predviđanje"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Spremljeno"</string> <string name="label_go_key" msgid="1635148082137219148">"Idi"</string> <string name="label_next_key" msgid="362972844525672568">"Dalje"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Više"</string> <string name="label_pause_key" msgid="181098308428035340">"Pauza"</string> <string name="label_wait_key" msgid="6402152600878093134">"Pričekaj"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Postavke"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Razmaknica"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboli"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulator"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Glasovni unos"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simboli uključeni"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simboli isključeni"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift uključen"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift isključen"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Glasovni unos"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Vaš jezik trenutno nije podržan za glasovni unos, ali radi za engleski."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Glasovni unos upotrebljava Googleovo prepoznavanje govora. Primjenjuju se "<a href="http://m.google.com/privacy">"Pravila o privatnosti za uslugu Mobile"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dodirnite unesene riječi da biste ih ispravili samo kada su prijedlozi vidljivi"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema tipkovnice"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Češka tipkovnica"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arapska tipkovnica"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danska tipkovnica"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Njemačka tipkovnica"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engleska (UK) tipkovnica"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Francuska tipkovnica"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Francuska (Kanada) tipkovnica"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Francuska (Švicarska) tipkovnica"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrejska tipkovnica"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Talijanska tipkovnica"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norveška tipkovnica"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nizozemska tipkovnica"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poljska tipkovnica"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ruska tipkovnica"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Srpska tipkovnica"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Švedska tipkovnica"</string> diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml index 923103bce..1740540fe 100644 --- a/java/res/values-hu/strings.xml +++ b/java/res/values-hu/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Hangjelzés billentyű megnyomása esetén"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Legyen nagyobb billentyű lenyomásakor"</string> <string name="general_category" msgid="1859088467017573195">"Általános"</string> - <string name="prediction_category" msgid="6361242011806282176">"Szövegjavítás"</string> + <string name="correction_category" msgid="2236750915056607613">"Szövegjavítás"</string> + <string name="ngram_category" msgid="5337109164339320257">"Javaslatok korábbi szavak alapján"</string> + <string name="misc_category" msgid="6894192814868233453">"Egyéb beállítások"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</string> <string name="quick_fixes" msgid="5353213327680897927">"Gyorsjavítások"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Kijavítja a gyakori gépelési hibákat"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mindig látszik"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Megjelenítés álló tájolásban"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Mindig rejtve"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Nyelvváltó: szóköz"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Beállítások billentyű megjelenítése"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatikus"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mindig látszik"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Ki"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mérsékelt"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresszív"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram javaslatok"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram javaslatok"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Előző szó használata a javaslatok javításához"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram előrejelzés"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Az előző szó használata a prediktív bevitelhez is"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : mentve"</string> <string name="label_go_key" msgid="1635148082137219148">"Ugrás"</string> <string name="label_next_key" msgid="362972844525672568">"Tovább"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Egyebek"</string> <string name="label_pause_key" msgid="181098308428035340">"Szün."</string> <string name="label_wait_key" msgid="6402152600878093134">"Vár"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Törlés"</string> - <string name="description_return_key" msgid="8750044000806461678">"Vissza"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Beállítások"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Szóköz"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Szimbólumok"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Hangbevitel"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Szimbólumok be"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Szimbólumok ki"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift be"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift ki"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Hangbevitel"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A hangbevitel szolgáltatás jelenleg nem támogatja az Ön nyelvét, ám angolul működik."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A hangbevitel a Google beszédfelismerő technológiáját használja, amelyre a "<a href="http://m.google.com/privacy">"Mobil adatvédelmi irányelvek"</a>" érvényesek."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"A beírt szavakat csak akkor javíthatja ki megérintve, ha látszanak javaslatok"</string> <string name="keyboard_layout" msgid="437433231038683666">"Billentyűzettéma"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Cseh billentyűzet"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arab billentyűzet"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dán billentyűzet"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Német billentyűzet"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Angol (UK) billentyűzet"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Francia billentyűzet"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Francia (kanadai) billentyűzet"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Francia (svájci) billentyűzet"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Héber billentyűzet"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Olasz billentyűzet"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norvég billentyűzet"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Holland billentyűzet"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Lengyel billentyűzet"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Orosz billentyűzet"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Szerb billentyűzet"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svéd billentyűzet"</string> diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml index 3322109c4..c37d8d565 100644 --- a/java/res/values-in/strings.xml +++ b/java/res/values-in/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Berbunyi jika tombol ditekan"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Muncul saat tombol ditekan"</string> <string name="general_category" msgid="1859088467017573195">"Umum"</string> - <string name="prediction_category" msgid="6361242011806282176">"Koreksi teks"</string> + <string name="correction_category" msgid="2236750915056607613">"Koreksi teks"</string> + <string name="ngram_category" msgid="5337109164339320257">"Saran berdasarkan kata sebelumnya"</string> + <string name="misc_category" msgid="6894192814868233453">"Opsi lain"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string> <string name="quick_fixes" msgid="5353213327680897927">"Perbaikan cepat"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Memperbaiki kesalahan ketik umum"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Selalu tampilkan"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Tampilkan pada mode potret"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Selalu sembunyikan"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Gunakan pengalih bahasa bilah spasi"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Lihat tombol setelan"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Otomatis"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Selalu tampilkan"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Mati"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Saran Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Saran bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gunakan kata sebelumnya untuk meningkatkan sara"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Prediksi bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan kata sebelumnya juga untuk prediksi"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Telah disimpan"</string> <string name="label_go_key" msgid="1635148082137219148">"Buka"</string> <string name="label_next_key" msgid="362972844525672568">"Berikutnya"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Lainnya"</string> <string name="label_pause_key" msgid="181098308428035340">"Jeda"</string> <string name="label_wait_key" msgid="6402152600878093134">"Tunggu"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Hapus"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Setelan"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Spasi"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simbol"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Masukan Suara"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simbol hidup"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simbol mati"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift hidup"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift mati"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Masukan suara"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Masukan suara saat ini tidak didukung untuk bahasa Anda, tetapi bekerja dalam Bahasa Inggris."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Masukan suara menggunakan pengenalan ucapan Google. "<a href="http://m.google.com/privacy">"Kebijakan Privasi Seluler"</a>" berlaku."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Sentuh kata yang dimasukkan untuk memperbaikinya, hanya saat saran dapat dilihat"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema Keyboard"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Keyboard Cheska"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Papan Tombol Arab"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Keyboard Denmark"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Keyboard Jerman"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Keyboard Inggris (Britania Raya)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Keyboard Prancis"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Keyboard Prancis (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Keyboard Prancis (Swiss)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Papan tombol Ibrani"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Keyboard Italia"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Keyboard Norwegia"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Keyboard Belanda"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Keyboard bahasa Polski"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Keyboard Rusia"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Keyboard Serbia"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Keyboard Swedia"</string> diff --git a/java/res/values-it/donottranslate.xml b/java/res/values-it/donottranslate.xml index 3e3f3ef2a..adb2a9a9d 100644 --- a/java/res/values-it/donottranslate.xml +++ b/java/res/values-it/donottranslate.xml @@ -18,6 +18,6 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Symbols that are commonly considered word separators in this language --> - <string name="word_separators">.\u0009\u0020,;:!?\'\n()[]*&@{}/<>_+=|\u0022</string> + <!-- Symbols that do NOT separate words --> + <string name="non_word_separator_symbols"></string> </resources> diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml index 337a04e07..6f05d6f75 100644 --- a/java/res/values-it/strings.xml +++ b/java/res/values-it/strings.xml @@ -27,7 +27,14 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Suono tasti"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Popup sui tasti"</string> <string name="general_category" msgid="1859088467017573195">"Generali"</string> - <string name="prediction_category" msgid="6361242011806282176">"Correzione testo"</string> + <string name="correction_category" msgid="2236750915056607613">"Correzione testo"</string> + <string name="ngram_category" msgid="5337109164339320257">"Suggerimenti in base alle parole precedenti"</string> + <string name="misc_category" msgid="6894192814868233453">"Altre opzioni"</string> + <string name="advanced_settings" msgid="362895144495591463">"Impostazioni avanzate"</string> + <string name="advanced_settings_summary" msgid="5193513161106637254">"Opzioni per utenti esperti"</string> + <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Ritardo eliminaz. popup chiave"</string> + <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Nessun ritardo"</string> + <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinito"</string> <string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string> <string name="quick_fixes" msgid="5353213327680897927">"Correzioni veloci"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corregge gli errori di digitazione più comuni"</string> @@ -36,6 +43,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostra sempre"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostra in modalità verticale"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Nascondi sempre"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Selettore lingua da barra spaziatrice"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Mostra tasto impostaz."</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatico"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostra sempre"</string> @@ -45,8 +53,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Off"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Media"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Massima"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Suggerimenti sui bigrammi"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Suggerimenti sui bigrammi"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizza parola precedente per migliorare il suggerimento"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Previsione bigramma"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usa anche la parola precedente per la previsione"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string> <string name="label_go_key" msgid="1635148082137219148">"Vai"</string> <string name="label_next_key" msgid="362972844525672568">"Avanti"</string> @@ -56,18 +66,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Altro"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Attesa"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Cancella"</string> - <string name="description_return_key" msgid="8750044000806461678">"Invio"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Impostazioni"</string> - <string name="description_shift_key" msgid="346906866277787836">"Maiuscolo"</string> - <string name="description_space_key" msgid="8512130111575878517">"Spazio"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboli"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulazione"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Input vocale"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simboli attivati"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simboli disattivati"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Maiuscole attivate"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Maiuscole disattivate"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Comandi vocali"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"L\'input vocale utilizza il riconoscimento vocale di Google. Sono valide le "<a href="http://m.google.com/privacy">"norme sulla privacy di Google Mobile"</a>"."</string> @@ -106,6 +104,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tocca le parole inserite per correggerle, solo quando sono visibili i suggerimenti"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema della tastiera"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tastiera ceca"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Tastiera araba"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Tastiera danese"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tastiera tedesca"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Tastiera inglese (Regno Unito)"</string> @@ -114,9 +113,12 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Tastiera francese"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Tastiera francese (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Tastiera francese (Svizzera)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Tastiera ebraica"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Tastiera italiana"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Tastiera norvegese"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Tastiera olandese"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Tastiera polacca"</string> + <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Tastiera portoghese"</string> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Tastiera russa"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Tastiera serba"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Tastiera svedese"</string> diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml index e71ab56c3..25f5c0aa2 100644 --- a/java/res/values-iw/strings.xml +++ b/java/res/values-iw/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"צלילים עם לחיצה על מקשים"</string> <string name="popup_on_keypress" msgid="123894815723512944">"חלון קופץ עם לחיצה על מקשים"</string> <string name="general_category" msgid="1859088467017573195">"כללי"</string> - <string name="prediction_category" msgid="6361242011806282176">"תיקון טקסט"</string> + <string name="correction_category" msgid="2236750915056607613">"תיקון טקסט"</string> + <string name="ngram_category" msgid="5337109164339320257">"הצעות המבוססות על מילים קודמות"</string> + <string name="misc_category" msgid="6894192814868233453">"אפשרויות אחרות"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"הפיכה אוטומטית של אותיות לרישיות"</string> <string name="quick_fixes" msgid="5353213327680897927">"תיקונים מהירים"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"מתקן שגיאות הקלדה נפוצות"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"הצג תמיד"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"הצג בפריסה לאורך"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"הסתר תמיד"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"השתמש במחליף השפה שבמקש הרווח"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"הצג מקש הגדרות"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"אוטומטי"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"הצג תמיד"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"כבוי"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"מצומצם"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"מחמיר"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"הצעות של צמדי אותיות (Bigram)"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"הצעות של צמדי אותיות (Bigram)"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"השתמש במילה הקודמת כדי לשפר את ההצעה"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"חיזוי צמדי אותיות (Bigram)"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"השתמש במילה הקודמת גם עבור חיזוי"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string> <string name="label_go_key" msgid="1635148082137219148">"בצע"</string> <string name="label_next_key" msgid="362972844525672568">"הבא"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"עוד"</string> <string name="label_pause_key" msgid="181098308428035340">"השהה"</string> <string name="label_wait_key" msgid="6402152600878093134">"המתן"</string> - <string name="description_delete_key" msgid="5586406298531883960">"מחק"</string> - <string name="description_return_key" msgid="8750044000806461678">"חזור"</string> - <string name="description_settings_key" msgid="7484527796782969219">"הגדרות"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"רווח"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"סמלים"</string> - <string name="description_tab_key" msgid="828186583738307137">"כרטיסייה"</string> - <string name="description_voice_key" msgid="3057731675774652754">"קלט קולי"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"מצב סמלים פועל"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"מצב סמלים כבוי"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift פועל"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift כבוי"</string> <string name="voice_warning_title" msgid="4419354150908395008">"קלט קולי"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"קלט קולי אינו נתמך בשלב זה בשפתך, אך הוא פועל באנגלית."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"קלט קולי משתמש בזיהוי דיבור של Google. "<a href="http://m.google.com/privacy">"מדיניות הפרטיות של \'Google לנייד\'"</a>" חלה במקרה זה."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"גע במילים שהוזנו כדי לתקן אותן, רק כאשר הצעות מוצגות"</string> <string name="keyboard_layout" msgid="437433231038683666">"עיצוב מקלדת"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"מקלדת צ\'כית"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"מקלדת בשפה הערבית"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"מקלדת דנית"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"מקלדת גרמנית "</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"מקלדת אנגלית (בריטניה)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"מקלדת צרפתית"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"מקלדת צרפתית (קנדה)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"מקלדת צרפתית (שוויץ)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"מקלדת בשפה העברית"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"מקלדת איטלקית"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"מקלדת נורווגית"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"מקלדת הולנדית"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"מקלדת פולנית"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"מקלדת רוסית"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"מקלדת סרבית"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"מקלדת שוודית"</string> diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml index 5d82a453b..97a73a461 100644 --- a/java/res/values-ja/strings.xml +++ b/java/res/values-ja/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"キー操作音"</string> <string name="popup_on_keypress" msgid="123894815723512944">"キー押下時ポップアップ"</string> <string name="general_category" msgid="1859088467017573195">"全般"</string> - <string name="prediction_category" msgid="6361242011806282176">"テキストの修正"</string> + <string name="correction_category" msgid="2236750915056607613">"テキストの修正"</string> + <string name="ngram_category" msgid="5337109164339320257">"前の語句に基づいた入力候補表示"</string> + <string name="misc_category" msgid="6894192814868233453">"他のオプション"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string> <string name="quick_fixes" msgid="5353213327680897927">"クイックフィックス"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"よくある誤字・脱字を修正します"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"常に表示"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"縦向きで表示"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"常に非表示"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"スペースバーで切替"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"設定キーを表示"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自動"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"常に表示"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"OFF"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"中"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"強"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"バイグラム入力候補表示"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"バイグラム入力候補表示"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"直前の単語から入力候補を予測します"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"バイグラム予測"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"前の語句も予測に使用"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:保存しました"</string> <string name="label_go_key" msgid="1635148082137219148">"実行"</string> <string name="label_next_key" msgid="362972844525672568">"次へ"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Shift"</string> <string name="label_pause_key" msgid="181098308428035340">"停止"</string> <string name="label_wait_key" msgid="6402152600878093134">"待機"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Del"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"設定"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Space"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"記号"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"音声入力"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"記号ON"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"記号OFF"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift ON"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift OFF"</string> <string name="voice_warning_title" msgid="4419354150908395008">"音声入力"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"音声入力は現在英語には対応していますが、日本語には対応していません。"</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"音声入力ではGoogleの音声認識技術を利用します。"<a href="http://m.google.com/privacy">"モバイルプライバシーポリシー"</a>"が適用されます。"</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"候補が表示されているときのみ、入力した語句をタップして修正する"</string> <string name="keyboard_layout" msgid="437433231038683666">"キーボードテーマ"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"チェコ語のキーボード"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"アラビア語のキーボード"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"デンマーク語のキーボード"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"ドイツ語のキーボード"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"英語(英国)のキーボード"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"フランス語のキーボード"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"フランス語(カナダ)のキーボード"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"フランス語(スイス)のキーボード"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"ヘブライ語のキーボード"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"イタリア語のキーボード"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"ノルウェー語のキーボード"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"オランダ語のキーボード"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"ポーランド語のキーボード"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"ロシア語のキーボード"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"セルビア語のキーボード"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"スウェーデン語のキーボード"</string> diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml index 2cf0ec2aa..a7d50c8eb 100644 --- a/java/res/values-ko/strings.xml +++ b/java/res/values-ko/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"키를 누를 때 소리 발생"</string> <string name="popup_on_keypress" msgid="123894815723512944">"키를 누를 때 팝업"</string> <string name="general_category" msgid="1859088467017573195">"일반"</string> - <string name="prediction_category" msgid="6361242011806282176">"텍스트 수정"</string> + <string name="correction_category" msgid="2236750915056607613">"텍스트 수정"</string> + <string name="ngram_category" msgid="5337109164339320257">"이전 단어에 기반한 추천"</string> + <string name="misc_category" msgid="6894192814868233453">"기타 옵션"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string> <string name="quick_fixes" msgid="5353213327680897927">"빠른 수정"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"자주 발생하는 오타를 수정합니다."</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"항상 표시"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"세로 모드로 표시"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"항상 숨기기"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"스페이스 바 언어 교환기 사용"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"설정 키 표시"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"자동"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"항상 표시"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"사용 안함"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"보통"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"적극적"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram 추천"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram 추천"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"이전 단어를 사용하여 추천 기능 개선"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram 예측"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"이전 단어를 사용하여 예상 검색어를 표시합니다."</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: 저장됨"</string> <string name="label_go_key" msgid="1635148082137219148">"이동"</string> <string name="label_next_key" msgid="362972844525672568">"다음"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"더보기"</string> <string name="label_pause_key" msgid="181098308428035340">"일시 중지"</string> <string name="label_wait_key" msgid="6402152600878093134">"대기"</string> - <string name="description_delete_key" msgid="5586406298531883960">"삭제"</string> - <string name="description_return_key" msgid="8750044000806461678">"리턴"</string> - <string name="description_settings_key" msgid="7484527796782969219">"설정"</string> - <string name="description_shift_key" msgid="346906866277787836">"시프트"</string> - <string name="description_space_key" msgid="8512130111575878517">"스페이스"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"기호"</string> - <string name="description_tab_key" msgid="828186583738307137">"탭"</string> - <string name="description_voice_key" msgid="3057731675774652754">"음성 입력"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"기호 사용"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"기호 사용 안함"</string> - <string name="description_shift_on" msgid="6983188949895971587">"시프트 사용"</string> - <string name="description_shift_off" msgid="8553265474523069034">"시프트 사용 안함"</string> <string name="voice_warning_title" msgid="4419354150908395008">"음성 입력"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"음성 입력에서는 Google의 음성 인식 기능을 사용합니다. "<a href="http://m.google.com/privacy">"모바일 개인정보취급방침"</a>"이 적용됩니다."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"입력한 단어를 터치하여 수정(추천 단어가 표시되는 경우에만)"</string> <string name="keyboard_layout" msgid="437433231038683666">"키보드 테마"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"체코어 키보드"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"아랍어 키보드"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"덴마크어 키보드"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"독일어 키보드"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"영어(영국) 키보드"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"프랑스어 키보드"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"프랑스어(캐나다) 키보드"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"프랑스어(스위스) 키보드"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"히브리어 키보드"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"이탈리아어 키보드"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"노르웨이어 키보드"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"네덜란드어 키보드"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"폴란드어 키보드"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"러시아어 키보드"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"세르비아어 키보드"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"스웨덴어 키보드"</string> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index 7df124bfc..6b52ad4e1 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -19,20 +19,25 @@ --> <resources> - <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 --> - <dimen name="keyboardHeight">1.060in</dimen> + <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.260in --> + <dimen name="keyboardHeight">1.100in</dimen> + <fraction name="minKeyboardHeight">45%p</fraction> <!-- key_height + key_bottom_gap = popup_key_height --> -<!-- <dimen name="key_height">0.250in</dimen>--> +<!-- <dimen name="key_height">0.260in</dimen>--> <dimen name="key_bottom_gap">0.020in</dimen> - <dimen name="popup_key_height">0.270in</dimen> + <dimen name="popup_key_height">0.280in</dimen> <dimen name="keyboard_top_padding">0.0in</dimen> <dimen name="keyboard_bottom_padding">0.0in</dimen> + <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen> + <fraction name="key_letter_ratio">55%</fraction> + <fraction name="key_label_text_ratio">35%</fraction> + <dimen name="key_preview_offset">0.08in</dimen> + <fraction name="key_preview_text_ratio">90%</fraction> <dimen name="candidate_strip_height">38dip</dimen> <dimen name="candidate_strip_fading_edge_length">63dip</dimen> - <dimen name="spacebar_vertical_correction">2dip</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> - <dimen name="mini_keyboard_slide_allowance">0.324in</dimen> + <dimen name="mini_keyboard_slide_allowance">0.336in</dimen> <!-- popup_key_height x -1.0 --> - <dimen name="mini_keyboard_vertical_correction">-0.270in</dimen> + <dimen name="mini_keyboard_vertical_correction">-0.280in</dimen> </resources> diff --git a/java/res/values-large-land/dimens.xml b/java/res/values-large-land/dimens.xml deleted file mode 100644 index 19b78d3b0..000000000 --- a/java/res/values-large-land/dimens.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?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. -*/ ---> - -<resources> - <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 --> - <dimen name="keyboardHeight">58.0mm</dimen> - <!-- key_height + key_bottom_gap = popup_key_height --> - <!-- <dimen name="key_height">14.5mm</dimen> --> - <dimen name="key_bottom_gap">0.0mm</dimen> - <dimen name="key_horizontal_gap">0.0mm</dimen> - <dimen name="popup_key_height">13.0mm</dimen> - <dimen name="keyboard_top_padding">1.1mm</dimen> - <dimen name="keyboard_bottom_padding">0.0mm</dimen> - <!-- key_height x 1.0 --> - <dimen name="key_preview_height">13.0mm</dimen> - - <dimen name="key_letter_size">28dip</dimen> - <dimen name="key_label_text_size">20dip</dimen> - <!-- left or right padding of label alignment --> - <dimen name="key_label_horizontal_alignment_padding">18dip</dimen> - <dimen name="candidate_strip_padding">40.0mm</dimen> -</resources> diff --git a/java/res/values-large/config.xml b/java/res/values-large/config.xml deleted file mode 100644 index fe5aee3cf..000000000 --- a/java/res/values-large/config.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?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. -*/ ---> - -<resources> - <bool name="config_enable_show_settings_key_option">true</bool> - <bool name="config_enable_show_subtype_settings">false</bool> - <bool name="config_enable_show_voice_key_option">true</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_swipe_down_dismiss_keyboard_enabled">false</bool> - <bool name="config_sliding_key_input_enabled">false</bool> - <bool name="config_digit_popup_characters_enabled">true</bool> - <!-- Whether or not Popup on key press is enabled by default --> - <bool name="config_default_popup_preview">false</bool> - <bool name="config_default_sound_enabled">true</bool> - <bool name="config_use_spacebar_language_switcher">false</bool> - <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false --> - <bool name="config_show_mini_keyboard_at_touched_point">true</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}. --> - <string name="config_default_keyboard_theme_id" translatable="false">5</string> - <string name="config_text_size_of_language_on_spacebar" translatable="false">medium</string> - <integer name="config_max_popup_keyboard_column">5</integer> -</resources> diff --git a/java/res/values-large/dimens.xml b/java/res/values-large/dimens.xml deleted file mode 100644 index 47d5e0f36..000000000 --- a/java/res/values-large/dimens.xml +++ /dev/null @@ -1,51 +0,0 @@ -<?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. -*/ ---> - -<resources> - <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 --> - <dimen name="keyboardHeight">48.0mm</dimen> - <!-- key_height + key_bottom_gap = popup_key_height --> - <!-- <dimen name="key_height">14.5mm</dimen> --> - <dimen name="key_bottom_gap">0.0mm</dimen> - <dimen name="key_horizontal_gap">0.0mm</dimen> - <dimen name="popup_key_height">10.0mm</dimen> - <dimen name="keyboard_top_padding">1.1mm</dimen> - <dimen name="keyboard_bottom_padding">0.0mm</dimen> - <!-- key_height x 1.0 --> - <dimen name="key_preview_height">13.0mm</dimen> - <dimen name="mini_keyboard_key_horizontal_padding">12dip</dimen> - <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> - <!-- popup_key_height x 1.2 --> - <dimen name="mini_keyboard_slide_allowance">15.6mm</dimen> - <!-- popup_key_height x -1.0 --> - <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen> - - <dimen name="key_letter_size">26dip</dimen> - <dimen name="key_label_text_size">16dip</dimen> - <dimen name="key_preview_text_size_large">24dip</dimen> - <!-- left or right padding of label alignment --> - <dimen name="key_label_horizontal_alignment_padding">6dip</dimen> - - <dimen name="candidate_strip_height">46dip</dimen> - <dimen name="candidate_strip_padding">15.0mm</dimen> - <dimen name="candidate_min_width">0.3in</dimen> - <dimen name="candidate_padding">12dip</dimen> - <dimen name="candidate_text_size">22dip</dimen> -</resources> diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml index 3ff1543c6..0b978f98c 100644 --- a/java/res/values-lt/strings.xml +++ b/java/res/values-lt/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Klavišo paspaudimo garsas"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Iššoka paspaudus klavišą"</string> <string name="general_category" msgid="1859088467017573195">"Bendra"</string> - <string name="prediction_category" msgid="6361242011806282176">"Teksto taisymas"</string> + <string name="correction_category" msgid="2236750915056607613">"Teksto taisymas"</string> + <string name="ngram_category" msgid="5337109164339320257">"Pasiūlymai pagal ankstesnius žodžius"</string> + <string name="misc_category" msgid="6894192814868233453">"Kitos parinktys"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</string> <string name="quick_fixes" msgid="5353213327680897927">"Greiti pataisymai"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Taiso dažnai padarytas rašybos klaidas"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Visada rodyti"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Rodyti stačiuoju režimu"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Visada slėpti"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Naud. tarpo kl. k. jung."</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Rodyti nustatymų raktą"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatinis"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Visada rodyti"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Išjungta"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Vidutinis"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Atkaklus"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Digramų pasiūlymai"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramų pasiūlymai"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Naudoti ankstesnį žodį pasiūlymui patobulinti"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigramų numatymas"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Numatant naudoti ir ankstesnį žodį"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: išsaugota"</string> <string name="label_go_key" msgid="1635148082137219148">"Pradėti"</string> <string name="label_next_key" msgid="362972844525672568">"Kitas"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Daugiau"</string> <string name="label_pause_key" msgid="181098308428035340">"Prist."</string> <string name="label_wait_key" msgid="6402152600878093134">"Lauk."</string> - <string name="description_delete_key" msgid="5586406298531883960">"Ištrinti"</string> - <string name="description_return_key" msgid="8750044000806461678">"Grįžti"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Nustatymai"</string> - <string name="description_shift_key" msgid="346906866277787836">"Keitimas"</string> - <string name="description_space_key" msgid="8512130111575878517">"Tarpas"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboliai"</string> - <string name="description_tab_key" msgid="828186583738307137">"Skirtukas"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Balso įvestis"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simboliai įjungti"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simboliai išjungti"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Keitimas įjungtas"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Keitimas išjungtas"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Balso įvestis"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Šiuo metu balso įvestis jūsų kompiuteryje nepalaikoma, bet ji veikia anglų k."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Balso įvesčiai naudojamas „Google“ kalbos atpažinimas. Taikoma "<a href="http://m.google.com/privacy">"privatumo politika mobiliesiems"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Jei norite ištaisyti įvestus žodžius, palieskite juos tik tada, kai matomi pasiūlymai"</string> <string name="keyboard_layout" msgid="437433231038683666">"Klaviatūros tema"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Čekiška klaviatūra"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabiška klaviatūra"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Daniška klaviatūra"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Vokiška klaviatūra"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Angliška (JK) klaviatūra"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Prancūziška klaviatūra"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Prancūziška (Kanada) klaviatūra"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Prancūziška (Šveicarija) klaviatūra"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrajiška klaviatūra"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Itališka klaviatūra"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norvegiška klaviatūra"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Olandiška klaviatūra"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Lenkiška klaviatūra"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Rusiška klaviatūra"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbiška klaviatūra"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Švediška klaviatūra"</string> diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml index 11e768fce..9d69d15a1 100644 --- a/java/res/values-lv/strings.xml +++ b/java/res/values-lv/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Skaņa, nospiežot taustiņu"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Nospiežot taustiņu, parādīt uznirstošo izvēlni"</string> <string name="general_category" msgid="1859088467017573195">"Vispārīgi"</string> - <string name="prediction_category" msgid="6361242011806282176">"Teksta korekcija"</string> + <string name="correction_category" msgid="2236750915056607613">"Teksta korekcija"</string> + <string name="ngram_category" msgid="5337109164339320257">"Ieteikumi, kuru pamatā ir iepriekšējie vārdi"</string> + <string name="misc_category" msgid="6894192814868233453">"Citas opcijas"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</string> <string name="quick_fixes" msgid="5353213327680897927">"Ātrie labojumi"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Nodrošina izplatītu drukas kļūdu labošanu."</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vienmēr rādīt"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Rādīt portreta režīmā"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vienmēr slēpt"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Izmantot valodu pārslēgšanai atstarpēšanas taustiņu"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Rādīt iestatījumu taustiņu"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automātiski"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vienmēr rādīt"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Izslēgta"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mērena"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresīva"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram ieteikumi"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigrammu ieteikumi"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Ieteikuma uzlabošanai izmantot iepriekšējo vārdu"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigrammu prognozes"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Izmantot iepriekšējo vārdu arī prognozēm"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: saglabāts"</string> <string name="label_go_key" msgid="1635148082137219148">"Sākt"</string> <string name="label_next_key" msgid="362972844525672568">"Tālāk"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Vairāk"</string> <string name="label_pause_key" msgid="181098308428035340">"Pauze"</string> <string name="label_wait_key" msgid="6402152600878093134">"Gaidīt"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Dzēšanas taustiņš"</string> - <string name="description_return_key" msgid="8750044000806461678">"Atgriešanās taustiņš"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Iestatījumu taustiņš"</string> - <string name="description_shift_key" msgid="346906866277787836">"Pārslēgšanas taustiņš"</string> - <string name="description_space_key" msgid="8512130111575878517">"Atstarpes taustiņš"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simbolu taustiņš"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulēšanas taustiņš"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Runas ievades taustiņš"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simbolu režīms ir ieslēgts."</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simbolu režīms ir izslēgts."</string> - <string name="description_shift_on" msgid="6983188949895971587">"Pārslēgšanas režīms ir ieslēgts."</string> - <string name="description_shift_off" msgid="8553265474523069034">"Pārslēgšanas režīms ir izslēgts."</string> <string name="voice_warning_title" msgid="4419354150908395008">"Balss ievade"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Balss ievade jūsu valodā pašlaik netiek atbalstīta, taču tā ir pieejama angļu valodā."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Balss ievadei tiek izmantota Google runas atpazīšanas funkcija. Uz šīs funkcijas lietošanu attiecas "<a href="http://m.google.com/privacy">"mobilo sakaru ierīču lietošanas konfidencialitātes politika"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Pieskarties ievadītajiem vārdiem, lai tos labotu (tikai tad, ja tiek rādīti ieteikumi)."</string> <string name="keyboard_layout" msgid="437433231038683666">"Tastatūras motīvs"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Čehu tastatūra"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arābu tastatūra"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dāņu tastatūra"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Vācu tastatūra"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Angļu (Lielbritānija) tastatūra"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Franču tastatūra"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Franču (Kanāda) tastatūra"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Franču (Šveices) tastatūra"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Ebreju tastatūra"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Itāļu tastatūra"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norvēģu tastatūra"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Holandiešu tastatūra"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poļu valodas tastatūra"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Krievu tastatūra"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbu tastatūra"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Zviedru tastatūra"</string> diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml index db163b963..3effab0fa 100644 --- a/java/res/values-nb/strings.xml +++ b/java/res/values-nb/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetrykk"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Hurtigvindu ved tastetrykk"</string> <string name="general_category" msgid="1859088467017573195">"Generelt"</string> - <string name="prediction_category" msgid="6361242011806282176">"Tekstkorrigering"</string> + <string name="correction_category" msgid="2236750915056607613">"Tekstkorrigering"</string> + <string name="ngram_category" msgid="5337109164339320257">"Forslag basert på tidligere ord"</string> + <string name="misc_category" msgid="6894192814868233453">"Andre alternativer"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string> <string name="quick_fixes" msgid="5353213327680897927">"Autokorrektur"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Retter vanlige stavefeil"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vis alltid"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Vis i stående modus"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Skjul alltid"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Skift språk med mellomromstasten"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Vis innstillingsnøkkel"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisk"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vis alltid"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Av"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Omfattende"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-forslag"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-forslag"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Bruk forrige ord til å forbedre forslaget"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram-prediksjon"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Bruk forrige ord også for forslag"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string> <string name="label_go_key" msgid="1635148082137219148">"Gå"</string> <string name="label_next_key" msgid="362972844525672568">"Neste"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mer"</string> <string name="label_pause_key" msgid="181098308428035340">"Pause"</string> <string name="label_wait_key" msgid="6402152600878093134">"Vent"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Innstillinger"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Mellomrom"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboler"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Taleinndata"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symboler er slått på"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symboler er slått av"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift på"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift av"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Stemmedata"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmedata håndteres foreløpig ikke på ditt språk, men fungerer på engelsk."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Google Voice bruker Googles talegjenkjenning. "<a href="http://m.google.com/privacy">"Personvernreglene for mobil"</a>" gjelder."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Når forslag er synlige, kan du trykke på ord du har skrevet inn, for å endre dem"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tastaturtema"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tsjekkisk tastatur"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabisk tastatur"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dansk tastatur"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tysk tastatur"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelsk tastatur (Storbritannia)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Fransk tastatur"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Fransk tastatur (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Fransk tastatur (Sveits)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebraisk tastatur"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiensk tastatur"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norsk tastatur"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nederlandsk tastatur"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polsk tastatur"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russisk tastatur"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbisk tastatur"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svensk tastatur"</string> diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml index 6dece4885..fb10b3229 100644 --- a/java/res/values-nl/strings.xml +++ b/java/res/values-nl/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Geluid bij toetsaanslag"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bij toetsaanslag"</string> <string name="general_category" msgid="1859088467017573195">"Algemeen"</string> - <string name="prediction_category" msgid="6361242011806282176">"Tekstcorrectie"</string> + <string name="correction_category" msgid="2236750915056607613">"Tekstcorrectie"</string> + <string name="ngram_category" msgid="5337109164339320257">"Suggesties op basis van eerdere woorden"</string> + <string name="misc_category" msgid="6894192814868233453">"Andere opties"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string> <string name="quick_fixes" msgid="5353213327680897927">"Snelle oplossingen"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Hiermee worden veelvoorkomende typefouten gecorrigeerd"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Altijd weergeven"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Weergeven in staande modus"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Altijd verbergen"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Taal schakelen via spatiebalk"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Instellingscode weergeven"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisch"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Altijd weergeven"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Uitgeschakeld"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Normaal"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressief"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Digram-suggesties"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Digram-suggesties"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Vorig woord gebruiken om suggestie te verbeteren"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Digram-voorspelling"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Het voorgaande woord ook voor voorspelling gebruiken"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: opgeslagen"</string> <string name="label_go_key" msgid="1635148082137219148">"Start"</string> <string name="label_next_key" msgid="362972844525672568">"Volgende"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Meer"</string> <string name="label_pause_key" msgid="181098308428035340">"Onderbr."</string> <string name="label_wait_key" msgid="6402152600878093134">"Wacht"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Instellingen"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Spatie"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbolen"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Spraakinvoer"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symbolen aan"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symbolen uit"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift aan"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift uit"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Spraakinvoer"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Spraakinvoer maakt gebruik van de spraakherkenning van Google. Het "<a href="http://m.google.com/privacy">"Privacybeleid van Google Mobile"</a>" is van toepassing."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Ingevoerde woorden aanraken om ze te verbeteren, alleen mogelijk wanneer suggesties zichtbaar zijn"</string> <string name="keyboard_layout" msgid="437433231038683666">"Toetsenbordthema"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tsjechisch toetsenbord"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabisch toetsenbord"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Deens toetsenbord"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Duits toetsenbord"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engels toetsenbord (VK)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Frans toetsenbord"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Frans toetsenbord (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Frans toetsenbord (Zwitserland)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebreeuws toetsenbord"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiaans toetsenbord"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Noors toetsenbord"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nederlands toetsenbord"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Pools toetsenbord"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russisch toetsenbord"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Servisch toetsenbord"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Zweeds toetsenbord"</string> diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml index 70c4b18df..796b412e3 100644 --- a/java/res/values-pl/strings.xml +++ b/java/res/values-pl/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Dźwięk przy naciśnięciu"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Powiększ po naciśnięciu"</string> <string name="general_category" msgid="1859088467017573195">"Ogólne"</string> - <string name="prediction_category" msgid="6361242011806282176">"Korekta tekstu"</string> + <string name="correction_category" msgid="2236750915056607613">"Poprawianie tekstu"</string> + <string name="ngram_category" msgid="5337109164339320257">"Podpowiedzi na podstawie wcześniejszych słów"</string> + <string name="misc_category" msgid="6894192814868233453">"Inne opcje"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string> <string name="quick_fixes" msgid="5353213327680897927">"Szybkie poprawki"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Poprawia częste błędy wpisywania"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Zawsze pokazuj"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Pokaż w trybie pionowym"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Zawsze ukrywaj"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Spacja przełącza język"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Pokaż klawisz ustawień"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatycznie"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Zawsze pokazuj"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Wyłącz"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Umiarkowana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresywna"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestie dla bigramów"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Podpowiadanie dwuznaków"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Używaj poprzedniego wyrazu, aby polepszyć sugestię"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Przewidywanie dwuznaków"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Przewiduj również na podstawie poprzedniego słowa"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"Dalej"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Więcej"</string> <string name="label_pause_key" msgid="181098308428035340">"Pauza"</string> <string name="label_wait_key" msgid="6402152600878093134">"Czekaj"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Ustawienia"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Spacja"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbole"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Wprowadzanie głosowe"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symbole włączone"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symbole wyłączone"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift włączony"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift wyłączony"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Wprowadzanie głosowe"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Wprowadzanie głosowe obecnie nie jest obsługiwane w Twoim języku, ale działa w języku angielskim."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Funkcja wprowadzania głosowego wykorzystuje mechanizm rozpoznawania mowy. Obowiązuje "<a href="http://m.google.com/privacy">"Polityka prywatności Google Mobile"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dotykaj wprowadzonych słów, aby je poprawiać tylko wówczas, gdy widoczne są sugestie."</string> <string name="keyboard_layout" msgid="437433231038683666">"Motyw klawiatury"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Klawiatura czeska"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Klawiatura arabska"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Klawiatura duńska"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Klawiatura niemiecka"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Klawiatura angielska (UK)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Klawiatura francuska"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Klawiatura francuska (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Klawiatura francuska (Szwajcaria)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Klawiatura hebrajska"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Klawiatura włoska"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Klawiatura norweska"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Klawiatura holenderska"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Klawiatura polska"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Klawiatura rosyjska"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Klawiatura serbska"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Klawiatura szwedzka"</string> diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml index 5845ebc59..541abf4ca 100644 --- a/java/res/values-pt-rPT/strings.xml +++ b/java/res/values-pt-rPT/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Som ao premir as teclas"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Mostrar popup ao premir tecla"</string> <string name="general_category" msgid="1859088467017573195">"Geral"</string> - <string name="prediction_category" msgid="6361242011806282176">"Correcção de texto"</string> + <string name="correction_category" msgid="2236750915056607613">"Correção de texto"</string> + <string name="ngram_category" msgid="5337109164339320257">"Sugestões baseadas em palavras anteriores"</string> + <string name="misc_category" msgid="6894192814868233453">"Outras opções"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string> <string name="quick_fixes" msgid="5353213327680897927">"Correcções rápidas"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige os erros de escrita comuns"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar sempre"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar no modo de retrato"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar sempre"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Utilizar barra esp. alt. idioma"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla das definições"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar sempre"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desligar"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressiva"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestões Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Sugestões Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizar a palavra anterior para melhorar a sugestão"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Predição Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar a palavra anterior também para predição"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Seguinte"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mais"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Esp."</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Definições"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Espaço"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Entrada de voz"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos ativados"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desativados"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift ativado"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift desativado"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A entrada de voz utiliza o reconhecimento de voz da Google. É aplicável a "<a href="http://m.google.com/privacy">"Política de privacidade do Google Mobile"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tocar nas palavras introduzidas para as corrigir, apenas quando as sugestões estiverem visíveis"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema do teclado"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado checo"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado dinamarquês"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado alemão"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado inglês (Reino Unido)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado francês"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado francês (Canadá)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado francês (Suíça)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebraico"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado italiano"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado norueguês"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado holandês"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado Polaco"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado russo"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado sérvio"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado sueco"</string> diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml index f1203c671..42857f06c 100644 --- a/java/res/values-pt/strings.xml +++ b/java/res/values-pt/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Som ao tocar a tecla"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Exibir pop-up ao digitar"</string> <string name="general_category" msgid="1859088467017573195">"Geral"</string> - <string name="prediction_category" msgid="6361242011806282176">"Correção de texto"</string> + <string name="correction_category" msgid="2236750915056607613">"Correção de texto"</string> + <string name="ngram_category" msgid="5337109164339320257">"Sugestões baseadas em palavras anteriores"</string> + <string name="misc_category" msgid="6894192814868233453">"Outras opções"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Capitaliz. automática"</string> <string name="quick_fixes" msgid="5353213327680897927">"Reparos rápidos"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige erros comuns de digitação"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar sempre"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar em modo retrato"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Sempre ocultar"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Alt. idiomas c/ a barra"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de config."</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar sempre"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desativado"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressivo"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestões de bigrama"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Sugestões de bigrama"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palavra anterior para melhorar a sugestão"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Previsão de bigrama"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use também a palavra anterior para prever"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Avançar"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mais"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Esp."</string> - <string name="description_delete_key" msgid="5586406298531883960">"Excluir"</string> - <string name="description_return_key" msgid="8750044000806461678">"Voltar"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Configurações"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Espaço"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Entrada de texto por voz"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos ativados"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desativados"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift ativado"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift desativado"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A entrada de texto por voz usa o reconhecimento de voz do Google. "<a href="http://m.google.com/privacy">"A política de privacidade para celulares"</a>" é aplicada."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toque nas palavras digitadas para corrigi-las apenas quando as sugestões estiverem visíveis"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema do teclado"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado em tcheco"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado para dinamarquês"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado para alemão"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado para inglês (Reino Unido)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado para francês"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado para francês (Canadá)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado para francês (Suíça)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebraico"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado para italiano"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado para norueguês"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado para holandês"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado polonês"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado para russo"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado para sérvio"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado para sueco"</string> diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml index 9c51cad72..e42412241 100644 --- a/java/res/values-rm/strings.xml +++ b/java/res/values-rm/strings.xml @@ -29,7 +29,22 @@ <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up cun smatgar ina tasta"</string> <!-- no translation found for general_category (1859088467017573195) --> <skip /> - <!-- outdated translation 7027100625580696660 --> <string name="prediction_category" msgid="6361242011806282176">"Parameters da las propostas per pleds"</string> + <!-- no translation found for correction_category (2236750915056607613) --> + <skip /> + <!-- no translation found for ngram_category (5337109164339320257) --> + <skip /> + <!-- no translation found for misc_category (6894192814868233453) --> + <skip /> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Maiusclas automaticas"</string> <string name="quick_fixes" msgid="5353213327680897927">"Correcturas sveltas"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Curregia sbagls da tippar currents"</string> @@ -43,6 +58,8 @@ <skip /> <!-- no translation found for prefs_suggestion_visibility_hide_name (6309143926422234673) --> <skip /> + <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) --> + <skip /> <!-- no translation found for prefs_settings_key (4623341240804046498) --> <skip /> <!-- no translation found for settings_key_mode_auto_name (2993460277873684680) --> @@ -59,8 +76,12 @@ <skip /> <!-- no translation found for auto_correction_threshold_mode_aggeressive (3524029103734923819) --> <skip /> - <string name="bigram_suggestion" msgid="1323347224043514969">"Propostas da tip bigram"</string> + <!-- outdated translation 1323347224043514969 --> <string name="bigram_suggestion" msgid="2636414079905220518">"Propostas da tip bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Meglierar la proposta cun agid dal pled precedent"</string> + <!-- no translation found for bigram_prediction (8914273444762259739) --> + <skip /> + <!-- no translation found for bigram_prediction_summary (1747261921174300098) --> + <skip /> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà"</string> <string name="label_go_key" msgid="1635148082137219148">"Dai"</string> <string name="label_next_key" msgid="362972844525672568">"Vinavant"</string> @@ -74,30 +95,6 @@ <skip /> <!-- no translation found for label_wait_key (6402152600878093134) --> <skip /> - <!-- no translation found for description_delete_key (5586406298531883960) --> - <skip /> - <!-- no translation found for description_return_key (8750044000806461678) --> - <skip /> - <!-- no translation found for description_settings_key (7484527796782969219) --> - <skip /> - <!-- no translation found for description_shift_key (346906866277787836) --> - <skip /> - <!-- no translation found for description_space_key (8512130111575878517) --> - <skip /> - <!-- no translation found for description_switch_alpha_symbol_key (4537975384274405537) --> - <skip /> - <!-- no translation found for description_tab_key (828186583738307137) --> - <skip /> - <!-- no translation found for description_voice_key (3057731675774652754) --> - <skip /> - <!-- no translation found for description_symbols_on (2994366855822840559) --> - <skip /> - <!-- no translation found for description_symbols_off (3209578267079515136) --> - <skip /> - <!-- no translation found for description_shift_on (6983188949895971587) --> - <skip /> - <!-- no translation found for description_shift_off (8553265474523069034) --> - <skip /> <string name="voice_warning_title" msgid="4419354150908395008">"Cumonds vocals"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\""</string> <!-- outdated translation 4611518823070986445 --> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Ils cumonds vocals èn ina funcziunalitad experimentala che utilisescha la renconuschientscha vocala da rait da Google."</string> @@ -146,6 +143,8 @@ <string name="keyboard_layout" msgid="437433231038683666">"Design da la tastatura"</string> <!-- no translation found for subtype_mode_cs_keyboard (1141718931112377586) --> <skip /> + <!-- no translation found for subtype_mode_ar_keyboard (2655338636329774995) --> + <skip /> <!-- no translation found for subtype_mode_da_keyboard (1243570804427922104) --> <skip /> <!-- no translation found for subtype_mode_de_keyboard (1990979135959462145) --> @@ -162,12 +161,18 @@ <skip /> <!-- no translation found for subtype_mode_fr_CH_keyboard (6742806653181621228) --> <skip /> + <!-- no translation found for subtype_mode_iw_keyboard (1787536828253289950) --> + <skip /> <!-- no translation found for subtype_mode_it_keyboard (4934199655425394484) --> <skip /> <!-- no translation found for subtype_mode_nb_keyboard (1175783216100212360) --> <skip /> <!-- no translation found for subtype_mode_nl_keyboard (5090278083256037936) --> <skip /> + <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) --> + <skip /> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <!-- no translation found for subtype_mode_ru_keyboard (1383995915064277943) --> <skip /> <!-- no translation found for subtype_mode_sr_keyboard (5019440799612208168) --> diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml index 0a80911ce..6a30f5581 100644 --- a/java/res/values-ro/strings.xml +++ b/java/res/values-ro/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Sunet la apăsarea tastei"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Fereastră pop-up la apăsarea tastei"</string> <string name="general_category" msgid="1859088467017573195">"General"</string> - <string name="prediction_category" msgid="6361242011806282176">"Corectare text"</string> + <string name="correction_category" msgid="2236750915056607613">"Corectare text"</string> + <string name="ngram_category" msgid="5337109164339320257">"Sugestii bazate pe cuvinte anterioare"</string> + <string name="misc_category" msgid="6894192814868233453">"Alte opţiuni"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string> <string name="quick_fixes" msgid="5353213327680897927">"Remedieri rapide"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Corectează greşelile introduse frecvent"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Afişaţi întotdeauna"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Afişaţi în modul Portret"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ascundeţi întotdeauna"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Spacebar – selector limbă"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Afişaţi tasta setări"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automat"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Afişaţi întotdeauna"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Dezactivată"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderată"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivă"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestii pentru cuvinte de două litere"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Sugestii de tip bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizaţi cuvântul anterior pentru a îmbunătăţi sugestia"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Predicţii de tip bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Se utilizează şi cuvântul precedent pentru predicţii"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: salvat"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"Înainte"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mai multe"</string> <string name="label_pause_key" msgid="181098308428035340">"Pauză"</string> <string name="label_wait_key" msgid="6402152600878093134">"Aşt."</string> - <string name="description_delete_key" msgid="5586406298531883960">"Ştergeţi"</string> - <string name="description_return_key" msgid="8750044000806461678">"Tasta Enter"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Setări"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Tasta Space"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboluri"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tasta Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Intrare vocală"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simbolurile sunt activate"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simbolurile sunt dezactivate"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Tasta Shift este activată"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Tasta Shift este dezactivată"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Intrare voce"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Intrarea vocală nu este acceptată în prezent pentru limba dvs., însă funcţionează în limba engleză."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Intrarea vocală utilizează funcţia Google de recunoaştere vocală. Se aplică "<a href="http://m.google.com/privacy">"Politica de confidenţialitate Google Mobil"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Atingeţi cuvintele introduse pentru a le corecta, numai când pot fi văzute sugestii"</string> <string name="keyboard_layout" msgid="437433231038683666">"Temă pentru tastatură"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tastatură cehă"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Tastatură arabă"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Tastatură daneză"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tastatură germană"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Tastatură engleză (Marea Britanie)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Tastatură franceză"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Tastatură franceză (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Tastatură franceză (Elveţia)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Tastatură ebraică"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Tastatură italiană"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Tastatură norvegiană"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Tastatură olandeză"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Tastatură poloneză"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Tastatură rusă"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Tastatură sârbă"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Tastatură suedeză"</string> diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml index 6dab43cb9..60d45df60 100644 --- a/java/res/values-ru/strings.xml +++ b/java/res/values-ru/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук клавиш"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Увеличение нажатых"</string> <string name="general_category" msgid="1859088467017573195">"Общие"</string> - <string name="prediction_category" msgid="6361242011806282176">"Коррекция текста"</string> + <string name="correction_category" msgid="2236750915056607613">"Исправление текста"</string> + <string name="ngram_category" msgid="5337109164339320257">"Подсказки, основанные на предыдущих словах"</string> + <string name="misc_category" msgid="6894192814868233453">"Другие варианты"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Заглавные автоматически"</string> <string name="quick_fixes" msgid="5353213327680897927">"Быстрое исправление"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Исправлять распространенные опечатки"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Всегда показывать"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Показать вертикально"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Всегда скрывать"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Пробел меняет язык"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Кнопка настроек"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматически"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Всегда показывать"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Откл."</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умеренное"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Активное"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Биграммные подсказки"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Биграммные подсказки"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Используйте предыдущее слово, чтобы исправить подсказку"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Биграммный прогноз"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Использовать предыдущее слово для прогнозирования"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: сохранено"</string> <string name="label_go_key" msgid="1635148082137219148">"Поиск"</string> <string name="label_next_key" msgid="362972844525672568">"Далее"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Ещё"</string> <string name="label_pause_key" msgid="181098308428035340">"Приостановить"</string> <string name="label_wait_key" msgid="6402152600878093134">"Подождите"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Клавиша удаления"</string> - <string name="description_return_key" msgid="8750044000806461678">"Клавиша \"Ввод\""</string> - <string name="description_settings_key" msgid="7484527796782969219">"Клавиша настроек"</string> - <string name="description_shift_key" msgid="346906866277787836">"Клавиша верхнего регистра"</string> - <string name="description_space_key" msgid="8512130111575878517">"Клавиша \"Пробел\""</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Клавиша символов"</string> - <string name="description_tab_key" msgid="828186583738307137">"Клавиша табуляции"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Клавиша голосового ввода"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Клавиши символов выключены"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Клавиши символов включены"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Верхний регистр включен"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Верхний регистр выключен"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Голосовой ввод"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"В настоящее время функция голосового ввода не поддерживает ваш язык, но вы можете пользоваться ей на английском."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Голосовой ввод использует алгоритмы распознавания речи Google. Действует "<a href="http://m.google.com/privacy">"политика конфиденциальности для мобильных устройств"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Нажмите на слово, чтобы исправить его (при наличии подсказок)"</string> <string name="keyboard_layout" msgid="437433231038683666">"Вид клавиатуры"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Клавиатура: чешская"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Арабская клавиатура"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Клавиатура: датская"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Клавиатура: немецкая"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Клавиатура: английская (Великобритания)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Клавиатура: французская"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Клавиатура: французская"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Клавиатура: французская (Швейцария)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Клавиатура на иврите"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Клавиатура: итальянская"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Клавиатура: норвежская"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Клавиатура: голландская"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Польская клавиатура"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Клавиатура: русская"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Клавиатура: сербская"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Голос: шведский"</string> diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml index e7a7cd194..caedfabe4 100644 --- a/java/res/values-sk/strings.xml +++ b/java/res/values-sk/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk pri stlačení klávesu"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Zobraziť znaky pri stlačení klávesu"</string> <string name="general_category" msgid="1859088467017573195">"Všeobecné"</string> - <string name="prediction_category" msgid="6361242011806282176">"Oprava textu"</string> + <string name="correction_category" msgid="2236750915056607613">"Oprava textu"</string> + <string name="ngram_category" msgid="5337109164339320257">"Návrhy na základe predchádzajúcich slov"</string> + <string name="misc_category" msgid="6894192814868233453">"Ďalšie možnosti"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</string> <string name="quick_fixes" msgid="5353213327680897927">"Rýchle opravy"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje najčastejšie chyby pri písaní"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vždy zobrazovať"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Zobraziť v režime na výšku"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vždy skrývať"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Použite medzerník na prepínanie medzi jazykmi"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Zobraziť kláves Nastavenia"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaticky"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vždy zobrazovať"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Vypnuté"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mierne"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresívne"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Návrh Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Návrhy Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Na zlepšenie návrhu použiť predchádzajúce slovo"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Odhady Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Použiť predchádzajúce slovo aj pre predpoveď"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uložené"</string> <string name="label_go_key" msgid="1635148082137219148">"Hľadať"</string> <string name="label_next_key" msgid="362972844525672568">"Ďalej"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Viac"</string> <string name="label_pause_key" msgid="181098308428035340">"Pozastaviť"</string> <string name="label_wait_key" msgid="6402152600878093134">"Čakajte"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Nastavenia"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Medzera"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboly"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Hlasový vstup"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Symboly zapnuté"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Symboly vypnuté"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift zapnutý"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift vypnutý"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pre váš jazyk aktuálne nie je hlasový vstup podporovaný, ale funguje v angličtine."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Hlasový vstup používa rozpoznávanie hlasu Google. Na používanie hlasového vstupu sa vzťahujú "<a href="http://m.google.com/privacy">"Pravidlá ochrany osobných údajov pre mobilné služby"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dotykom zadaných slov tieto slová opravíte, musia však byť viditeľné návrhy"</string> <string name="keyboard_layout" msgid="437433231038683666">"Motív klávesnice"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"klávesnica – čeština"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"klávesnica – arabčina"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"klávesnica – dánčina"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"klávesnica – nemčina"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"klávesnica – angličtina (br.)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"klávesnica – francúzština"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"klávesnica – francúzština (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"klávesnica – francúzština (Švajč.)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"klávesnica – hebrejčina"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"klávesnica – taliančina"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"klávesnica – nórčina"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"klávesnica – holandčina"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poľská klávesnica"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"klávesnica – ruština"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"hlas – srbčina"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"klávesnica – švédčina"</string> diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml index 6bb0b36c8..ed9b60bae 100644 --- a/java/res/values-sl/strings.xml +++ b/java/res/values-sl/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Zvok ob pritisku tipke"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Pojavno okno ob pritisku tipke"</string> <string name="general_category" msgid="1859088467017573195">"Splošno"</string> - <string name="prediction_category" msgid="6361242011806282176">"Popravek besedila"</string> + <string name="correction_category" msgid="2236750915056607613">"Popravek besedila"</string> + <string name="ngram_category" msgid="5337109164339320257">"Predlogi, ki temeljijo na prejšnjih besedah"</string> + <string name="misc_category" msgid="6894192814868233453">"Druge možnosti"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Samodejne velike začetnice"</string> <string name="quick_fixes" msgid="5353213327680897927">"Hitri popravki"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Popravi pogoste tipkarske napake"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vedno pokaži"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Pokaži v pokončnem načinu"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vedno skrij"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Preklopite med jeziki s preslednico"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Pokaži tipko za nastavitve"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Samodejno"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vedno pokaži"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Izklopljeno"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Zmerno"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivno"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramni predlogi"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramni predlogi"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Predlog izboljšaj s prejšnjo besedo"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigramsko predvidevanje"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Uporabi prejšnjo besedo tudi za predvidevanje"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: shranjeno"</string> <string name="label_go_key" msgid="1635148082137219148">"Pojdi"</string> <string name="label_next_key" msgid="362972844525672568">"Naprej"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Več"</string> <string name="label_pause_key" msgid="181098308428035340">"Premor"</string> <string name="label_wait_key" msgid="6402152600878093134">"Čakaj"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Izbriši"</string> - <string name="description_return_key" msgid="8750044000806461678">"Vračalka"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Nastavitve"</string> - <string name="description_shift_key" msgid="346906866277787836">"Dvigalka"</string> - <string name="description_space_key" msgid="8512130111575878517">"Preslednica"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Znaki"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabulatorka"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Glasovni vnos"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Znaki vklopljeni"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Znaki izklopljeni"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Dvigalka vklopljena"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Dvigalka izklopljena"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Glasovni vnos"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Glasovni vnos trenutno ni podprt v vašem jeziku, deluje pa v angleščini."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Glasovni vnos uporablja Googlovo prepoznavanje govora. Zanj velja "<a href="http://m.google.com/privacy">"pravilnik o zasebnosti za mobilne naprave"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dotaknite se vnesenih besed in jih popravite, samo ko so predlogi vidni"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema tipkovnice"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Češka tipkovnica"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabska tipkovnica"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danska tipkovnica"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Nemška tipkovnica"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Tipkovnica za britansko angleščino"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Francoska tipkovnica"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Tipkovnica za kanadsko francoščino"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Tipkovnica za švicarsko francoščino"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrejska tipkovnica"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italijanska tipkovnica"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norveška tipkovnica"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nizozemska tipkovnica"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poljska tipkovnica"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ruska tipkovnica"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Srbska tipkovnica"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Švedska tipkovnica"</string> diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml index 02e7593ca..be375a1f9 100644 --- a/java/res/values-sr/strings.xml +++ b/java/res/values-sr/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук на притисак тастера"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Искачући прозор приликом притиска тастера"</string> <string name="general_category" msgid="1859088467017573195">"Опште"</string> - <string name="prediction_category" msgid="6361242011806282176">"Исправљање текста"</string> + <string name="correction_category" msgid="2236750915056607613">"Исправљање текста"</string> + <string name="ngram_category" msgid="5337109164339320257">"Предлози на основу претходних речи"</string> + <string name="misc_category" msgid="6894192814868233453">"Друге опције"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string> <string name="quick_fixes" msgid="5353213327680897927">"Брзе исправке"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Исправља честе грешке у куцању"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Увек прикажи"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Прикажи у усправном режиму"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Увек сакриј"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Користи размак за избор језика"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Прикажи тастер за подешавања"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Аутоматски"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Увек прикажи"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Искључи"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агресивно"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram предлози"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram предлози"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Користи претходну реч за побољшање предлога"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram предвиђање"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Користи претходну реч и за предвиђање"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string> <string name="label_go_key" msgid="1635148082137219148">"Иди"</string> <string name="label_next_key" msgid="362972844525672568">"Следеће"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Још"</string> <string name="label_pause_key" msgid="181098308428035340">"Паузирај"</string> <string name="label_wait_key" msgid="6402152600878093134">"Сачекајте"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Подешавања"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Размак"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Симболи"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Гласовни унос"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Симболи су укључени"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Симболи су искључени"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift је укључен"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift је искључен"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Гласовни унос"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Гласовни унос тренутно није подржан за ваш језик, али функционише на енглеском."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Гласовни унос користи Google-ову функцију за препознавање гласа. Примењује се "<a href="http://m.google.com/privacy">"политика приватности за мобилне уређаје"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Додирните унете речи да бисте их исправили само када су предлози видљиви"</string> <string name="keyboard_layout" msgid="437433231038683666">"Тема тастатуре"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Језик тастатуре: чешки"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Језик тастатуре: арапски"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Језик тастатуре: дански"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Језик тастатуре: немачки"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Језик тастатуре: енглески (УК)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Језик тастатуре: француски"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Језик тастатуре: француски (Канада)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Језик тастатуре: француски (Швајц.)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Језик тастатуре: хебрејски"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Језик тастатуре: италијански"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Језик тастатуре: норвешки"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Језик тастатуре: холандски"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Језик тастатуре: пољски"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Језик тастатуре: руски"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Језик тастатуре: српски"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Језик тастатуре: шведски"</string> diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml index eaf350583..067427a4d 100644 --- a/java/res/values-sv/strings.xml +++ b/java/res/values-sv/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Knappljud"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Popup vid knapptryck"</string> <string name="general_category" msgid="1859088467017573195">"Allmänt"</string> - <string name="prediction_category" msgid="6361242011806282176">"Textkorrigering"</string> + <string name="correction_category" msgid="2236750915056607613">"Textkorrigering"</string> + <string name="ngram_category" msgid="5337109164339320257">"Förslag baserade på tidigare ord"</string> + <string name="misc_category" msgid="6894192814868233453">"Andra alternativ"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string> <string name="quick_fixes" msgid="5353213327680897927">"Snabba lösningar"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Åtgärdar automatiskt vanliga misstag"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Visa alltid"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Visa stående"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Dölj alltid"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Byt språk m. mellanslag"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Visa inställningsknapp"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatiskt"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Visa alltid"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Av"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Måttlig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramförslag"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramförslag"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Förbättra förslaget med föregående ord"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigramförslag"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Använd även föregående ord för att ge förslag"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string> <string name="label_go_key" msgid="1635148082137219148">"Kör"</string> <string name="label_next_key" msgid="362972844525672568">"Nästa"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Mer"</string> <string name="label_pause_key" msgid="181098308428035340">"Pausa"</string> <string name="label_wait_key" msgid="6402152600878093134">"Vänta"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Ta bort"</string> - <string name="description_return_key" msgid="8750044000806461678">"Retur"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Inställningar"</string> - <string name="description_shift_key" msgid="346906866277787836">"Skift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Blanksteg"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboler"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tabb"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Röstinmatning"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Aktivera symboler"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Inaktivera symboler"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Aktivera Skift"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Inaktivera Skift"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Röstindata"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Röstindata stöds inte på ditt språk än, men tjänsten fungerar på engelska."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Röstinmatning använder sig av Googles tjänst för taligenkänning. "<a href="http://m.google.com/privacy">"Sekretesspolicyn för mobila enheter"</a>" gäller."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tryck på skrivna ord om du vill korrigera dem, endast när förslag visas"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tangentbordstema"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tjeckiskt tangentbord"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabiskt tangentbord"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danskt tangentbord"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tyskt tangentbord"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelskt tangentbord (Storbrit.)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Franskt tangentbord"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Franskt tangentbord (Kanada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Franskt tangentbord (Schweiz)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebreiskt tangentbord"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italienskt tangentbord"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norskt tangentbord"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Holländskt tangentbord"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polskt tangentbord"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ryskt tangentbord"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbiskt tangentbord"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svenskt tangentbord"</string> diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml index 6dc813b74..d4b5b11fd 100644 --- a/java/res/values-th/strings.xml +++ b/java/res/values-th/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"ส่งเสียงเมื่อกดปุ่ม"</string> <string name="popup_on_keypress" msgid="123894815723512944">"ป๊อปอัปเมื่อกดแป้น"</string> <string name="general_category" msgid="1859088467017573195">"ทั่วไป"</string> - <string name="prediction_category" msgid="6361242011806282176">"การแก้ไขข้อความ"</string> + <string name="correction_category" msgid="2236750915056607613">"การแก้ไขข้อความ"</string> + <string name="ngram_category" msgid="5337109164339320257">"ข้อเสนอแนะตามคำก่อนหน้านี้"</string> + <string name="misc_category" msgid="6894192814868233453">"ตัวเลือกอื่นๆ"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string> <string name="quick_fixes" msgid="5353213327680897927">"แก้ไขด่วน"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"แก้ไขข้อผิดพลาดในการพิมพ์ที่พบบ่อย"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"แสดงทุกครั้ง"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"แสดงในโหมดแนวตั้ง"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"ซ่อนทุกครั้ง"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"ใช้แป้น Spacebar เพื่อสลับภาษา"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"แสดงแป้นการตั้งค่า"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"อัตโนมัติ"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"แสดงตลอดเวลา"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ปิด"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ปานกลาง"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"เข้มงวด"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"คำแนะนำ Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"คำแนะนำ Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"ใช้คำก่อนหน้านี้เพื่อปรับปรุงคำแนะนำ"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"การคาดคะเน Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"ใช้คำก่อนหน้านี้สำหรับการคาดคะเน"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึกแล้ว"</string> <string name="label_go_key" msgid="1635148082137219148">"ไป"</string> <string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"เพิ่มเติม"</string> <string name="label_pause_key" msgid="181098308428035340">"หยุดชั่วคราว"</string> <string name="label_wait_key" msgid="6402152600878093134">"รอ"</string> - <string name="description_delete_key" msgid="5586406298531883960">"ลบ"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"การตั้งค่า"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Space"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"สัญลักษณ์"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"ป้อนข้อมูลด้วยเสียง"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"สัญลักษณ์เปิดอยู่"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"สัญลักษณ์ปิดอยู่"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift เปิดอยู่"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift ปิดอยู่"</string> <string name="voice_warning_title" msgid="4419354150908395008">"การป้อนข้อมูลด้วยเสียง"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ขณะนี้การป้อนข้อมูลด้วยเสียงยังไม่ได้รับการสนับสนุนในภาษาของคุณ แต่ใช้ได้ในภาษาอังกฤษ"</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ป้อนข้อมูลด้วยเสียงใช้การจดจำคำพูดของ Google "<a href="http://m.google.com/privacy">" นโยบายส่วนบุคคลของมือถือ"</a>"มีผลบังคับใช้"</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"แตะคำที่ป้อนไว้เพื่อแก้ไข เฉพาะเมื่อเห็นข้อเสนอแนะเท่านั้น"</string> <string name="keyboard_layout" msgid="437433231038683666">"ชุดรูปแบบแป้นพิมพ์"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"แป้นพิมพ์ภาษาเช็ก"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"แป้นพิมพ์ภาษาอาหรับ"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"แป้นพิมพ์ภาษาเดนมาร์ก"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"แป้นพิมพ์ภาษาเยอรมัน"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"แป้นพิมพ์ภาษาอังกฤษ (สหราชอาณาจักร)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"แป้นพิมพ์ภาษาฝรั่งเศส"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"แป้นพิมพ์ภาษาฝรั่งเศส (แคนาดา)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"แป้นพิมพ์ภาษาฝรั่งเศส (สวิตเซอร์แลนด์)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"แป้นพิมพ์ภาษาฮิบรู"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"แป้นพิมพ์ภาษาอิตาลี"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"แป้นพิมพ์ภาษานอร์เวย์"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"แป้นพิมพ์ภาษาดัตช์"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"แป้นพิมพ์ภาษาโปแลนด์"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"แป้นพิมพ์ภาษารัสเซีย"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"แป้นพิมพ์ภาษาเซอร์เบีย"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"แป้นพิมพ์ภาษาสวีเดน"</string> diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml index bdd700b67..6f4fd81e9 100644 --- a/java/res/values-tl/strings.xml +++ b/java/res/values-tl/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Tunog sa keypress"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Popup sa keypress"</string> <string name="general_category" msgid="1859088467017573195">"Pangkalahatan"</string> - <string name="prediction_category" msgid="6361242011806282176">"Pagwawasto ng teksto"</string> + <string name="correction_category" msgid="2236750915056607613">"Pagwawasto ng teksto"</string> + <string name="ngram_category" msgid="5337109164339320257">"Mga suhestiyon batay sa mga nakaraang salita"</string> + <string name="misc_category" msgid="6894192814868233453">"Iba pang mga pagpipilian"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string> <string name="quick_fixes" msgid="5353213327680897927">"Mga mabilisang pagsasaayos"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Itinatama ang mga karaniwang na-type na mali"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Palaging ipakita"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Ipakita sa portrait mode"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Palaging itago"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Gamitin ang panglipat ng wika sa spacebar"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Ipakita ang key ng mga setting"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Awtomatiko"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Palaging ipakita"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Naka-off"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresibo"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Mga Suhestiyon na Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Mga bigram na suhestiyon"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gamitin ang nakaraang salita upang pahusayin ang suhestiyon"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram na hula"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gamitin ang nakaraang salita para din sa hula"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Na-save"</string> <string name="label_go_key" msgid="1635148082137219148">"Punta"</string> <string name="label_next_key" msgid="362972844525672568">"Susunod"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Higit pa"</string> <string name="label_pause_key" msgid="181098308428035340">"Pause"</string> <string name="label_wait_key" msgid="6402152600878093134">"Intay"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Tanggalin"</string> - <string name="description_return_key" msgid="8750044000806461678">"Bumalik"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Mga Setting"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Puwang"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Mga Simbolo"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Input ng Boses"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Naka-on ang mga simbolo"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Naka-off ang mga simbolo"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Naka-on ang shift"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Naka-off ang shift"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Pag-input ng boses"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Hindi kasalukuyang suportado ang pag-input ng boses para sa iyong wika, ngunit gumagana sa Ingles."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Gumagamit ang pag-input ng boses ng speech recognition ng Google. Nalalapat "<a href="http://m.google.com/privacy">"Ang Patakaran sa Privacy ng Mobile"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Pindutin ang mga inilagay na salita upang iwasto ang mga ito, kapag nakikita lang ang mga suhestiyon"</string> <string name="keyboard_layout" msgid="437433231038683666">"Tema ng Keyboard"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Czech na Keyboard"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabic na Keyboard"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danish na Keyboard"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"German na Keyboard"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Ingles (UK) na Keyboard"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"French na Keyboard"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"French (Canada) na Keyboard"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"French (Switzerland) na Keyboard"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrew na Keyboard"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italian na Keyboard"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norwegian na Keyboard"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Dutch na Keyboard"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polish na Keyboard"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russian na Keyboard"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbian na Keyboard"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Swedish na Keyboard"</string> diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml index a88b50960..1dfb2e905 100644 --- a/java/res/values-tr/strings.xml +++ b/java/res/values-tr/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Tuşa basıldığında ses çıkar"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Tuşa basıldığında pop-up aç"</string> <string name="general_category" msgid="1859088467017573195">"Genel"</string> - <string name="prediction_category" msgid="6361242011806282176">"Metin düzeltme"</string> + <string name="correction_category" msgid="2236750915056607613">"Metin düzeltme"</string> + <string name="ngram_category" msgid="5337109164339320257">"Önceki kelimelere dayalı öneriler"</string> + <string name="misc_category" msgid="6894192814868233453">"Diğer seçenekler"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</string> <string name="quick_fixes" msgid="5353213327680897927">"Hızlı onarımlar"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Yaygın olarak yapılan yazım hatalarını düzeltir"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Her zaman göster"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Dikey modda göster"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Her zaman gizle"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Dil geçişi > boşluk çubuğuyla"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Ayarları göster tuşu"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Otomatik"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Her zaman göster"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Kapalı"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ölçülü"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram Önerileri"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram önerileri"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Öneriyi geliştirmek için önceki kelimeyi kullanın"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Bigram tahmini"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Önceki kelimeyi de tahmin için kullan"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string> <string name="label_go_key" msgid="1635148082137219148">"Git"</string> <string name="label_next_key" msgid="362972844525672568">"İleri"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Diğer"</string> <string name="label_pause_key" msgid="181098308428035340">"Durkl"</string> <string name="label_wait_key" msgid="6402152600878093134">"Bekle"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Sil"</string> - <string name="description_return_key" msgid="8750044000806461678">"Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Ayarlar"</string> - <string name="description_shift_key" msgid="346906866277787836">"Üst Karakter"</string> - <string name="description_space_key" msgid="8512130111575878517">"Boşluk"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simgeler"</string> - <string name="description_tab_key" msgid="828186583738307137">"Sekme"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Ses Girişi"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Simgeler açık"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Simgeler kapalı"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Üst Karakter açık"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Üst Karakter kapalı"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Ses girişi"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Ses girişi, şu anda sizin diliniz için desteklenmiyor ama İngilizce dilinde kullanılabilir."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Ses girişi Google\'ın konuşma tanıma işlevini kullanır. "<a href="http://m.google.com/privacy">" Mobil Gizlilik Politikası"</a>" geçerlidir."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Yalnızca öneriler görünür olduğunda, düzeltmek için girilen kelimelere dokunun"</string> <string name="keyboard_layout" msgid="437433231038683666">"Klavye Teması"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Çekçe Klavye"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arapça Klavye"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danca Klavye"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Almanca Klavye"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"İngilizce (İngiltere) Klavye"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Fransızca Klavye"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Fransızca (Kanada) Klavye"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Fransızca (İsviçre) Klavye"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"İbranice Klavye"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"İtalyanca Klavye"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norveççe Klavye"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Felemenkçe Klavye"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Lehçe Klavye"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Rusça Klavye"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Sırpça Klavye"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"İsveççe Klavye"</string> diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml index 5010ee9b5..b935e90f7 100644 --- a/java/res/values-uk/strings.xml +++ b/java/res/values-uk/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натиску клав."</string> <string name="popup_on_keypress" msgid="123894815723512944">"Сплив. при нат.клав."</string> <string name="general_category" msgid="1859088467017573195">"Загальні"</string> - <string name="prediction_category" msgid="6361242011806282176">"Виправлення тексту"</string> + <string name="correction_category" msgid="2236750915056607613">"Виправлення тексту"</string> + <string name="ngram_category" msgid="5337109164339320257">"Пропозиції на основі попередніх слів"</string> + <string name="misc_category" msgid="6894192814868233453">"Інші опції"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string> <string name="quick_fixes" msgid="5353213327680897927">"Шв. виправлення"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Виправляє поширені помилки"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Завжди показувати"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Показувати в книжковому режимі"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Завжди ховати"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Використ. зміну мови пробілом"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Показ. клав. налашт."</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматично"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Завжди показ."</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Вимк."</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Середнє"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Повне"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Двобуквені пропозиції"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Пропозиції з двох слів"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Викор. попер. слово для покращ. пропозиції"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Передбачений запит із двох слів"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Використовувати попереднє слово також як передбачений запит"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string> <string name="label_go_key" msgid="1635148082137219148">"Іти"</string> <string name="label_next_key" msgid="362972844525672568">"Далі"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Більше"</string> <string name="label_pause_key" msgid="181098308428035340">"Пауза"</string> <string name="label_wait_key" msgid="6402152600878093134">"Чек."</string> - <string name="description_delete_key" msgid="5586406298531883960">"Клавіша Delete"</string> - <string name="description_return_key" msgid="8750044000806461678">"Клавіша Return"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Клавіша Settings"</string> - <string name="description_shift_key" msgid="346906866277787836">"Клавіша Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Клавіша Space"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Клавіша Symbols"</string> - <string name="description_tab_key" msgid="828186583738307137">"Клавіша Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Клавіша Voice Input"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Символи ввімкнено"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Символи вимкнено"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift увімкнено"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift вимкнено"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Голос. ввід"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Голос. ввід наразі не підтрим. для вашої мови, але можна користуватися англійською."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Голосовий ввід використовує розпізнавання мовлення Google. Застосовується "<a href="http://m.google.com/privacy">"Політика конфіденційності для мобільних пристроїв"</a>"."</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Торкніться введених слів, щоб виправити їх, лише коли ввімкнено пропозиції"</string> <string name="keyboard_layout" msgid="437433231038683666">"Тема клавіатури"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Чеська розкладка"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Розкладка для арабської мови"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Данська розкладка"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Німецька розкладка"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Англ. розкладка (Великобританія)"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Французька розкладка"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Французька розкладка (Канада)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Французька розкладка (Швейцарія)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Розкладка для івриту"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Італійська розкладка"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Норвезька розкладка"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Голланд. розклад."</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Польська розкладка"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Російська розкладка"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Сербська розкладка"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Шведська розкладка"</string> diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml index 8dac2f922..53bd16a48 100644 --- a/java/res/values-vi/strings.xml +++ b/java/res/values-vi/strings.xml @@ -27,7 +27,14 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"Âm thanh khi nhấn phím"</string> <string name="popup_on_keypress" msgid="123894815723512944">"Cửa sổ bật lên khi nhấn phím"</string> <string name="general_category" msgid="1859088467017573195">"Chung"</string> - <string name="prediction_category" msgid="6361242011806282176">"Sửa văn bản"</string> + <string name="correction_category" msgid="2236750915056607613">"Sửa văn bản"</string> + <string name="ngram_category" msgid="5337109164339320257">"Đề xuất dựa trên các từ trước đó"</string> + <string name="misc_category" msgid="6894192814868233453">"Tùy chọn khác"</string> + <string name="advanced_settings" msgid="362895144495591463">"Cài đặt nâng cao"</string> + <string name="advanced_settings_summary" msgid="5193513161106637254">"Tùy chọn cho người dùng chuyên gia"</string> + <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Hlại việc l.bỏ csổ b.lên chính"</string> + <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Không có tgian trễ"</string> + <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Mặc định"</string> <string name="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</string> <string name="quick_fixes" msgid="5353213327680897927">"Sửa nhanh"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"Sửa lỗi nhập thông thường"</string> @@ -36,6 +43,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Luôn hiển thị"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Hiển thị trên chế độ khổ đứng"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Luôn ẩn"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Sử dụng trình chuyển đổi ngôn ngữ thanh cách"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"Hiển thị phím cài đặt"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Tự động"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Luôn hiển thị"</string> @@ -45,8 +53,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Tắt"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Đơn giản"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Linh hoạt"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"Đề xuất Bigram"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"Đề xuất Bigram"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Sử dụng từ trước đó để cải tiến đề xuất"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"Dự đoán Bigram"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"Cũng sử dụng từ trước đó để dự đoán"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Đã lưu"</string> <string name="label_go_key" msgid="1635148082137219148">"Đến"</string> <string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string> @@ -56,18 +66,6 @@ <string name="label_more_key" msgid="3760239494604948502">"Khác"</string> <string name="label_pause_key" msgid="181098308428035340">"Tạm dừng"</string> <string name="label_wait_key" msgid="6402152600878093134">"Đợi"</string> - <string name="description_delete_key" msgid="5586406298531883960">"Xóa"</string> - <string name="description_return_key" msgid="8750044000806461678">"Quay lại"</string> - <string name="description_settings_key" msgid="7484527796782969219">"Cài đặt"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"Dấu cách"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Biểu tượng"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"Nhập liệu bằng giọng nói"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"Bật biểu tượng"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"Tắt biểu tượng"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Bật Shift"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Tắt Shift"</string> <string name="voice_warning_title" msgid="4419354150908395008">"Nhập liệu bằng giọng nói"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Nhập liệu bằng giọng nói hiện không được hỗ trợ cho ngôn ngữ của bạn nhưng hoạt động với ngôn ngữ tiếng Anh."</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Nhập liệu bằng giọng nói sử dụng nhận dạng giọng nói của Google. Áp dụng "<a href="http://m.google.com/privacy">"Chính sách bảo mật dành cho điện thoại di động"</a>"."</string> @@ -106,6 +104,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Chạm các từ đã nhập để sửa, chỉ khi các đề xuất hiển thị"</string> <string name="keyboard_layout" msgid="437433231038683666">"Chủ đề bàn phím"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Bàn phím tiếng Séc"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Bàn phím tiếng Ả Rập"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Bàn phím tiếng Đan Mạch"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Bàn phím tiếng Đức"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Bàn phím tiếng Anh (Anh)"</string> @@ -114,9 +113,12 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Bàn phím tiếng Pháp"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Bàn phím tiếng Pháp (Canada)"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Bàn phím tiếng Pháp (Thụy Sĩ)"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Bàn phím tiếng Do Thái"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Bàn phím tiếng Ý"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Bàn phím tiếng Na Uy"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Bàn phím tiếng Hà Lan"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Bàn phím tiếng Ba Lan"</string> + <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Bàn phím tiếng Bồ Đào Nha"</string> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Bàn phím tiếng Nga"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Bàn phím tiếng Serbia"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Bàn phím tiếng Thụy Điển"</string> diff --git a/java/res/values-xlarge-land/dimens.xml b/java/res/values-xlarge-land/dimens.xml index 625dd263c..65fd29d81 100644 --- a/java/res/values-xlarge-land/dimens.xml +++ b/java/res/values-xlarge-land/dimens.xml @@ -19,8 +19,9 @@ --> <resources> - <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 --> + <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=14.5mm --> <dimen name="keyboardHeight">58.0mm</dimen> + <fraction name="minKeyboardHeight">45%p</fraction> <!-- key_height + key_bottom_gap = popup_key_height --> <!-- <dimen name="key_height">14.5mm</dimen> --> <dimen name="key_bottom_gap">0.0mm</dimen> @@ -28,12 +29,14 @@ <dimen name="popup_key_height">13.0mm</dimen> <dimen name="keyboard_top_padding">1.1mm</dimen> <dimen name="keyboard_bottom_padding">0.0mm</dimen> - <!-- key_height x 1.0 --> - <dimen name="key_preview_height">13.0mm</dimen> + <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen> - <dimen name="key_letter_size">28dip</dimen> - <dimen name="key_label_text_size">20dip</dimen> + <fraction name="key_letter_ratio">30.7%</fraction> + <fraction name="key_label_text_ratio">21.9%</fraction> <!-- left or right padding of label alignment --> <dimen name="key_label_horizontal_alignment_padding">18dip</dimen> + <dimen name="key_preview_height_holo">26.5mm</dimen> + <dimen name="key_preview_offset_holo">7.5mm</dimen> + <dimen name="candidate_strip_padding">40.0mm</dimen> </resources> diff --git a/java/res/values-xlarge/config.xml b/java/res/values-xlarge/config.xml index f075b1b50..663332fe1 100644 --- a/java/res/values-xlarge/config.xml +++ b/java/res/values-xlarge/config.xml @@ -20,9 +20,9 @@ <resources> <bool name="config_enable_show_settings_key_option">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_popup_on_keypress_option">false</bool> + <!-- TODO: This configuration value is temporary set true to check popup preview behavior. --> + <bool name="config_enable_show_popup_on_keypress_option">true</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> @@ -36,10 +36,11 @@ <bool name="config_use_spacebar_language_switcher">false</bool> <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false --> <bool name="config_show_mini_keyboard_at_touched_point">true</bool> - <!-- The language is never displayed if == 0, always displayed if < 0 --> - <integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer> + <integer name="config_delay_update_suggestions">180</integer> <!-- 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_text_size_of_language_on_spacebar" translatable="false">medium</string> <integer name="config_max_popup_keyboard_column">5</integer> + <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" --> + <integer name="log_screen_metrics">2</integer> </resources> diff --git a/java/res/values-xlarge/dimens.xml b/java/res/values-xlarge/dimens.xml index 69283202e..37cfc9dfd 100644 --- a/java/res/values-xlarge/dimens.xml +++ b/java/res/values-xlarge/dimens.xml @@ -19,8 +19,9 @@ --> <resources> - <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 --> + <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=12mm --> <dimen name="keyboardHeight">48.0mm</dimen> + <fraction name="minKeyboardHeight">-35.0%p</fraction> <!-- key_height + key_bottom_gap = popup_key_height --> <!-- <dimen name="key_height">14.5mm</dimen> --> <dimen name="key_bottom_gap">0.0mm</dimen> @@ -28,8 +29,8 @@ <dimen name="popup_key_height">10.0mm</dimen> <dimen name="keyboard_top_padding">1.1mm</dimen> <dimen name="keyboard_bottom_padding">0.0mm</dimen> - <!-- key_height x 1.0 --> - <dimen name="key_preview_height">13.0mm</dimen> + <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen> + <dimen name="mini_keyboard_horizontal_padding_holo">40dip</dimen> <dimen name="mini_keyboard_key_horizontal_padding">12dip</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> @@ -37,15 +38,20 @@ <!-- popup_key_height x -1.0 --> <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen> - <dimen name="key_letter_size">26dip</dimen> - <dimen name="key_label_text_size">16dip</dimen> - <dimen name="key_preview_text_size_large">24dip</dimen> + <fraction name="key_letter_ratio">34.4%</fraction> + <fraction name="key_label_text_ratio">21.2%</fraction> <!-- left or right padding of label alignment --> <dimen name="key_label_horizontal_alignment_padding">6dip</dimen> + <fraction name="key_preview_text_ratio">26.3%</fraction> + <dimen name="key_preview_height_holo">23.0mm</dimen> + <dimen name="key_preview_offset_holo">8.0mm</dimen> <dimen name="candidate_strip_height">46dip</dimen> + <!-- candidate_strip_minimum_height = + key_preview_height_holo - key_preview_offset_holo + alpha --> + <dimen name="candidate_strip_minimum_height">18mm</dimen> <dimen name="candidate_strip_padding">15.0mm</dimen> - <dimen name="candidate_min_width">0.3in</dimen> - <dimen name="candidate_padding">12dip</dimen> + <dimen name="candidate_min_width">46dip</dimen> + <dimen name="candidate_padding">8dip</dimen> <dimen name="candidate_text_size">22dip</dimen> </resources> diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml index 9d7689153..c1b99fc96 100644 --- a/java/res/values-zh-rCN/strings.xml +++ b/java/res/values-zh-rCN/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"按键时播放音效"</string> <string name="popup_on_keypress" msgid="123894815723512944">"按键时显示弹出窗口"</string> <string name="general_category" msgid="1859088467017573195">"常规"</string> - <string name="prediction_category" msgid="6361242011806282176">"文本更正"</string> + <string name="correction_category" msgid="2236750915056607613">"文本更正"</string> + <string name="ngram_category" msgid="5337109164339320257">"根据前面的字词提供建议"</string> + <string name="misc_category" msgid="6894192814868233453">"其他选项"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"自动大写"</string> <string name="quick_fixes" msgid="5353213327680897927">"快速纠正"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"纠正常见的输入错误"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"始终显示"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"以纵向模式显示"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"始终隐藏"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"使用空格键切换语言"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"显示设置键"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自动"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"始终显示"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"关闭"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"部分"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"全部"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"双连词建议"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"双连词建议"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"使用以前的字词改进建议"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"双连词预测"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"结合前一个字词进行预测"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已保存"</string> <string name="label_go_key" msgid="1635148082137219148">"开始"</string> <string name="label_next_key" msgid="362972844525672568">"下一步"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"更多"</string> <string name="label_pause_key" msgid="181098308428035340">"暂停"</string> <string name="label_wait_key" msgid="6402152600878093134">"等待"</string> - <string name="description_delete_key" msgid="5586406298531883960">"删除"</string> - <string name="description_return_key" msgid="8750044000806461678">"回车"</string> - <string name="description_settings_key" msgid="7484527796782969219">"设置"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift"</string> - <string name="description_space_key" msgid="8512130111575878517">"空格"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"符号"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab"</string> - <string name="description_voice_key" msgid="3057731675774652754">"语音输入"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"符号模式已打开"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"符号模式已关闭"</string> - <string name="description_shift_on" msgid="6983188949895971587">"Shift 模式已打开"</string> - <string name="description_shift_off" msgid="8553265474523069034">"Shift 模式已关闭"</string> <string name="voice_warning_title" msgid="4419354150908395008">"语音输入"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"语音输入功能当前还不支持您的语言,您只能输入英语语音。"</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"语音输入采用了 Google 的语音识别技术,因此请遵守"<a href="http://m.google.com/privacy">"“Google 移动”隐私权政策"</a>"。"</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"仅在系统显示建议后,才触摸输入的字词进行更正"</string> <string name="keyboard_layout" msgid="437433231038683666">"键盘主题"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"捷克语键盘"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"阿拉伯语键盘"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"丹麦语键盘"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"德语键盘"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"英语(英国)键盘"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"法语键盘"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"法语(加拿大)键盘"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"法语(瑞士)键盘"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"希伯来语键盘"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"意大利语键盘"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"挪威语键盘"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"荷兰语键盘"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"波兰语键盘"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"俄语键盘"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"塞尔维亚语键盘"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"瑞典语键盘"</string> diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml index 9ba728461..667934547 100644 --- a/java/res/values-zh-rTW/strings.xml +++ b/java/res/values-zh-rTW/strings.xml @@ -27,7 +27,19 @@ <string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</string> <string name="popup_on_keypress" msgid="123894815723512944">"按鍵時顯示彈出式視窗"</string> <string name="general_category" msgid="1859088467017573195">"一般設定"</string> - <string name="prediction_category" msgid="6361242011806282176">"文字修正"</string> + <string name="correction_category" msgid="2236750915056607613">"文字修正"</string> + <string name="ngram_category" msgid="5337109164339320257">"根據先前字詞產生的建議"</string> + <string name="misc_category" msgid="6894192814868233453">"其他選項"</string> + <!-- no translation found for advanced_settings (362895144495591463) --> + <skip /> + <!-- no translation found for advanced_settings_summary (5193513161106637254) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) --> + <skip /> + <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) --> + <skip /> <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string> <string name="quick_fixes" msgid="5353213327680897927">"快速修正"</string> <string name="quick_fixes_summary" msgid="3405028402510332373">"修正一般打字錯誤"</string> @@ -36,6 +48,7 @@ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"一律顯示"</string> <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"以垂直模式顯示"</string> <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"永遠隱藏"</string> + <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"使用空白鍵切換語言"</string> <string name="prefs_settings_key" msgid="4623341240804046498">"顯示設定金鑰"</string> <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自動"</string> <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"一律顯示"</string> @@ -45,8 +58,10 @@ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"關閉"</string> <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"部分"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"全部"</string> - <string name="bigram_suggestion" msgid="1323347224043514969">"雙連詞建議"</string> + <string name="bigram_suggestion" msgid="2636414079905220518">"雙連詞建議"</string> <string name="bigram_suggestion_summary" msgid="4383845146070101531">"根據前一個字詞自動找出更適合的建議"</string> + <string name="bigram_prediction" msgid="8914273444762259739">"雙連詞預測"</string> + <string name="bigram_prediction_summary" msgid="1747261921174300098">"同樣使用先前的字詞進行預測"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string> <string name="label_go_key" msgid="1635148082137219148">"開始"</string> <string name="label_next_key" msgid="362972844525672568">"繼續"</string> @@ -56,18 +71,6 @@ <string name="label_more_key" msgid="3760239494604948502">"更多"</string> <string name="label_pause_key" msgid="181098308428035340">"暫停"</string> <string name="label_wait_key" msgid="6402152600878093134">"等候"</string> - <string name="description_delete_key" msgid="5586406298531883960">"刪除"</string> - <string name="description_return_key" msgid="8750044000806461678">"返回"</string> - <string name="description_settings_key" msgid="7484527796782969219">"設定"</string> - <string name="description_shift_key" msgid="346906866277787836">"Shift 鍵"</string> - <string name="description_space_key" msgid="8512130111575878517">"空白鍵"</string> - <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"符號"</string> - <string name="description_tab_key" msgid="828186583738307137">"Tab 鍵"</string> - <string name="description_voice_key" msgid="3057731675774652754">"語音輸入"</string> - <string name="description_symbols_on" msgid="2994366855822840559">"開啟符號"</string> - <string name="description_symbols_off" msgid="3209578267079515136">"關閉符號"</string> - <string name="description_shift_on" msgid="6983188949895971587">"開啟位移"</string> - <string name="description_shift_off" msgid="8553265474523069034">"關閉位移"</string> <string name="voice_warning_title" msgid="4419354150908395008">"語音輸入"</string> <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"語音輸入目前不支援您的語言,但是可以辨識英文。"</string> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"語音輸入使用 Google 的語音辨識功能,並遵循《"<a href="http://m.google.com/privacy">"行動服務隱私權政策"</a>"》。"</string> @@ -106,6 +109,7 @@ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"輕觸輸入的字詞即可加以修正 (出現建議時才適用)"</string> <string name="keyboard_layout" msgid="437433231038683666">"鍵盤主題"</string> <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"捷克文鍵盤"</string> + <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"阿拉伯文鍵盤"</string> <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"丹麥文鍵盤"</string> <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"德文鍵盤"</string> <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"英文 (英國) 鍵盤"</string> @@ -114,9 +118,13 @@ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"法文鍵盤"</string> <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"法文 (加拿大) 鍵盤"</string> <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"法文 (瑞士) 鍵盤"</string> + <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"希伯來文鍵盤"</string> <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"義大利文鍵盤"</string> <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"挪威文鍵盤"</string> <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"荷蘭文鍵盤"</string> + <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"波蘭文鍵盤"</string> + <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) --> + <skip /> <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"俄文鍵盤"</string> <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"塞爾維亞文鍵盤"</string> <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"瑞典文語音"</string> diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index f0da2744b..f03da4f8f 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -25,11 +25,13 @@ checkable+checked+pressed. --> <attr name="keyBackground" format="reference" /> - <!-- Size of the text for one letter character keys. --> - <attr name="keyLetterSize" format="dimension" /> + <!-- Size of the text for one letter character keys, in the proportion of key height. + --> + <attr name="keyLetterRatio" format="float" /> - <!-- Size of the text for custom keys with some text and no icon. --> - <attr name="labelTextSize" format="dimension" /> + <!-- Size of the text for custom keys with some text and no icon, in the proportion of key + height. --> + <attr name="labelTextRatio" format="float" /> <!-- Color to use for the label in a key. --> <attr name="keyTextColor" format="color" /> @@ -80,6 +82,9 @@ <attr name="keyboardHeight" format="dimension" /> <!-- Maximum keyboard height, in pixels or percentage of display height --> <attr name="maxKeyboardHeight" format="dimension|fraction" /> + <!-- Minimum keyboard height represented in pixels, percentage of display height if fraction + is positive, or percentage of display width if fraction is negative. --> + <attr name="minKeyboardHeight" format="dimension|fraction" /> <!-- Default width of a key, in pixels or percentage of display width. --> <attr name="keyWidth" format="dimension|fraction" /> <!-- Default height of a row (key height + vertical gap), in pixels or percentage of @@ -91,6 +96,8 @@ <attr name="verticalGap" format="dimension|fraction" /> <!-- Popup keyboard layout template --> <attr name="popupKeyboardTemplate" format="reference" /> + <!-- Locale of the keyboard layout --> + <attr name="keyboardLocale" format="string" /> </declare-styleable> <declare-styleable name="Keyboard_Key"> @@ -107,8 +114,8 @@ <!-- Key is anchored to the right of the keyboard. --> <flag name="right" value="2" /> </attr> - <!-- Whether this is a modifier key such as Alt or Shift. --> - <attr name="isModifier" format="boolean" /> + <!-- Whether this is a functional key which has different key top than normal key. --> + <attr name="isFunctional" format="boolean" /> <!-- Whether this is a toggle key. --> <attr name="isSticky" format="boolean" /> <!-- Whether long-pressing on this key will make it repeat. --> @@ -142,6 +149,9 @@ <attr name="shiftedIcon" format="reference" /> <!-- The key is enabled and responds on press. --> <attr name="enabled" format="boolean" /> + <!-- Visual insets --> + <attr name="visualInsetsLeft" format="dimension|fraction" /> + <attr name="visualInsetsRight" format="dimension|fraction" /> </declare-styleable> <declare-styleable name="Keyboard_Row"> diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml index 741171f88..733a464cc 100644 --- a/java/res/values/colors.xml +++ b/java/res/values/colors.xml @@ -21,7 +21,6 @@ <color name="candidate_normal">#FFFFFFFF</color> <color name="candidate_recommended">#FFFCAE00</color> <color name="candidate_other">#FFFCAE00</color> - <color name="latinkeyboard_transparent">#00000000</color> <color name="latinkeyboard_bar_language_shadow_white">#80000000</color> <color name="latinkeyboard_bar_language_shadow_black">#80FFFFFF</color> <color name="latinkeyboard_bar_language_text">#FFC0C0C0</color> diff --git a/java/res/values/config.xml b/java/res/values/config.xml index 7c100c367..c61a6d52a 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -21,7 +21,6 @@ <resources> <bool name="config_swipeDisambiguation">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_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> @@ -36,20 +35,28 @@ <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> + <!-- Default value for bigram suggestion: while showing candidates for a word should we weigh + in the previous word? --> <bool name="config_default_bigram_suggestions">true</bool> + <!-- Default value for bigram prediction: after entering a word and a space only, should we look + at input history to suggest a hopefully helpful candidate for the next word? --> + <bool name="config_default_bigram_prediction">false</bool> <bool name="config_default_recorrection_enabled">true</bool> <bool name="config_default_sound_enabled">false</bool> <bool name="config_use_spacebar_language_switcher">true</bool> <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false --> <bool name="config_show_mini_keyboard_at_touched_point">false</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_delay_before_fadeout_language_on_spacebar">1200</integer> + <integer name="config_delay_update_suggestions">100</integer> + <integer name="config_delay_update_old_suggestions">300</integer> + <integer name="config_delay_update_shift_state">100</integer> <integer name="config_duration_of_fadeout_language_on_spacebar">50</integer> - <integer name="config_final_fadeout_percentage_of_language_on_spacebar">15</integer> + <integer name="config_final_fadeout_percentage_of_language_on_spacebar">50</integer> <integer name="config_delay_before_preview">0</integer> - <integer name="config_delay_after_preview">10</integer> - <integer name="config_preview_fadein_anim_time">0</integer> - <integer name="config_preview_fadeout_anim_time">70</integer> + <integer name="config_delay_after_preview">70</integer> + <integer name="config_mini_keyboard_fadein_anim_time">0</integer> + <integer name="config_mini_keyboard_fadeout_anim_time">100</integer> <integer name="config_delay_before_key_repeat_start">400</integer> <integer name="config_key_repeat_interval">50</integer> <integer name="config_keyboard_grid_width">32</integer> @@ -73,4 +80,7 @@ will be subject to auto-correction. --> <item>0</item> </string-array> + <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" --> + <integer name="log_screen_metrics">0</integer> + <bool name="config_require_umlaut_processing">false</bool> </resources> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index d28b9232b..e26cad3f2 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -19,41 +19,49 @@ --> <resources> - <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 --> - <dimen name="keyboardHeight">1.265in</dimen> + <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.295in --> + <dimen name="keyboardHeight">1.285in</dimen> + <fraction name="maxKeyboardHeight">50%p</fraction> + <fraction name="minKeyboardHeight">-61.8%p</fraction> <!-- key_height + key_bottom_gap = popup_key_height --> - <!-- <dimen name="key_height">0.290in</dimen> --> + <!-- <dimen name="key_height">0.295in</dimen> --> <dimen name="key_bottom_gap">0.035in</dimen> <dimen name="key_horizontal_gap">0.000in</dimen> - <dimen name="popup_key_height">0.325in</dimen> + <dimen name="popup_key_height">0.330in</dimen> <dimen name="keyboard_top_padding">0.00in</dimen> <dimen name="keyboard_bottom_padding">0.06in</dimen> - <!-- key_preview_text_size_large x 2 --> - <dimen name="key_preview_height">80sp</dimen> + <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen> + <dimen name="mini_keyboard_horizontal_padding">16dip</dimen> + <dimen name="mini_keyboard_horizontal_padding_holo">32dip</dimen> <dimen name="mini_keyboard_key_horizontal_padding">8dip</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> - <dimen name="mini_keyboard_slide_allowance">0.390in</dimen> + <dimen name="mini_keyboard_slide_allowance">0.396in</dimen> <!-- popup_key_height x -1.0 --> - <dimen name="mini_keyboard_vertical_correction">-0.325in</dimen> - - <dimen name="key_letter_size">0.13in</dimen> - <dimen name="key_label_text_size">0.083in</dimen> - <dimen name="key_preview_text_size_large">40sp</dimen> - <!-- left or right padding of label alignment --> - <dimen name="key_label_horizontal_alignment_padding">0.13in</dimen> - <dimen name="key_preview_offset">0.000in</dimen> + <dimen name="mini_keyboard_vertical_correction">-0.330in</dimen> <!-- We use "inch", not "dip" because this value tries dealing with physical distance related to user's finger. --> <dimen name="keyboard_vertical_correction">-0.05in</dimen> + <fraction name="key_letter_ratio">45%</fraction> + <fraction name="key_label_text_ratio">29%</fraction> + <!-- left or right padding of label alignment --> + <dimen name="key_label_horizontal_alignment_padding">21dip</dimen> + <dimen name="key_preview_height">80sp</dimen> + <dimen name="key_preview_offset">0.1in</dimen> + <fraction name="key_preview_text_ratio">82%</fraction> + <dimen name="key_preview_height_holo">130sp</dimen> + <dimen name="key_preview_offset_holo">0.193in</dimen> + <dimen name="candidate_strip_height">42dip</dimen> + <!-- candidate_strip_minimum_height = + key_preview_height_holo - key_preview_offset_holo + alpha --> + <dimen name="candidate_strip_minimum_height">100sp</dimen> <dimen name="candidate_strip_fading_edge_length">63dip</dimen> <dimen name="candidate_strip_padding">0dip</dimen> - <dimen name="candidate_min_width">0.3in</dimen> + <dimen name="candidate_min_width">32dip</dimen> <dimen name="candidate_padding">6dip</dimen> <dimen name="candidate_text_size">18dip</dimen> - <dimen name="spacebar_vertical_correction">4dip</dimen> <!-- If the screen height in landscape is larger than the below value, then the keyboard will not go into extract (fullscreen) mode. --> <dimen name="max_height_for_fullscreen">2.5in</dimen> diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 6a1069e99..1cdae3d81 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -18,12 +18,19 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Symbols that are commonly considered word separators in this language --> - <string name="word_separators">.\u0009\u0020,;:!?\n()[]*&@{}/<>_+=|\u0022</string> - <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. --> - <string name="sentence_separators">.,!?)</string> <!-- Symbols that are suggested between words --> <string name="suggested_punctuations">!?,\u0022\u0027:();-/@_</string> + <!-- Symbols that should be swapped with a magic space --> + <string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string> + <!-- Symbols that should strip a magic space --> + <string name="magic_space_stripping_symbols">\u0009\u0020\n/_\u0027-</string> + <!-- Symbols that should convert magic spaces into real space --> + <string name="magic_space_promoting_symbols">([*&@{<>+=|</string> + <!-- Symbols that do NOT separate words --> + <string name="non_word_separator_symbols">\u0027-</string> + <!-- Word separator list is the union of all symbols except those that are not separators: + magic_space_swapping_symbols | magic_space_stripping_symbols | + magic_space_neutral_symbols \ non_word_separator_symbols --> <!-- Label for ALT modifier key. Must be short to fit on key! --> <string name="label_alt_key">ALT</string> diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml index d6f9bfc28..ee345291a 100644 --- a/java/res/values/keycodes.xml +++ b/java/res/values/keycodes.xml @@ -26,26 +26,6 @@ <integer name="key_shift">-1</integer> <integer name="key_switch_alpha_symbol">-2</integer> <integer name="key_delete">-5</integer> - <integer name="key_settings">-100</integer> - <integer name="key_voice">-102</integer> - - <!-- Array used for mapping key codes to description strings. --> - <array name="key_descriptions"> - <item>@integer/key_tab</item> - <item>@string/description_tab_key</item> - <item>@integer/key_return</item> - <item>@string/description_return_key</item> - <item>@integer/key_space</item> - <item>@string/description_space_key</item> - <item>@integer/key_shift</item> - <item>@string/description_shift_key</item> - <item>@integer/key_switch_alpha_symbol</item> - <item>@string/description_switch_alpha_symbol_key</item> - <item>@integer/key_delete</item> - <item>@string/description_delete_key</item> - <item>@integer/key_settings</item> - <item>@string/description_settings_key</item> - <item>@integer/key_voice</item> - <item>@string/description_voice_key</item> - </array> + <integer name="key_settings">-6</integer> + <integer name="key_shortcut">-8</integer> </resources> diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index ac14a2082..b75b21a84 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -38,7 +38,25 @@ <string name="general_category">General</string> <!-- Category title for text prediction --> - <string name="prediction_category">Text correction</string> + <string name="correction_category">Text correction</string> + + <!-- Category title for ngrams --> + <string name="ngram_category">Suggestions based on previous words</string> + + <!-- Category title for misc options --> + <string name="misc_category">Other options</string> + + <!-- Option name for advanced settings screen [CHAR LIMIT=25] --> + <string name="advanced_settings">Advanced settings</string> + <!-- Option summary for advanced settings screen [CHAR LIMIT=65 (two lines) or 30 (fits on one line, preferable)] --> + <string name="advanced_settings_summary">Options for expert users</string> + + <!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] --> + <string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string> + <!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] --> + <string name="key_preview_popup_dismiss_no_delay">No delay</string> + <!-- Description for delay for dismissing a popup on screen: default value of the delay [CHAR LIMIT=15] --> + <string name="key_preview_popup_dismiss_default_delay">Default</string> <!-- Option to enable auto capitalization of sentences --> <string name="auto_cap">Auto-capitalization</string> @@ -55,6 +73,8 @@ <string name="prefs_suggestion_visibility_show_name">Always show</string> <string name="prefs_suggestion_visibility_show_only_portrait_name">Show on portrait mode</string> <string name="prefs_suggestion_visibility_hide_name">Always hide</string> + <!-- Option to enable spacebar language switcher [CHAR LIMIT=20]--> + <string name="prefs_use_spacebar_language_switch">Use the spacebar language switcher</string> <!-- Option to show/hide the settings key --> <string name="prefs_settings_key">Show settings key</string> @@ -78,9 +98,13 @@ <string name="auto_correction_threshold_mode_aggeressive">Aggressive</string> <!-- Option to enable bigram correction --> - <string name="bigram_suggestion">Bigram Suggestions</string> + <string name="bigram_suggestion">Bigram suggestions</string> <!-- Description for auto correction --> <string name="bigram_suggestion_summary">Use previous word to improve suggestion</string> + <!-- Option to enable using user-history bigram when no input --> + <string name="bigram_prediction">Bigram prediction</string> + <!-- Description for auto correction --> + <string name="bigram_prediction_summary">Use previous word also for prediction</string> <!-- Indicates that a word has been added to the dictionary --> <string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string> @@ -102,31 +126,6 @@ <!-- Label for "Wait" key of phone number keyboard. Must be short to fit on key! [CHAR LIMIT=5]--> <string name="label_wait_key">Wait</string> - <!-- Spoken text description for delete key. --> - <string name="description_delete_key">Delete</string> - <!-- Spoken text description for return key. --> - <string name="description_return_key">Return</string> - <!-- Spoken text description for settings key. --> - <string name="description_settings_key">Settings</string> - <!-- Spoken text description for shift key. --> - <string name="description_shift_key">Shift</string> - <!-- Spoken text description for space key. --> - <string name="description_space_key">Space</string> - <!-- Spoken text description for symbols key. --> - <string name="description_switch_alpha_symbol_key">Symbols</string> - <!-- Spoken text description for tab key. --> - <string name="description_tab_key">Tab</string> - <!-- Spoken text description for voice input key. --> - <string name="description_voice_key">Voice Input</string> - <!-- Spoken text description for symbols mode on. --> - <string name="description_symbols_on">Symbols on</string> - <!-- Spoken text description for symbols mode off. --> - <string name="description_symbols_off">Symbols off</string> - <!-- Spoken text description for shift mode on. --> - <string name="description_shift_on">Shift on</string> - <!-- Spoken text description for shift mode off. --> - <string name="description_shift_off">Shift off</string> - <!-- Voice related labels --> <!-- Title of the warning dialog that shows when a user initiates voice input for @@ -242,6 +241,8 @@ <!-- Description for Czech keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_cs_keyboard">Czech Keyboard</string> + <!-- Description for Arabic keyboard subtype [CHAR LIMIT=35] --> + <string name="subtype_mode_ar_keyboard">Arabic Keyboard</string> <!-- Description for Danish keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_da_keyboard">Danish Keyboard</string> <!-- Description for German keyboard subtype [CHAR LIMIT=35] --> @@ -258,12 +259,19 @@ <string name="subtype_mode_fr_CA_keyboard">French (Canada) Keyboard</string> <!-- Description for French (Switzerland) keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_fr_CH_keyboard">French (Switzerland) Keyboard</string> + <!-- Description for Hebrew keyboard subtype [CHAR LIMIT=35] --> + <!-- Java uses the deprecated "iw" code instead of the standard "he" code --> + <string name="subtype_mode_iw_keyboard">Hebrew Keyboard</string> <!-- Description for Italian keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_it_keyboard">Italian Keyboard</string> <!-- Description for Norwegian keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_nb_keyboard">Norwegian Keyboard</string> <!-- Description for Dutch keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_nl_keyboard">Dutch Keyboard</string> + <!-- Description for Polish keyboard subtype [CHAR LIMIT=35] --> + <string name="subtype_mode_pl_keyboard">Polish Keyboard</string> + <!-- Description for Portuguese keyboard subtype [CHAR LIMIT=35] --> + <string name="subtype_mode_pt_keyboard">Portuguese Keyboard</string> <!-- Description for Russian keyboard subtype [CHAR LIMIT=35] --> <string name="subtype_mode_ru_keyboard">Russian Keyboard</string> <!-- Description for Serbian keyboard subtype [CHAR LIMIT=35] --> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 130714fd3..3a389e57b 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -19,14 +19,14 @@ <item name="android:background">@drawable/keyboard_background</item> <item name="keyBackground">@drawable/btn_keyboard_key</item> - <item name="keyLetterSize">@dimen/key_letter_size</item> + <item name="keyLetterRatio">@fraction/key_letter_ratio</item> <item name="keyLetterStyle">normal</item> <item name="keyTextColor">#FFFFFFFF</item> <item name="keyTextColorDisabled">#FFFFFFFF</item> <item name="keyPreviewLayout">@layout/key_preview</item> <item name="keyPreviewOffset">@dimen/key_preview_offset</item> <item name="keyPreviewHeight">@dimen/key_preview_height</item> - <item name="labelTextSize">@dimen/key_label_text_size</item> + <item name="labelTextRatio">@fraction/key_label_text_ratio</item> <item name="popupLayout">@layout/keyboard_popup</item> <item name="keyHysteresisDistance">@dimen/key_hysteresis_distance</item> <item name="verticalCorrection">@dimen/keyboard_vertical_correction</item> @@ -35,11 +35,7 @@ <item name="backgroundDimAmount">0.5</item> <item name="colorScheme">white</item> </style> - <style name="KeyPreviewAnimation"> - <item name="android:windowEnterAnimation">@anim/key_preview_fadein</item> - <item name="android:windowExitAnimation">@anim/key_preview_fadeout</item> - </style> - <style name="MiniKeyboardAnimation"> + <style name="PopupMiniKeyboardAnimation"> <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item> <item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item> </style> diff --git a/java/res/xml-large/kbd_qwerty_rows.xml b/java/res/xml-ar/kbd_qwerty.xml index a2d26b3de..93310bf9c 100644 --- a/java/res/xml-large/kbd_qwerty_rows.xml +++ b/java/res/xml-ar/kbd_qwerty.xml @@ -18,17 +18,19 @@ */ --> -<merge +<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + latin:keyboardHeight="@dimen/keyboardHeight" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" + latin:rowHeight="25%p" + latin:keyWidth="10%p" + latin:horizontalGap="@dimen/key_horizontal_gap" + latin:verticalGap="@dimen/key_bottom_gap" + latin:popupKeyboardTemplate="@xml/kbd_popup_template" + latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="ar" > <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row1" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row2" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row3" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row4" /> -</merge> + latin:keyboardLayout="@xml/kbd_ar_rows" /> +</Keyboard> diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml-cs/kbd_qwerty.xml index 010bdb3f7..a74f7fa84 100644 --- a/java/res/xml-cs/kbd_qwerty.xml +++ b/java/res/xml-cs/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="cs" > <include latin:keyboardLayout="@xml/kbd_qwertz_rows" /> diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-da/kbd_qwerty.xml index 441b7cb17..12ea33c13 100644 --- a/java/res/xml-da/kbd_qwerty.xml +++ b/java/res/xml-da/kbd_qwerty.xml @@ -21,12 +21,14 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="da" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" /> diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml index a23e4fbf0..cc7722a44 100644 --- a/java/res/xml-de/kbd_qwerty.xml +++ b/java/res/xml-de/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="de" > <include latin:keyboardLayout="@xml/kbd_qwertz_rows" /> diff --git a/java/res/xml-large/kbd_popup_template.xml b/java/res/xml-es/kbd_qwerty.xml index fff2659be..3906bde38 100644 --- a/java/res/xml-large/kbd_popup_template.xml +++ b/java/res/xml-es/kbd_qwerty.xml @@ -18,10 +18,19 @@ */ --> -<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyWidth="8%p" +<Keyboard + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + latin:keyboardHeight="@dimen/keyboardHeight" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" + latin:rowHeight="25%p" + latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" - latin:verticalGap="0px" - latin:rowHeight="@dimen/popup_key_height" - > + latin:verticalGap="@dimen/key_bottom_gap" + latin:popupKeyboardTemplate="@xml/kbd_popup_template" + latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="es,es_US" +> + <include + latin:keyboardLayout="@xml/kbd_qwerty_rows" /> </Keyboard> diff --git a/java/res/xml-fi/kbd_qwerty.xml b/java/res/xml-fi/kbd_qwerty.xml index b0a7b3eb0..e35ab2b41 100644 --- a/java/res/xml-fi/kbd_qwerty.xml +++ b/java/res/xml-fi/kbd_qwerty.xml @@ -21,12 +21,14 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="fi" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" /> diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml index 92d92f0e6..e649a1e9c 100644 --- a/java/res/xml-fr-rCA/kbd_qwerty.xml +++ b/java/res/xml-fr-rCA/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="fr_CA" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows" /> diff --git a/java/res/xml-fr-rCH/kbd_qwerty.xml b/java/res/xml-fr-rCH/kbd_qwerty.xml index a23e4fbf0..f82becb48 100644 --- a/java/res/xml-fr-rCH/kbd_qwerty.xml +++ b/java/res/xml-fr-rCH/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="fr_CH" > <include latin:keyboardLayout="@xml/kbd_qwertz_rows" /> diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml-fr/kbd_qwerty.xml index 2d0b42baf..5d1f10c6b 100644 --- a/java/res/xml-fr/kbd_qwerty.xml +++ b/java/res/xml-fr/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="fr" > <include latin:keyboardLayout="@xml/kbd_azerty_rows" /> diff --git a/java/res/xml-hu/kbd_qwerty.xml b/java/res/xml-hu/kbd_qwerty.xml index 010bdb3f7..952ad9a0f 100644 --- a/java/res/xml-hu/kbd_qwerty.xml +++ b/java/res/xml-hu/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="hu" > <include latin:keyboardLayout="@xml/kbd_qwertz_rows" /> diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml index 98bfd7e0b..cfe404c9d 100644 --- a/java/res/xml-iw/kbd_qwerty.xml +++ b/java/res/xml-iw/kbd_qwerty.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2010, 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 +** 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 +** 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 +** 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. */ --> @@ -21,92 +21,16 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="iw" > <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:rowEdgeFlags="top" - > - <Spacer - latin:horizontalGap="5%p" /> - <Key - latin:keyLabel="ק" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="ר" /> - <Key - latin:keyLabel="א" /> - <Key - latin:keyLabel="ט" /> - <Key - latin:keyLabel="ו" /> - <Key - latin:keyLabel="ן" /> - <Key - latin:keyLabel="ם" /> - <Key - latin:keyLabel="פ" /> - <Spacer - latin:horizontalGap="1.25%p" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="13.75%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyLabel="ש" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="ד" /> - <Key - latin:keyLabel="ג" /> - <Key - latin:keyLabel="כ" /> - <Key - latin:keyLabel="ע" /> - <Key - latin:keyLabel="י" /> - <Key - latin:keyLabel="ח" /> - <Key - latin:keyLabel="ל" /> - <Key - latin:keyLabel="ך" /> - <Key - latin:keyLabel="ף" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Spacer - latin:horizontalGap="5%p" /> - <Key - latin:keyLabel="ז" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="ס" /> - <Key - latin:keyLabel="ב" /> - <Key - latin:keyLabel="ה" /> - <Key - latin:keyLabel="נ" /> - <Key - latin:keyLabel="מ" /> - <Key - latin:keyLabel="צ" /> - <Key - latin:keyLabel="ת" /> - <Key - latin:keyLabel="ץ" - latin:keyEdgeFlags="right" /> - </Row> - <include latin:keyboardLayout="@xml/kbd_qwerty_row4" /> + latin:keyboardLayout="@xml/kbd_iw_rows" /> </Keyboard> diff --git a/java/res/xml-large/kbd_azerty_rows.xml b/java/res/xml-large/kbd_azerty_rows.xml deleted file mode 100644 index d0100e017..000000000 --- a/java/res/xml-large/kbd_azerty_rows.xml +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:keyWidth="10%p" - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="a" - latin:keyHintIcon="@drawable/keyboard_hint_1" - latin:popupCharacters="@string/alternates_for_a" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="z" - latin:keyHintIcon="@drawable/keyboard_hint_2" - latin:popupCharacters="@string/alternates_for_z" /> - <Key - latin:keyLabel="e" - latin:keyHintIcon="@drawable/keyboard_hint_3" - latin:popupCharacters="@string/alternates_for_e" /> - <Key - latin:keyLabel="r" - latin:keyHintIcon="@drawable/keyboard_hint_4" - latin:popupCharacters="@string/alternates_for_r" /> - <Key - latin:keyLabel="t" - latin:keyHintIcon="@drawable/keyboard_hint_5" - latin:popupCharacters="@string/alternates_for_t" /> - <Key - latin:keyLabel="y" - latin:keyHintIcon="@drawable/keyboard_hint_6" - latin:popupCharacters="@string/alternates_for_y" /> - <Key - latin:keyLabel="u" - latin:keyHintIcon="@drawable/keyboard_hint_7" - latin:popupCharacters="@string/alternates_for_u" /> - <Key - latin:keyLabel="i" - latin:keyHintIcon="@drawable/keyboard_hint_8" - latin:popupCharacters="@string/alternates_for_i" /> - <Key - latin:keyLabel="o" - latin:keyHintIcon="@drawable/keyboard_hint_9" - latin:popupCharacters="@string/alternates_for_o" /> - <Key - latin:keyLabel="p" - latin:keyHintIcon="@drawable/keyboard_hint_0" - latin:popupCharacters="@string/alternates_for_p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="10%p" - > - <Key - latin:keyLabel="q" - latin:popupCharacters="@string/alternates_for_q" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="s" - latin:popupCharacters="@string/alternates_for_s" /> - <Key - latin:keyLabel="d" - latin:popupCharacters="@string/alternates_for_d" /> - <Key - latin:keyLabel="f" /> - <Key - latin:keyLabel="g" - latin:popupCharacters="@string/alternates_for_g" /> - <Key - latin:keyLabel="h" /> - <Key - latin:keyLabel="j" /> - <Key - latin:keyLabel="k" - latin:popupCharacters="@string/alternates_for_k" /> - <Key - latin:keyLabel="l" - latin:popupCharacters="@string/alternates_for_l" /> - <Key - latin:keyLabel="m" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="10%p" - > - <Key - latin:keyStyle="shiftKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="w" - latin:popupCharacters="@string/alternates_for_w" /> - <Key - latin:keyLabel="x" /> - <Key - latin:keyLabel="c" - - latin:popupCharacters="@string/alternates_for_c" /> - <Key - latin:keyLabel="v" - latin:popupCharacters="@string/alternates_for_v" /> - <Key - latin:keyLabel="b" /> - <Key - latin:keyLabel="n" - latin:popupCharacters="@string/alternates_for_n" /> - <Key - latin:keyLabel="\'" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </Row> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row4" /> -</merge> diff --git a/java/res/xml-large/kbd_key_styles.xml b/java/res/xml-large/kbd_key_styles.xml deleted file mode 100644 index c2ca3e13a..000000000 --- a/java/res/xml-large/kbd_key_styles.xml +++ /dev/null @@ -1,338 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <!-- Base key style for the functional key --> - <switch> - <case - latin:colorScheme="white" - > - <key-style - latin:styleName="functionalKeyStyle" - latin:isModifier="true" /> - </case> - <case - latin:colorScheme="black" - > - <key-style - latin:styleName="functionalKeyStyle" /> - </case> - </switch> - <!-- Base key style for the key which may have settings key as popup key --> - <switch> - <case - latin:hasSettingsKey="true" - > - <key-style - latin:styleName="settingsPopupStyle" - latin:parentStyle="functionalKeyStyle" /> - </case> - <!-- latin:hasSettingsKey="false" --> - <default> - <key-style - latin:styleName="settingsPopupStyle" - latin:keyHintIcon="@drawable/hint_popup" - latin:popupCharacters="\@drawable/sym_keyboard_settings|\@integer/key_settings" - latin:parentStyle="functionalKeyStyle" /> - </default> - </switch> - <!-- Functional key styles --> - <switch> - <case - latin:colorScheme="white" - > - <key-style - latin:styleName="shiftKeyStyle" - latin:code="@integer/key_shift" - latin:keyIcon="@drawable/sym_keyboard_shift_holo" - latin:shiftedIcon="@drawable/sym_keyboard_shift_locked_holo" - latin:iconPreview="@drawable/sym_keyboard_feedback_shift" - latin:parentStyle="functionalKeyStyle" - latin:isSticky="true" /> - <key-style - latin:styleName="deleteKeyStyle" - latin:code="@integer/key_delete" - latin:keyIcon="@drawable/sym_keyboard_delete_holo" - latin:iconPreview="@drawable/sym_keyboard_feedback_delete" - latin:parentStyle="functionalKeyStyle" - latin:isRepeatable="true" /> - <switch> - <!-- When this qwerty keyboard has no voice key but voice key is enabled, then - symbol keyboard will have mic key. That means we should use "?123mic" key - here. --> - <case - latin:voiceKeyEnabled="true" - latin:hasVoiceKey="false" - > - <key-style - latin:styleName="toSymbolKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyIcon="@drawable/sym_keyboard_123_mic" - latin:iconPreview="@drawable/sym_keyboard_feedback_123_mic" - latin:parentStyle="functionalKeyStyle" /> - </case> - <default> - <key-style - latin:styleName="toSymbolKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyLabel="@string/label_to_symbol_key" - latin:parentStyle="functionalKeyStyle" /> - </default> - </switch> - <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 - latin:styleName="spaceKeyStyle" - latin:code="@integer/key_space" - latin:keyIcon="@drawable/sym_keyboard_space_holo" - latin:iconPreview="@drawable/sym_keyboard_feedback_space" - latin:parentStyle="functionalKeyStyle" /> - <key-style - latin:styleName="tabKeyStyle" - latin:code="@integer/key_tab" - latin:keyIcon="@drawable/sym_keyboard_tab" - latin:iconPreview="@drawable/sym_keyboard_feedback_tab" - latin:parentStyle="functionalKeyStyle" /> - <key-style - latin:styleName="micKeyStyle" - latin:code="@integer/key_voice" - latin:keyIcon="@drawable/sym_keyboard_mic" - latin:iconPreview="@drawable/sym_keyboard_feedback_mic" - latin:parentStyle="settingsPopupStyle" /> - <!-- Note: This key style is not for functional tab key. This is used for the tab key - which is laid out as normal letter key. --> - <key-style - latin:styleName="nonSpecialBackgroundTabKeyStyle" - latin:code="@integer/key_tab" - latin:keyIcon="@drawable/sym_keyboard_tab" - latin:iconPreview="@drawable/sym_keyboard_feedback_tab" /> - </case> - <case - latin:colorScheme="black" - > - <key-style - latin:styleName="shiftKeyStyle" - latin:code="@integer/key_shift" - latin:keyIcon="@drawable/sym_bkeyboard_shift" - latin:shiftedIcon="@drawable/sym_bkeyboard_shift_locked" - latin:iconPreview="@drawable/sym_keyboard_feedback_shift" - latin:parentStyle="functionalKeyStyle" - latin:isSticky="true" /> - <key-style - latin:styleName="deleteKeyStyle" - latin:code="@integer/key_delete" - latin:keyIcon="@drawable/sym_bkeyboard_delete" - latin:iconPreview="@drawable/sym_keyboard_feedback_delete" - latin:parentStyle="functionalKeyStyle" - latin:isRepeatable="true" /> - <switch> - <!-- When this qwerty keyboard has no voice key but voice key is enabled, then - symbol keyboard will have mic key. That means we should use "?123mic" key - here. --> - <case - latin:voiceKeyEnabled="true" - latin:hasVoiceKey="false" - > - <key-style - latin:styleName="toSymbolKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyIcon="@drawable/sym_bkeyboard_123_mic" - latin:iconPreview="@drawable/sym_keyboard_feedback_123_mic" - latin:parentStyle="functionalKeyStyle" /> - </case> - <default> - <key-style - latin:styleName="toSymbolKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyLabel="@string/label_to_symbol_key" - latin:parentStyle="functionalKeyStyle" /> - </default> - </switch> - <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 - latin:styleName="spaceKeyStyle" - latin:code="@integer/key_space" - latin:keyIcon="@drawable/sym_bkeyboard_space" - latin:iconPreview="@drawable/sym_keyboard_feedback_space" - latin:parentStyle="functionalKeyStyle" /> - <key-style - latin:styleName="tabKeyStyle" - latin:code="@integer/key_tab" - latin:keyIcon="@drawable/sym_bkeyboard_tab" - latin:iconPreview="@drawable/sym_keyboard_feedback_tab" - latin:parentStyle="functionalKeyStyle" /> - <key-style - latin:styleName="micKeyStyle" - latin:code="@integer/key_voice" - latin:keyIcon="@drawable/sym_bkeyboard_mic" - latin:iconPreview="@drawable/sym_keyboard_feedback_mic" - latin:parentStyle="settingsPopupStyle" /> - <!-- Note: This key style is not for functional tab key. This is used for the tab key - which is laid out as normal letter key. --> - <key-style - latin:styleName="nonSpecialBackgroundTabKeyStyle" - latin:code="@integer/key_tab" - latin:keyIcon="@drawable/sym_bkeyboard_tab" - latin:iconPreview="@drawable/sym_keyboard_feedback_tab" /> - </case> - </switch> - <!-- Return key style --> - <switch> - <case - latin:imeAction="actionGo" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyLabel="@string/label_go_key" - latin:parentStyle="functionalKeyStyle" /> - </case> - <case - latin:imeAction="actionNext" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyLabel="@string/label_next_key" - latin:parentStyle="functionalKeyStyle" /> - </case> - <case - latin:imeAction="actionDone" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyLabel="@string/label_done_key" - latin:parentStyle="functionalKeyStyle" /> - </case> - <case - latin:imeAction="actionSend" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyLabel="@string/label_send_key" - latin:parentStyle="functionalKeyStyle" /> - </case> - <case - latin:imeAction="actionSearch" - > - <switch> - <case - latin:colorScheme="white" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyIcon="@drawable/sym_keyboard_search" - latin:iconPreview="@drawable/sym_keyboard_feedback_search" - latin:parentStyle="functionalKeyStyle" /> - </case> - <case - latin:colorScheme="black" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyIcon="@drawable/sym_bkeyboard_search" - latin:iconPreview="@drawable/sym_keyboard_feedback_search" - latin:parentStyle="functionalKeyStyle" /> - </case> - </switch> - </case> - <default> - <switch> - <case - latin:colorScheme="white" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyIcon="@drawable/sym_keyboard_return" - latin:iconPreview="@drawable/sym_keyboard_feedback_return" - latin:parentStyle="functionalKeyStyle" /> - </case> - <case - latin:colorScheme="black" - > - <key-style - latin:styleName="returnKeyStyle" - latin:code="@integer/key_return" - latin:keyIcon="@drawable/sym_bkeyboard_return" - latin:iconPreview="@drawable/sym_keyboard_feedback_return" - latin:parentStyle="functionalKeyStyle" /> - </case> - </switch> - </default> - </switch> - <key-style - latin:styleName="toAlphaKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyLabel="@string/label_to_alpha_key" - latin:parentStyle="functionalKeyStyle" /> - <key-style - latin:styleName="altKeyStyle" - latin:code="@integer/key_shift" - latin:keyLabel="@string/label_alt_key" - latin:parentStyle="functionalKeyStyle" - latin:isSticky="true" /> - <key-style - latin:styleName="smileyKeyStyle" - latin:keyLabel=":-)" - latin:keyOutputText=":-) " - latin:keyHintIcon="@drawable/hint_popup_holo" - latin:popupCharacters="@string/alternates_for_smiley" - latin:maxPopupKeyboardColumn="5" - latin:parentStyle="functionalKeyStyle" /> - <switch> - <case - latin:passwordInput="true" - > - <key-style - latin:styleName="nonPasswordSymbolKeyStyle" - latin:enabled="false" /> - <key-style - latin:styleName="nonPasswordFunctionalKeyStyle" - latin:enabled="false" - latin:parentStyle="functionalKeyStyle" /> - </case> - <!-- latin:passwordInput="false" --> - <default> - <key-style - latin:styleName="nonPasswordSymbolKeyStyle" - latin:enabled="true" /> - <key-style - latin:styleName="nonPasswordFunctionalKeyStyle" - latin:enabled="true" - latin:parentStyle="functionalKeyStyle" /> - </default> - </switch> -</merge> diff --git a/java/res/xml-large/kbd_number.xml b/java/res/xml-large/kbd_number.xml deleted file mode 100644 index 9b8d4b31d..000000000 --- a/java/res/xml-large/kbd_number.xml +++ /dev/null @@ -1,94 +0,0 @@ -<?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. -*/ ---> - -<Keyboard - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" - latin:rowHeight="25%p" - latin:keyWidth="26.67%p" - latin:horizontalGap="@dimen/key_horizontal_gap" - latin:verticalGap="@dimen/key_bottom_gap" - latin:popupKeyboardTemplate="@xml/kbd_popup_template" - latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <include - latin:keyboardLayout="@xml/kbd_numkey_styles" /> - <Row - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="1" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="2" /> - <Key - latin:keyLabel="3" /> - <Key - latin:keyLabel="-" - latin:keyStyle="functionalKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyLabel="4" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="5" /> - <Key - latin:keyLabel="6" /> - <Key - latin:keyLabel="," - latin:keyStyle="functionalKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyLabel="7" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="8" /> - <Key - latin:keyLabel="9" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:rowEdgeFlags="bottom" - > - <Key - latin:keyStyle="numSpaceKeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="0" /> - <Key - latin:keyLabel="." /> - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> -</Keyboard> diff --git a/java/res/xml-large/kbd_numkey_styles.xml b/java/res/xml-large/kbd_numkey_styles.xml deleted file mode 100644 index 72efbbcba..000000000 --- a/java/res/xml-large/kbd_numkey_styles.xml +++ /dev/null @@ -1,150 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <switch> - <case - latin:colorScheme="white" - > - <key-style - latin:styleName="num0KeyStyle" - latin:code="48" - latin:keyIcon="@drawable/sym_keyboard_num0_holo" /> - <key-style - latin:styleName="num1KeyStyle" - latin:code="49" - latin:keyIcon="@drawable/sym_keyboard_num1_holo" /> - <key-style - latin:styleName="num2KeyStyle" - latin:code="50" - latin:keyIcon="@drawable/sym_keyboard_num2_holo" /> - <key-style - latin:styleName="num3KeyStyle" - latin:code="51" - latin:keyIcon="@drawable/sym_keyboard_num3_holo" /> - <key-style - latin:styleName="num4KeyStyle" - latin:code="52" - latin:keyIcon="@drawable/sym_keyboard_num4_holo" /> - <key-style - latin:styleName="num5KeyStyle" - latin:code="53" - latin:keyIcon="@drawable/sym_keyboard_num5_holo" /> - <key-style - latin:styleName="num6KeyStyle" - latin:code="54" - latin:keyIcon="@drawable/sym_keyboard_num6_holo" /> - <key-style - latin:styleName="num7KeyStyle" - latin:code="55" - latin:keyIcon="@drawable/sym_keyboard_num7_holo" /> - <key-style - latin:styleName="num8KeyStyle" - latin:code="56" - latin:keyIcon="@drawable/sym_keyboard_num8_holo" /> - <key-style - latin:styleName="num9KeyStyle" - latin:code="57" - latin:keyIcon="@drawable/sym_keyboard_num9_holo" /> - <key-style - latin:styleName="numStarKeyStyle" - latin:code="42" - latin:keyIcon="@drawable/sym_keyboard_numbstar_holo" /> - <key-style - latin:styleName="numPoundKeyStyle" - latin:code="35" - latin:keyIcon="@drawable/sym_keyboard_numbpound_holo" /> - <key-style - latin:styleName="numAltKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyIcon="@drawable/sym_keyboard_numalt" - latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" /> - <key-style - latin:styleName="numSpaceKeyStyle" - latin:code="@integer/key_space" - latin:iconPreview="@drawable/sym_keyboard_feedback_space" - latin:keyIcon="@drawable/sym_keyboard_space" /> - </case> - <case - latin:colorScheme="black" - > - <key-style - latin:styleName="num0KeyStyle" - latin:code="48" - latin:keyIcon="@drawable/sym_bkeyboard_num0" /> - <key-style - latin:styleName="num1KeyStyle" - latin:code="49" - latin:keyIcon="@drawable/sym_bkeyboard_num1" /> - <key-style - latin:styleName="num2KeyStyle" - latin:code="50" - latin:keyIcon="@drawable/sym_bkeyboard_num2" /> - <key-style - latin:styleName="num3KeyStyle" - latin:code="51" - latin:keyIcon="@drawable/sym_bkeyboard_num3" /> - <key-style - latin:styleName="num4KeyStyle" - latin:code="52" - latin:keyIcon="@drawable/sym_bkeyboard_num4" /> - <key-style - latin:styleName="num5KeyStyle" - latin:code="53" - latin:keyIcon="@drawable/sym_bkeyboard_num5" /> - <key-style - latin:styleName="num6KeyStyle" - latin:code="54" - latin:keyIcon="@drawable/sym_bkeyboard_num6" /> - <key-style - latin:styleName="num7KeyStyle" - latin:code="55" - latin:keyIcon="@drawable/sym_bkeyboard_num7" /> - <key-style - latin:styleName="num8KeyStyle" - latin:code="56" - latin:keyIcon="@drawable/sym_bkeyboard_num8" /> - <key-style - latin:styleName="num9KeyStyle" - latin:code="57" - latin:keyIcon="@drawable/sym_bkeyboard_num9" /> - <key-style - latin:styleName="numStarKeyStyle" - latin:code="42" - latin:keyIcon="@drawable/sym_bkeyboard_numstar" /> - <key-style - latin:styleName="numPoundKeyStyle" - latin:code="35" - latin:keyIcon="@drawable/sym_bkeyboard_numpound" /> - <key-style - latin:styleName="numAltKeyStyle" - latin:code="@integer/key_switch_alpha_symbol" - latin:keyIcon="@drawable/sym_bkeyboard_numalt" - latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" /> - <key-style - latin:styleName="numSpaceKeyStyle" - latin:code="@integer/key_space" - latin:iconPreview="@drawable/sym_keyboard_feedback_space" - latin:keyIcon="@drawable/sym_keyboard_space" /> - </case> - </switch> -</merge> diff --git a/java/res/xml-large/kbd_phone.xml b/java/res/xml-large/kbd_phone.xml deleted file mode 100644 index 8dd1ab760..000000000 --- a/java/res/xml-large/kbd_phone.xml +++ /dev/null @@ -1,94 +0,0 @@ -<?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. -*/ ---> - -<Keyboard - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" - latin:rowHeight="25%p" - latin:keyWidth="26.67%p" - latin:horizontalGap="@dimen/key_horizontal_gap" - latin:verticalGap="@dimen/key_bottom_gap" - latin:popupKeyboardTemplate="@xml/kbd_popup_template" - latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <include - latin:keyboardLayout="@xml/kbd_numkey_styles" /> - <Row - latin:rowEdgeFlags="top" - > - <Key - latin:keyStyle="num1KeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="num2KeyStyle" /> - <Key - latin:keyStyle="num3KeyStyle" /> - <Key - latin:keyLabel="-" - latin:keyStyle="functionalKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyStyle="num4KeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="num5KeyStyle" /> - <Key - latin:keyStyle="num6KeyStyle" /> - <Key - latin:keyLabel="." - latin:keyStyle="functionalKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyStyle="num7KeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="num8KeyStyle" /> - <Key - latin:keyStyle="num9KeyStyle" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:rowEdgeFlags="bottom" - > - <Key - latin:keyStyle="numAltKeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="num0KeyStyle" /> - <Key - latin:keyStyle="numSpaceKeyStyle" /> - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> -</Keyboard> diff --git a/java/res/xml-large/kbd_phone_symbols.xml b/java/res/xml-large/kbd_phone_symbols.xml deleted file mode 100644 index d355c8eac..000000000 --- a/java/res/xml-large/kbd_phone_symbols.xml +++ /dev/null @@ -1,100 +0,0 @@ -<?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. -*/ ---> - -<Keyboard - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" - latin:rowHeight="25%p" - latin:keyWidth="26.67%p" - latin:horizontalGap="@dimen/key_horizontal_gap" - latin:verticalGap="@dimen/key_bottom_gap" - latin:popupKeyboardTemplate="@xml/kbd_popup_template" - latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <include - latin:keyboardLayout="@xml/kbd_numkey_styles" /> - <Row - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="(" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="/" /> - <Key - latin:keyLabel=")" /> - <Key - latin:keyLabel="-" - latin:keyStyle="functionalKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyLabel="N" - latin:keyEdgeFlags="left" /> - <!-- Pause is a comma. Check PhoneNumberUtils.java to see if this - has changed. --> - <Key - latin:code="44" - latin:keyLabel="Pause" /> - <Key - latin:keyLabel="," /> - <Key - latin:keyLabel="." - latin:keyStyle="functionalKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyStyle="numStarKeyStyle" - latin:keyEdgeFlags="left" /> - <!-- Wait is a semicolon. --> - <Key - latin:code="59" - latin:keyLabel="Wait" /> - <Key - latin:keyStyle="numPoundKeyStyle" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:rowEdgeFlags="bottom" - > - <Key - latin:code="@integer/key_switch_alpha_symbol" - latin:keyLabel="@string/label_to_numeric_key" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="+" /> - <Key - latin:keyStyle="numSpaceKeyStyle" /> - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </Row> -</Keyboard> diff --git a/java/res/xml-large/kbd_qwerty_row1.xml b/java/res/xml-large/kbd_qwerty_row1.xml deleted file mode 100644 index df9712535..000000000 --- a/java/res/xml-large/kbd_qwerty_row1.xml +++ /dev/null @@ -1,71 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <Row - latin:keyWidth="10%p" - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="q" - latin:keyHintIcon="@drawable/keyboard_hint_1" - latin:popupCharacters="@string/alternates_for_q" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="w" - latin:keyHintIcon="@drawable/keyboard_hint_2" - latin:popupCharacters="@string/alternates_for_w" /> - <Key - latin:keyLabel="e" - latin:keyHintIcon="@drawable/keyboard_hint_3" - latin:popupCharacters="@string/alternates_for_e" /> - <Key - latin:keyLabel="r" - latin:keyHintIcon="@drawable/keyboard_hint_4" - latin:popupCharacters="@string/alternates_for_r" /> - <Key - latin:keyLabel="t" - latin:keyHintIcon="@drawable/keyboard_hint_5" - latin:popupCharacters="@string/alternates_for_t" /> - <Key - latin:keyLabel="y" - latin:keyHintIcon="@drawable/keyboard_hint_6" - latin:popupCharacters="@string/alternates_for_y" /> - <Key - latin:keyLabel="u" - latin:keyHintIcon="@drawable/keyboard_hint_7" - latin:popupCharacters="@string/alternates_for_u" /> - <Key - latin:keyLabel="i" - latin:keyHintIcon="@drawable/keyboard_hint_8" - latin:popupCharacters="@string/alternates_for_i" /> - <Key - latin:keyLabel="o" - latin:keyHintIcon="@drawable/keyboard_hint_9" - latin:popupCharacters="@string/alternates_for_o" /> - <Key - latin:keyLabel="p" - latin:keyHintIcon="@drawable/keyboard_hint_0" - latin:popupCharacters="@string/alternates_for_p" - latin:keyEdgeFlags="right" /> - </Row> -</merge> diff --git a/java/res/xml-large/kbd_qwerty_row2.xml b/java/res/xml-large/kbd_qwerty_row2.xml deleted file mode 100644 index 07dd66f6b..000000000 --- a/java/res/xml-large/kbd_qwerty_row2.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <Row - latin:keyWidth="10%p" - > - <Spacer - latin:horizontalGap="5%p" /> - <Key - latin:keyLabel="a" - latin:popupCharacters="@string/alternates_for_a" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="s" - latin:popupCharacters="@string/alternates_for_s" /> - <Key - latin:keyLabel="d" - latin:popupCharacters="@string/alternates_for_d" /> - <Key - latin:keyLabel="f" /> - <Key - latin:keyLabel="g" - latin:popupCharacters="@string/alternates_for_g" /> - <Key - latin:keyLabel="h" /> - <Key - latin:keyLabel="j" /> - <Key - latin:keyLabel="k" - latin:popupCharacters="@string/alternates_for_k" /> - <Key - latin:keyLabel="l" - latin:popupCharacters="@string/alternates_for_l" - latin:keyEdgeFlags="right" /> - </Row> -</merge> diff --git a/java/res/xml-large/kbd_qwerty_row3.xml b/java/res/xml-large/kbd_qwerty_row3.xml deleted file mode 100644 index c8e78d440..000000000 --- a/java/res/xml-large/kbd_qwerty_row3.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <Row - latin:keyWidth="10%p" - > - <Key - latin:keyStyle="shiftKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="z" - latin:popupCharacters="@string/alternates_for_z" /> - <Key - latin:keyLabel="x" /> - <Key - latin:keyLabel="c" - latin:popupCharacters="@string/alternates_for_c" /> - <Key - latin:keyLabel="v" - latin:popupCharacters="@string/alternates_for_v" /> - <Key - latin:keyLabel="b" /> - <Key - latin:keyLabel="n" - latin:popupCharacters="@string/alternates_for_n" /> - <Key - latin:keyLabel="m" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </Row> -</merge> diff --git a/java/res/xml-large/kbd_qwerty_row4.xml b/java/res/xml-large/kbd_qwerty_row4.xml deleted file mode 100644 index afe12e89b..000000000 --- a/java/res/xml-large/kbd_qwerty_row4.xml +++ /dev/null @@ -1,137 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <Row - latin:keyWidth="10%p" - latin:rowEdgeFlags="bottom" - > - <switch> - <case - latin:hasSettingsKey="false" - > - <Key - latin:keyStyle="toSymbolKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="left" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_f1" /> - <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="40%p" /> - <switch> - <case - latin:mode="web" - > - <Key - latin:keyHintIcon="@drawable/hint_popup" - latin:popupCharacters="@string/alternates_for_web_tab_punctuation" - latin:maxPopupKeyboardColumn="8" - latin:keyStyle="tabKeyStyle" /> - </case> - <default> - <Key - latin:keyLabel="." - latin:keyHintIcon="@drawable/hint_popup" - latin:popupCharacters="@string/alternates_for_punctuation" - latin:maxPopupKeyboardColumn="7" - latin:keyStyle="functionalKeyStyle" /> - </default> - </switch> - <switch> - <case - latin:mode="im" - > - <Key - latin:keyStyle="smileyKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </case> - <default> - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="20%p" - latin:keyEdgeFlags="right" /> - </default> - </switch> - </case> - <case - latin:hasSettingsKey="true" - > - <Key - latin:keyStyle="toSymbolKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="settingsKeyStyle" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_f1" /> - <switch> - <case - latin:mode="web" - > - <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="30%p" /> - <Key - latin:keyStyle="tabKeyStyle" /> - </case> - <default> - <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="30%p" /> - </default> - </switch> - <Key - latin:keyLabel="." - latin:keyHintIcon="@drawable/hint_popup" - latin:popupCharacters="@string/alternates_for_punctuation" - latin:maxPopupKeyboardColumn="7" - latin:keyStyle="functionalKeyStyle" /> - <switch> - <case - latin:mode="im" - > - <Key - latin:keyStyle="smileyKeyStyle" - latin:keyWidth="25%p" - latin:keyEdgeFlags="right" /> - </case> - <case - latin:mode="web" - > - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </case> - <default> - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="25%p" - latin:keyEdgeFlags="right" /> - </default> - </switch> - </case> - </switch> - </Row> -</merge> diff --git a/java/res/xml-large/kbd_qwerty_rows_scandinavia.xml b/java/res/xml-large/kbd_qwerty_rows_scandinavia.xml deleted file mode 100644 index 9521c0b37..000000000 --- a/java/res/xml-large/kbd_qwerty_rows_scandinavia.xml +++ /dev/null @@ -1,119 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:keyWidth="9.09%p" - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="q" - latin:keyHintIcon="@drawable/keyboard_hint_1" - latin:popupCharacters="@string/alternates_for_q" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="w" - latin:keyHintIcon="@drawable/keyboard_hint_2" - latin:popupCharacters="@string/alternates_for_w" /> - <Key - latin:keyLabel="e" - latin:keyHintIcon="@drawable/keyboard_hint_3" - latin:popupCharacters="@string/alternates_for_e" /> - <Key - latin:keyLabel="r" - latin:keyHintIcon="@drawable/keyboard_hint_4" - latin:popupCharacters="@string/alternates_for_r" /> - <Key - latin:keyLabel="t" - latin:keyHintIcon="@drawable/keyboard_hint_5" - latin:popupCharacters="@string/alternates_for_t" /> - <Key - latin:keyLabel="y" - latin:keyHintIcon="@drawable/keyboard_hint_6" - latin:popupCharacters="@string/alternates_for_y" /> - <Key - latin:keyLabel="u" - latin:keyHintIcon="@drawable/keyboard_hint_7" - latin:popupCharacters="@string/alternates_for_u" /> - <Key - latin:keyLabel="i" - latin:keyHintIcon="@drawable/keyboard_hint_8" - latin:popupCharacters="@string/alternates_for_i" /> - <Key - latin:keyLabel="o" - latin:keyHintIcon="@drawable/keyboard_hint_9" - latin:popupCharacters="@string/alternates_for_o" /> - <Key - latin:keyLabel="p" - latin:keyHintIcon="@drawable/keyboard_hint_0" - latin:popupCharacters="@string/alternates_for_p" /> - <Key - latin:keyLabel="å" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="9.09%p" - > - <Key - latin:keyLabel="a" - latin:popupCharacters="@string/alternates_for_a" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="s" - latin:popupCharacters="@string/alternates_for_s" /> - <Key - latin:keyLabel="d" - latin:popupCharacters="@string/alternates_for_d" /> - <Key - latin:keyLabel="f" /> - <Key - latin:keyLabel="g" - latin:popupCharacters="@string/alternates_for_g" /> - <Key - latin:keyLabel="h" /> - <Key - latin:keyLabel="j" /> - <Key - latin:keyLabel="k" - latin:popupCharacters="@string/alternates_for_k" /> - <Key - latin:keyLabel="l" - latin:popupCharacters="@string/alternates_for_l" /> - <Key - latin:keyLabel="@string/keylabel_for_scandinavia_row2_10" - latin:popupCharacters="@string/alternates_for_scandinavia_row2_10" /> - <Key - latin:keyLabel="@string/keylabel_for_scandinavia_row2_11" - latin:popupCharacters="@string/alternates_for_scandinavia_row2_11" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="right" /> - </Row> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row3" /> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row4" /> -</merge> diff --git a/java/res/xml-large/kbd_qwertz_rows.xml b/java/res/xml-large/kbd_qwertz_rows.xml deleted file mode 100644 index 239563dca..000000000 --- a/java/res/xml-large/kbd_qwertz_rows.xml +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:keyWidth="10%p" - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="q" - latin:keyHintIcon="@drawable/keyboard_hint_1" - latin:popupCharacters="@string/alternates_for_q" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="w" - latin:keyHintIcon="@drawable/keyboard_hint_2" - latin:popupCharacters="@string/alternates_for_w" /> - <Key - latin:keyLabel="e" - latin:keyHintIcon="@drawable/keyboard_hint_3" - latin:popupCharacters="@string/alternates_for_e" /> - <Key - latin:keyLabel="r" - latin:keyHintIcon="@drawable/keyboard_hint_4" - latin:popupCharacters="@string/alternates_for_r" /> - <Key - latin:keyLabel="t" - latin:keyHintIcon="@drawable/keyboard_hint_5" - latin:popupCharacters="@string/alternates_for_t" /> - <Key - latin:keyLabel="z" - latin:keyHintIcon="@drawable/keyboard_hint_6" - latin:popupCharacters="@string/alternates_for_z" /> - <Key - latin:keyLabel="u" - latin:keyHintIcon="@drawable/keyboard_hint_7" - latin:popupCharacters="@string/alternates_for_u" /> - <Key - latin:keyLabel="i" - latin:keyHintIcon="@drawable/keyboard_hint_8" - latin:popupCharacters="@string/alternates_for_i" /> - <Key - latin:keyLabel="o" - latin:keyHintIcon="@drawable/keyboard_hint_9" - latin:popupCharacters="@string/alternates_for_o" /> - <Key - latin:keyLabel="p" - latin:keyHintIcon="@drawable/keyboard_hint_0" - latin:popupCharacters="@string/alternates_for_p" - latin:keyEdgeFlags="right" /> - </Row> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row2" /> - <Row - latin:keyWidth="10%p" - > - <Key - latin:keyStyle="shiftKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="y" - latin:popupCharacters="@string/alternates_for_y" /> - <Key - latin:keyLabel="x" /> - <Key - latin:keyLabel="c" - latin:popupCharacters="@string/alternates_for_c" /> - <Key - latin:keyLabel="v" - latin:popupCharacters="@string/alternates_for_v" /> - <Key - latin:keyLabel="b" /> - <Key - latin:keyLabel="n" - latin:popupCharacters="@string/alternates_for_n" /> - <Key - latin:keyLabel="m" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </Row> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row4" /> -</merge> diff --git a/java/res/xml-large/kbd_ru_rows.xml b/java/res/xml-large/kbd_ru_rows.xml deleted file mode 100644 index fa2af3be0..000000000 --- a/java/res/xml-large/kbd_ru_rows.xml +++ /dev/null @@ -1,140 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:keyWidth="9.091%p" - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="й" - latin:keyHintIcon="@drawable/keyboard_hint_1" - latin:popupCharacters="1" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="ц" - latin:keyHintIcon="@drawable/keyboard_hint_2" - latin:popupCharacters="2" /> - <Key - latin:keyLabel="у" - latin:keyHintIcon="@drawable/keyboard_hint_3" - latin:popupCharacters="3" /> - <Key - latin:keyLabel="к" - latin:keyHintIcon="@drawable/keyboard_hint_4" - latin:popupCharacters="4" /> - <Key - latin:keyLabel="е" - latin:keyHintIcon="@drawable/keyboard_hint_5" - latin:popupCharacters="@string/alternates_for_cyrillic_e" /> - <Key - latin:keyLabel="н" - latin:keyHintIcon="@drawable/keyboard_hint_6" - latin:popupCharacters="6" /> - <Key - latin:keyLabel="г" - latin:keyHintIcon="@drawable/keyboard_hint_7" - latin:popupCharacters="7" /> - <Key - latin:keyLabel="ш" - latin:keyHintIcon="@drawable/keyboard_hint_8" - latin:popupCharacters="8" /> - <Key - latin:keyLabel="щ" - latin:keyHintIcon="@drawable/keyboard_hint_9" - latin:popupCharacters="9" /> - <Key - latin:keyLabel="з" - latin:keyHintIcon="@drawable/keyboard_hint_0" - latin:popupCharacters="0" /> - <Key - latin:keyLabel="х" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="9.091%p" - > - <Key - latin:keyLabel="ф" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="ы" /> - <Key - latin:keyLabel="в" /> - <Key - latin:keyLabel="а" /> - <Key - latin:keyLabel="п" /> - <Key - latin:keyLabel="р" /> - <Key - latin:keyLabel="о" /> - <Key - latin:keyLabel="л" /> - <Key - latin:keyLabel="д" /> - <Key - latin:keyLabel="ж" /> - <Key - latin:keyLabel="э" - latin:keyWidth="8.75%p" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="8.5%p" - > - <Key - latin:keyStyle="shiftKeyStyle" - latin:keyWidth="11.75%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="я" /> - <Key - latin:keyLabel="ч" /> - <Key - latin:keyLabel="с" /> - <Key - latin:keyLabel="м" /> - <Key - latin:keyLabel="и" /> - <Key - latin:keyLabel="т" /> - <Key - latin:keyLabel="ь" - latin:popupCharacters="@string/alternates_for_cyrillic_soft_sign" /> - <Key - latin:keyLabel="б" /> - <Key - latin:keyLabel="ю" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="11.75%p" - latin:keyEdgeFlags="right" /> - </Row> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row4" /> -</merge> diff --git a/java/res/xml-large/kbd_sr_rows.xml b/java/res/xml-large/kbd_sr_rows.xml deleted file mode 100644 index 8d6b070b2..000000000 --- a/java/res/xml-large/kbd_sr_rows.xml +++ /dev/null @@ -1,134 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2011, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:keyWidth="9.09%p" - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="љ" - latin:keyHintIcon="@drawable/keyboard_hint_1" - latin:popupCharacters="1" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="њ" - latin:keyHintIcon="@drawable/keyboard_hint_2" - latin:popupCharacters="2" /> - <Key - latin:keyLabel="е" - latin:keyHintIcon="@drawable/keyboard_hint_3" - latin:popupCharacters="3" /> - <Key - latin:keyLabel="р" - latin:keyHintIcon="@drawable/keyboard_hint_4" - latin:popupCharacters="4" /> - <Key - latin:keyLabel="т" - latin:keyHintIcon="@drawable/keyboard_hint_5" - latin:popupCharacters="5" /> - <Key - latin:keyLabel="з" - latin:keyHintIcon="@drawable/keyboard_hint_6" - latin:popupCharacters="6" /> - <Key - latin:keyLabel="у" - latin:keyHintIcon="@drawable/keyboard_hint_7" - latin:popupCharacters="7" /> - <Key - latin:keyLabel="и" - latin:keyHintIcon="@drawable/keyboard_hint_8" - latin:popupCharacters="8" /> - <Key - latin:keyLabel="о" - latin:keyHintIcon="@drawable/keyboard_hint_9" - latin:popupCharacters="9" /> - <Key - latin:keyLabel="п" - latin:keyHintIcon="@drawable/keyboard_hint_0" - latin:popupCharacters="0" /> - <Key - latin:keyLabel="ш" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="9.09%p" - > - <Key - latin:keyLabel="а" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="с" /> - <Key - latin:keyLabel="д" /> - <Key - latin:keyLabel="ф" /> - <Key - latin:keyLabel="г" /> - <Key - latin:keyLabel="х" /> - <Key - latin:keyLabel="ј" /> - <Key - latin:keyLabel="к" /> - <Key - latin:keyLabel="л" /> - <Key - latin:keyLabel="ч" /> - <Key - latin:keyLabel="ћ" - latin:keyEdgeFlags="right" /> - </Row> - <Row - latin:keyWidth="8.90%p" - > - <Key - latin:keyStyle="shiftKeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="ѕ" /> - <Key - latin:keyLabel="џ" /> - <Key - latin:keyLabel="ц" /> - <Key - latin:keyLabel="в" /> - <Key - latin:keyLabel="б" /> - <Key - latin:keyLabel="н" /> - <Key - latin:keyLabel="м" /> - <Key - latin:keyLabel="ђ" /> - <Key - latin:keyLabel="ж" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="11.00%p" - latin:keyEdgeFlags="right" /> - </Row> - <include - latin:keyboardLayout="@xml/kbd_qwerty_row4" /> -</merge> diff --git a/java/res/xml-large/kbd_symbols.xml b/java/res/xml-large/kbd_symbols.xml deleted file mode 100644 index 3f79ae178..000000000 --- a/java/res/xml-large/kbd_symbols.xml +++ /dev/null @@ -1,131 +0,0 @@ -<?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. -*/ ---> - -<Keyboard - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" - latin:rowHeight="25%p" - latin:keyWidth="10%p" - latin:horizontalGap="@dimen/key_horizontal_gap" - latin:verticalGap="@dimen/key_bottom_gap" - latin:popupKeyboardTemplate="@xml/kbd_popup_template" - latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <include - latin:keyboardLayout="@xml/kbd_currency_key_styles" /> - <Row - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="1" - latin:popupCharacters="¹,½,⅓,¼,⅛" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="2" - latin:popupCharacters="²,⅔" /> - <Key - latin:keyLabel="3" - latin:popupCharacters="³,¾,⅜" /> - <Key - latin:keyLabel="4" - latin:popupCharacters="⁴" /> - <Key - latin:keyLabel="5" - latin:popupCharacters="⅝" /> - <Key - latin:keyLabel="6" /> - <Key - latin:keyLabel="7" - latin:popupCharacters="⅞" /> - <Key - latin:keyLabel="8" /> - <Key - latin:keyLabel="9" /> - <Key - latin:keyLabel="0" - latin:popupCharacters="ⁿ,∅" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyLabel="\@" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="\#" /> - <Key - latin:keyStyle="currencyKeyStyle" /> - <Key - latin:keyLabel="%" - latin:popupCharacters="‰" /> - <Key - latin:keyLabel="&" /> - <Key - latin:keyLabel="*" - latin:popupCharacters="†,‡,★" /> - <Key - latin:keyLabel="-" - latin:popupCharacters="_,–,—" /> - <Key - latin:keyLabel="+" - latin:popupCharacters="±" /> - <Key - latin:keyLabel="(" - latin:popupCharacters="[,{,<" /> - <Key - latin:keyLabel=")" - latin:popupCharacters="],},>" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyStyle="altKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="!" - latin:popupCharacters="¡" /> - <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. --> - <!-- latin:popupCharacters="“,”,„,‟,«,»" --> - <Key - latin:keyLabel=""" - latin:popupCharacters="“,”,«,»" - latin:maxPopupKeyboardColumn="6" /> - <Key - latin:keyLabel="\'" - latin:popupCharacters="‘,’,‚,‛" /> - <Key - latin:keyLabel=":" /> - <Key - latin:keyLabel=";" /> - <Key - latin:keyLabel="/" /> - <Key - latin:keyLabel="\?" - latin:popupCharacters="¿" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </Row> - <include latin:keyboardLayout="@xml/kbd_symbols_row4" /> -</Keyboard> diff --git a/java/res/xml-large/kbd_symbols_shift.xml b/java/res/xml-large/kbd_symbols_shift.xml deleted file mode 100644 index 97fbc1ec7..000000000 --- a/java/res/xml-large/kbd_symbols_shift.xml +++ /dev/null @@ -1,130 +0,0 @@ -<?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. -*/ ---> - -<Keyboard - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" - latin:rowHeight="25%p" - latin:keyWidth="10%p" - latin:horizontalGap="@dimen/key_horizontal_gap" - latin:verticalGap="@dimen/key_bottom_gap" - latin:popupKeyboardTemplate="@xml/kbd_popup_template" - latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" -> - <include - latin:keyboardLayout="@xml/kbd_key_styles" /> - <Row - latin:rowEdgeFlags="top" - > - <Key - latin:keyLabel="~" - latin:keyEdgeFlags="left" /> - <Key - latin:keyLabel="`" /> - <Key - latin:keyLabel="|" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="•" - latin:popupCharacters="♪,♥,♠,♦,♣" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="√" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="π" - latin:popupCharacters="Π" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="÷" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="×" /> - <Key - latin:keyLabel="{" /> - <Key - latin:keyLabel="}" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyStyle="nonSpecialBackgroundTabKeyStyle" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="£" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="¢" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="€" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="°" - latin:popupCharacters="′,″" /> - <Key - latin:keyLabel="^" - latin:popupCharacters="↑,↓,←,→" /> - <Key - latin:keyLabel="_" /> - <Key - latin:keyLabel="=" - latin:popupCharacters="≠,≈,∞" /> - <Key - latin:keyLabel="[" /> - <Key - latin:keyLabel="]" - latin:keyEdgeFlags="right" /> - </Row> - <Row> - <Key - latin:keyStyle="shiftKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="left" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="™" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="®" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="©" /> - <Key - latin:keyStyle="nonPasswordSymbolKeyStyle" - latin:keyLabel="¶" - latin:popupCharacters="§" /> - <Key - latin:keyLabel="\\" /> - <Key - latin:keyLabel="<" - latin:popupCharacters="≤,«,‹" /> - <Key - latin:keyLabel=">" - latin:popupCharacters="≥,»,›" /> - <Key - latin:keyStyle="deleteKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </Row> - <include latin:keyboardLayout="@xml/kbd_symbols_shift_row4" /> -</Keyboard> diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml index 441b7cb17..e7a743ca9 100644 --- a/java/res/xml-nb/kbd_qwerty.xml +++ b/java/res/xml-nb/kbd_qwerty.xml @@ -21,12 +21,14 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="nb" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" /> diff --git a/java/res/xml-large/kbd_qwerty.xml b/java/res/xml-pl/kbd_qwerty.xml index 9541e13fd..ab5b88728 100644 --- a/java/res/xml-large/kbd_qwerty.xml +++ b/java/res/xml-pl/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="pl" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows" /> diff --git a/java/res/xml-xlarge/kbd_qwerty.xml b/java/res/xml-pt/kbd_qwerty.xml index 1c8d51ffe..83fb5b4c1 100644 --- a/java/res/xml-xlarge/kbd_qwerty.xml +++ b/java/res/xml-pt/kbd_qwerty.xml @@ -2,7 +2,7 @@ <!-- /* ** -** Copyright 2010, The Android Open Source Project +** 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. @@ -21,12 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" + latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="pt" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows" /> diff --git a/java/res/xml-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml index 0eb311501..826818c46 100644 --- a/java/res/xml-ru/kbd_qwerty.xml +++ b/java/res/xml-ru/kbd_qwerty.xml @@ -21,12 +21,14 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="ru" > <include latin:keyboardLayout="@xml/kbd_ru_rows" /> diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml index 3995e4e27..6116c7536 100644 --- a/java/res/xml-sr/kbd_qwerty.xml +++ b/java/res/xml-sr/kbd_qwerty.xml @@ -21,12 +21,14 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="sr" > <include latin:keyboardLayout="@xml/kbd_sr_rows" /> diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml index 72bdc339e..69f0b3fa0 100644 --- a/java/res/xml-sv/kbd_qwerty.xml +++ b/java/res/xml-sv/kbd_qwerty.xml @@ -21,12 +21,14 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="sv" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" /> diff --git a/java/res/xml-xlarge/kbd_ar_rows.xml b/java/res/xml-xlarge/kbd_ar_rows.xml new file mode 100644 index 000000000..e84aae6b5 --- /dev/null +++ b/java/res/xml-xlarge/kbd_ar_rows.xml @@ -0,0 +1,139 @@ +<?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. +*/ +--> + +<!-- This file for Arabic layout is an alpha version. It allows to enter --> +<!-- some right-to-left text, but it has gone through no study whatsoever, --> +<!-- and needs to be run through UX. --> +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <include + latin:keyboardLayout="@xml/kbd_key_styles" /> + <Row + latin:keyWidth="7.49%p" + > + <Key + latin:keyStyle="tabKeyStyle" + latin:keyLabelOption="alignLeft" + latin:keyWidth="7.949%p" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ض" /> + <Key + latin:keyLabel="ص" /> + <Key + latin:keyLabel="ث" /> + <Key + latin:keyLabel="ق" /> + <Key + latin:keyLabel="ف" + latin:popupCharacters="ف,ڤ" /> + <Key + latin:keyLabel="غ" /> + <Key + latin:keyLabel="ع" /> + <Key + latin:keyLabel="ه" + latin:popupCharacters="ه,هـ" /> + <Key + latin:keyLabel="خ" /> + <Key + latin:keyLabel="ح" /> + <Key + latin:keyLabel="ج" + latin:popupCharacters="ج,چ" /> + <Key + latin:keyStyle="deleteKeyStyle" + latin:keyWidth="9.331%p" + latin:keyEdgeFlags="right" /> + </Row> + <Row + latin:keyWidth="7.49%p" + > + <Key + latin:keyStyle="toSymbolKeyStyle" + latin:keyLabelOption="alignLeft" + latin:keyWidth="7.949%p" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ش" /> + <Key + latin:keyLabel="س" /> + <Key + latin:keyLabel="ي" /> + <Key + latin:keyLabel="ب" + latin:popupCharacters="ب,پ" /> + <Key + latin:keyLabel="ل" + latin:popupCharacters="ل,لا" /> + <Key + latin:keyLabel="ا" + latin:popupCharacters="ا,أ,إ,آ" /> + <Key + latin:keyLabel="ت" /> + <Key + latin:keyLabel="ن" /> + <Key + latin:keyLabel="م" /> + <Key + latin:keyLabel="ك" + latin:popupCharacters="ك,گ" /> + <Key + latin:keyLabel="ط" /> + <Key + latin:keyStyle="returnKeyStyle" + latin:keyWidth="8.593%p" + latin:keyEdgeFlags="right" /> + </Row> + <Row + latin:keyWidth="8.042%p" + > + <Key + latin:keyLabel="ئ" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ء" /> + <Key + latin:keyLabel="ؤ" /> + <Key + latin:keyLabel="ر" /> + <Key + latin:keyLabel="ذ" /> + <Key + latin:keyLabel="ى" /> + <Key + latin:keyLabel="ة" /> + <Key + latin:keyLabel="و" /> + <Key + latin:keyLabel="ز" + latin:popupCharacters="ز,ژ" /> + <Key + latin:keyLabel="ظ" /> + <Key + latin:keyLabel="د" /> + <Key + latin:keyStyle="shiftKeyStyle" + latin:keyWidth="11.736%p" + latin:keyEdgeFlags="right" /> + </Row> + <include latin:keyboardLayout="@xml/kbd_qwerty_row4" /> +</merge> diff --git a/java/res/xml-xlarge/kbd_iw_rows.xml b/java/res/xml-xlarge/kbd_iw_rows.xml new file mode 100644 index 000000000..a3a239dbf --- /dev/null +++ b/java/res/xml-xlarge/kbd_iw_rows.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2011, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <include + latin:keyboardLayout="@xml/kbd_key_styles" /> + <Row + latin:keyWidth="8.272%p" + > + <Key + latin:keyStyle="tabKeyStyle" + latin:keyLabelOption="alignLeft" + latin:keyWidth="7.949%p" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="," /> + <Key + latin:keyLabel="." /> + <Key + latin:keyLabel="ק" /> + <Key + latin:keyLabel="ר" /> + <Key + latin:keyLabel="א" /> + <Key + latin:keyLabel="ט" /> + <Key + latin:keyLabel="ו" /> + <Key + latin:keyLabel="ן" /> + <Key + latin:keyLabel="ם" /> + <Key + latin:keyLabel="פ" /> + <Key + latin:keyStyle="deleteKeyStyle" + latin:keyWidth="9.331%p" + latin:keyEdgeFlags="right" /> + </Row> + <Row + latin:keyWidth="8.157%p" + > + <Key + latin:keyStyle="toSymbolKeyStyle" + latin:keyLabelOption="alignLeft" + latin:keyWidth="10.167%p" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ש" /> + <Key + latin:keyLabel="ד" /> + <Key + latin:keyLabel="ג" + latin:popupCharacters="ג,ג׳" /> + <Key + latin:keyLabel="כ" /> + <Key + latin:keyLabel="ע" /> + <Key + latin:keyLabel="י" + latin:popupCharacters="י,ײַ" /> + <Key + latin:keyLabel="ח" + latin:popupCharacters="ח,ח׳" /> + <Key + latin:keyLabel="ל" /> + <Key + latin:keyLabel="ך" /> + <Key + latin:keyLabel="ף" /> + <Key + latin:keyStyle="returnKeyStyle" + latin:keyWidth="8.593%p" + latin:keyEdgeFlags="right" /> + </Row> + <Row + latin:keyWidth="8.042%p" + > + <Key + latin:keyStyle="shiftKeyStyle" + latin:keyWidth="15.192%p" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ז" + latin:popupCharacters="ז,ז׳" /> + <Key + latin:keyLabel="ס" /> + <Key + latin:keyLabel="ב" /> + <Key + latin:keyLabel="ה" /> + <Key + latin:keyLabel="נ" /> + <Key + latin:keyLabel="מ" /> + <Key + latin:keyLabel="צ" + latin:popupCharacters="צ,צ׳" /> + <Key + latin:keyLabel="ת" + latin:popupCharacters="ת,ת׳" /> + <Key + latin:keyLabel="ץ" + latin:popupCharacters="ץ,ץ׳" /> + <Key + latin:keyStyle="shiftKeyStyle" + latin:keyWidth="12.530%p" + latin:keyEdgeFlags="right" /> + </Row> + <include latin:keyboardLayout="@xml/kbd_qwerty_row4" /> +</merge> diff --git a/java/res/xml-xlarge/kbd_key_styles.xml b/java/res/xml-xlarge/kbd_key_styles.xml index fc06d00fc..57eaccbae 100644 --- a/java/res/xml-xlarge/kbd_key_styles.xml +++ b/java/res/xml-xlarge/kbd_key_styles.xml @@ -28,7 +28,7 @@ > <key-style latin:styleName="functionalKeyStyle" - latin:isModifier="true" /> + latin:isFunctional="true" /> <key-style latin:styleName="shiftKeyStyle" latin:code="@integer/key_shift" @@ -73,7 +73,7 @@ latin:parentStyle="functionalKeyStyle" /> <key-style latin:styleName="micKeyStyle" - latin:code="@integer/key_voice" + latin:code="@integer/key_shortcut" latin:keyIcon="@drawable/sym_keyboard_voice_holo" latin:iconPreview="@drawable/sym_keyboard_feedback_mic" latin:parentStyle="functionalKeyStyle" /> @@ -127,7 +127,7 @@ latin:parentStyle="functionalKeyStyle" /> <key-style latin:styleName="micKeyStyle" - latin:code="@integer/key_voice" + latin:code="@integer/key_shortcut" latin:keyIcon="@drawable/sym_bkeyboard_mic" latin:iconPreview="@drawable/sym_keyboard_feedback_mic" latin:parentStyle="functionalKeyStyle" /> diff --git a/java/res/xml-xlarge/kbd_number.xml b/java/res/xml-xlarge/kbd_number.xml index 012b75115..7cb77ea00 100644 --- a/java/res/xml-xlarge/kbd_number.xml +++ b/java/res/xml-xlarge/kbd_number.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="11.949%p" latin:horizontalGap="@dimen/key_horizontal_gap" diff --git a/java/res/xml-xlarge/kbd_phone.xml b/java/res/xml-xlarge/kbd_phone.xml index 9122176a9..60edcf2bd 100644 --- a/java/res/xml-xlarge/kbd_phone.xml +++ b/java/res/xml-xlarge/kbd_phone.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="11.949%p" latin:horizontalGap="@dimen/key_horizontal_gap" diff --git a/java/res/xml-xlarge/kbd_phone_symbols.xml b/java/res/xml-xlarge/kbd_phone_symbols.xml index 055c14867..c388a4667 100644 --- a/java/res/xml-xlarge/kbd_phone_symbols.xml +++ b/java/res/xml-xlarge/kbd_phone_symbols.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="11.949%p" latin:horizontalGap="@dimen/key_horizontal_gap" diff --git a/java/res/xml-xlarge/kbd_symbols.xml b/java/res/xml-xlarge/kbd_symbols.xml index 16722a04b..41e8522dc 100644 --- a/java/res/xml-xlarge/kbd_symbols.xml +++ b/java/res/xml-xlarge/kbd_symbols.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" @@ -214,7 +215,7 @@ <Key latin:keyLabel="-" /> </case> - <default> + <default> <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. --> <!-- latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" --> <Key diff --git a/java/res/xml-xlarge/kbd_symbols_shift.xml b/java/res/xml-xlarge/kbd_symbols_shift.xml index cc23358a5..d7f5958b7 100644 --- a/java/res/xml-xlarge/kbd_symbols_shift.xml +++ b/java/res/xml-xlarge/kbd_symbols_shift.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" diff --git a/java/res/xml/kbd_ar_rows.xml b/java/res/xml/kbd_ar_rows.xml new file mode 100644 index 000000000..b2ea45701 --- /dev/null +++ b/java/res/xml/kbd_ar_rows.xml @@ -0,0 +1,119 @@ +<?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. +*/ +--> + +<!-- This file for Arabic layout is an alpha version. It allows to enter --> +<!-- some right-to-left text, but it has gone through no study whatsoever, --> +<!-- and needs to be run through UX. --> +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <include + latin:keyboardLayout="@xml/kbd_key_styles" /> + <Row + latin:keyWidth="10%p" + > + <Key + latin:keyLabel="ض" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ص" /> + <Key + latin:keyLabel="ق" /> + <Key + latin:keyLabel="ف" + latin:popupCharacters="ڤ" /> + <Key + latin:keyLabel="غ" /> + <Key + latin:keyLabel="ع" /> + <Key + latin:keyLabel="ه" + latin:popupCharacters="هـ" /> + <Key + latin:keyLabel="خ" /> + <Key + latin:keyLabel="ح" /> + <Key + latin:keyLabel="ج" + latin:popupCharacters="چ" + latin:keyEdgeFlags="right" /> + </Row> + <Row + latin:keyWidth="10%p" + > + <Key + latin:keyLabel="ش" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="س" /> + <Key + latin:keyLabel="ي" + latin:popupCharacters="ى,ئ" /> + <Key + latin:keyLabel="ب" + latin:popupCharacters="پ" /> + <Key + latin:keyLabel="ل" + latin:popupCharacters="لا" /> + <Key + latin:keyLabel="ا" + latin:popupCharacters="أ,إ,آ,ء" /> + <Key + latin:keyLabel="ت" /> + <Key + latin:keyLabel="ن" /> + <Key + latin:keyLabel="م" /> + <Key + latin:keyLabel="ك" + latin:popupCharacters="گ" + latin:keyEdgeFlags="right" /> + </Row> + <Row + latin:keyWidth="9.7%p" + > + <Key + latin:keyLabel="ظ" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ط" /> + <Key + latin:keyLabel="ذ" /> + <Key + latin:keyLabel="د" /> + <Key + latin:keyLabel="ز" + latin:popupCharacters="ژ" /> + <Key + latin:keyLabel="ر" /> + <Key + latin:keyLabel="و" + latin:popupCharacters="ؤ" /> + <Key + latin:keyLabel="ة" /> + <Key + latin:keyLabel="ث" /> + <Key + latin:keyStyle="deleteKeyStyle" + latin:keyWidth="12%p" + latin:keyEdgeFlags="right" /> + </Row> + <include latin:keyboardLayout="@xml/kbd_qwerty_row4" /> +</merge> diff --git a/java/res/xml/kbd_azerty_rows.xml b/java/res/xml/kbd_azerty_rows.xml index 9eeb22ecb..e805d5b1b 100644 --- a/java/res/xml/kbd_azerty_rows.xml +++ b/java/res/xml/kbd_azerty_rows.xml @@ -108,6 +108,7 @@ <Key latin:keyStyle="shiftKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsRight="1%p" latin:keyEdgeFlags="left" /> <Key latin:keyLabel="w" @@ -127,10 +128,12 @@ latin:keyLabel="n" latin:popupCharacters="@string/alternates_for_n" /> <Key - latin:keyLabel="\'" /> + latin:keyLabel="\'" + latin:popupCharacters="‘,’,‚,‛" /> <Key latin:keyStyle="deleteKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsLeft="1%p" latin:keyEdgeFlags="right" /> </Row> <include diff --git a/java/res/xml/kbd_iw_rows.xml b/java/res/xml/kbd_iw_rows.xml new file mode 100644 index 000000000..fb0c2a915 --- /dev/null +++ b/java/res/xml/kbd_iw_rows.xml @@ -0,0 +1,106 @@ +<?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. +*/ +--> + +<!-- This file for Hebrew layout is an alpha version. It allows to enter --> +<!-- some right-to-left text, but it has gone through no study whatsoever, --> +<!-- and needs to be run through UX. --> +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <include + latin:keyboardLayout="@xml/kbd_key_styles" /> + <Row + latin:rowEdgeFlags="top" + > + <Spacer + latin:horizontalGap="5%p" /> + <Key + latin:keyLabel="ק" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ר" /> + <Key + latin:keyLabel="א" /> + <Key + latin:keyLabel="ט" /> + <Key + latin:keyLabel="ו" /> + <Key + latin:keyLabel="ן" /> + <Key + latin:keyLabel="ם" /> + <Key + latin:keyLabel="פ" /> + <Key + latin:keyStyle="deleteKeyStyle" + latin:keyWidth="15%p" + latin:visualInsetsLeft="1%p" + latin:keyEdgeFlags="right" /> + </Row> + <Row> + <Key + latin:keyLabel="ש" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ד" /> + <Key + latin:keyLabel="ג" /> + <Key + latin:keyLabel="כ" /> + <Key + latin:keyLabel="ע" /> + <Key + latin:keyLabel="י" /> + <Key + latin:keyLabel="ח" /> + <Key + latin:keyLabel="ל" /> + <Key + latin:keyLabel="ך" /> + <Key + latin:keyLabel="ף" + latin:keyEdgeFlags="right" /> + </Row> + <Row> + <Spacer + latin:horizontalGap="5%p" /> + <Key + latin:keyLabel="ז" + latin:keyEdgeFlags="left" /> + <Key + latin:keyLabel="ס" /> + <Key + latin:keyLabel="ב" /> + <Key + latin:keyLabel="ה" /> + <Key + latin:keyLabel="נ" /> + <Key + latin:keyLabel="מ" /> + <Key + latin:keyLabel="צ" /> + <Key + latin:keyLabel="ת" /> + <Key + latin:keyLabel="ץ" + latin:keyEdgeFlags="right" /> + </Row> + <include latin:keyboardLayout="@xml/kbd_qwerty_row4" /> +</merge> diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml index 54522369b..d4d25d4a2 100644 --- a/java/res/xml/kbd_key_styles.xml +++ b/java/res/xml/kbd_key_styles.xml @@ -28,7 +28,7 @@ > <key-style latin:styleName="functionalKeyStyle" - latin:isModifier="true" /> + latin:isFunctional="true" /> </case> <case latin:colorScheme="black" @@ -118,7 +118,7 @@ latin:parentStyle="functionalKeyStyle" /> <key-style latin:styleName="micKeyStyle" - latin:code="@integer/key_voice" + latin:code="@integer/key_shortcut" latin:keyIcon="@drawable/sym_keyboard_mic" latin:iconPreview="@drawable/sym_keyboard_feedback_mic" latin:parentStyle="settingsPopupStyle" /> @@ -191,7 +191,7 @@ latin:parentStyle="functionalKeyStyle" /> <key-style latin:styleName="micKeyStyle" - latin:code="@integer/key_voice" + latin:code="@integer/key_shortcut" latin:keyIcon="@drawable/sym_bkeyboard_mic" latin:iconPreview="@drawable/sym_keyboard_feedback_mic" latin:parentStyle="settingsPopupStyle" /> @@ -335,4 +335,4 @@ latin:parentStyle="functionalKeyStyle" /> </default> </switch> -</merge> +</merge>
\ No newline at end of file diff --git a/java/res/xml/kbd_number.xml b/java/res/xml/kbd_number.xml index 7bd679bce..2556f6830 100644 --- a/java/res/xml/kbd_number.xml +++ b/java/res/xml/kbd_number.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="26.67%p" latin:horizontalGap="@dimen/key_horizontal_gap" diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml index 62fbdeeec..ca591c72d 100644 --- a/java/res/xml/kbd_phone.xml +++ b/java/res/xml/kbd_phone.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="26.67%p" latin:horizontalGap="@dimen/key_horizontal_gap" diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml index 67cd330e7..99db23ef1 100644 --- a/java/res/xml/kbd_phone_symbols.xml +++ b/java/res/xml/kbd_phone_symbols.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="26.67%p" latin:horizontalGap="@dimen/key_horizontal_gap" diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml index 92d92f0e6..fd43740a7 100644 --- a/java/res/xml/kbd_qwerty.xml +++ b/java/res/xml/kbd_qwerty.xml @@ -21,13 +21,15 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column" + latin:keyboardLocale="en_GB,en_US" > <include latin:keyboardLayout="@xml/kbd_qwerty_rows" /> diff --git a/java/res/xml/kbd_qwerty_row3.xml b/java/res/xml/kbd_qwerty_row3.xml index 26608fd71..3d106e615 100644 --- a/java/res/xml/kbd_qwerty_row3.xml +++ b/java/res/xml/kbd_qwerty_row3.xml @@ -27,6 +27,7 @@ <Key latin:keyStyle="shiftKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsRight="1%p" latin:keyEdgeFlags="left" /> <Key latin:keyLabel="z" @@ -49,6 +50,7 @@ <Key latin:keyStyle="deleteKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsLeft="1%p" latin:keyEdgeFlags="right" /> </Row> </merge> diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/kbd_qwerty_row4.xml index 0db011672..82f5a4a92 100644 --- a/java/res/xml/kbd_qwerty_row4.xml +++ b/java/res/xml/kbd_qwerty_row4.xml @@ -35,29 +35,28 @@ latin:keyEdgeFlags="left" /> <include latin:keyboardLayout="@xml/kbd_qwerty_f1" /> + <Key + latin:keyStyle="spaceKeyStyle" + latin:keyWidth="40%p" /> <switch> <case latin:mode="web" > - <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="20%p" /> - <Key - latin:keyStyle="tabKeyStyle" - latin:keyWidth="20%p" /> + <Key + latin:keyHintIcon="@drawable/hint_popup" + latin:popupCharacters="@string/alternates_for_web_tab_punctuation" + latin:maxPopupKeyboardColumn="8" + latin:keyStyle="tabKeyStyle" /> </case> <default> <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="40%p" /> + latin:keyLabel="." + latin:keyHintIcon="@drawable/hint_popup" + latin:popupCharacters="@string/alternates_for_punctuation" + latin:maxPopupKeyboardColumn="7" + latin:keyStyle="functionalKeyStyle" /> </default> </switch> - <Key - latin:keyLabel="." - latin:keyHintIcon="@drawable/hint_popup" - latin:popupCharacters="@string/alternates_for_punctuation" - latin:maxPopupKeyboardColumn="7" - latin:keyStyle="functionalKeyStyle" /> <switch> <case latin:mode="im" @@ -86,28 +85,28 @@ latin:keyStyle="settingsKeyStyle" /> <include latin:keyboardLayout="@xml/kbd_qwerty_f1" /> + <Key + latin:keyStyle="spaceKeyStyle" + latin:keyWidth="30%p" /> <switch> <case latin:mode="web" > - <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="30%p" /> - <Key + <Key + latin:keyHintIcon="@drawable/hint_popup" + latin:popupCharacters="@string/alternates_for_web_tab_punctuation" + latin:maxPopupKeyboardColumn="8" latin:keyStyle="tabKeyStyle" /> </case> <default> <Key - latin:keyStyle="spaceKeyStyle" - latin:keyWidth="30%p" /> + latin:keyLabel="." + latin:keyHintIcon="@drawable/hint_popup" + latin:popupCharacters="@string/alternates_for_punctuation" + latin:maxPopupKeyboardColumn="7" + latin:keyStyle="functionalKeyStyle" /> </default> </switch> - <Key - latin:keyLabel="." - latin:keyHintIcon="@drawable/hint_popup" - latin:popupCharacters="@string/alternates_for_punctuation" - latin:maxPopupKeyboardColumn="7" - latin:keyStyle="functionalKeyStyle" /> <switch> <case latin:mode="im" @@ -117,14 +116,6 @@ latin:keyWidth="25%p" latin:keyEdgeFlags="right" /> </case> - <case - latin:mode="web" - > - <Key - latin:keyStyle="returnKeyStyle" - latin:keyWidth="15%p" - latin:keyEdgeFlags="right" /> - </case> <default> <Key latin:keyStyle="returnKeyStyle" diff --git a/java/res/xml/kbd_qwertz_rows.xml b/java/res/xml/kbd_qwertz_rows.xml index 375f12335..bb41f067a 100644 --- a/java/res/xml/kbd_qwertz_rows.xml +++ b/java/res/xml/kbd_qwertz_rows.xml @@ -78,6 +78,7 @@ <Key latin:keyStyle="shiftKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsRight="1%p" latin:keyEdgeFlags="left" /> <Key latin:keyLabel="y" @@ -100,6 +101,7 @@ <Key latin:keyStyle="deleteKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsLeft="1%p" latin:keyEdgeFlags="right" /> </Row> <include diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml index bd3917bb2..0a8068991 100644 --- a/java/res/xml/kbd_symbols.xml +++ b/java/res/xml/kbd_symbols.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" @@ -100,6 +101,7 @@ <Key latin:keyStyle="altKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsRight="1%p" latin:keyEdgeFlags="left" /> <Key latin:keyLabel="!" @@ -125,6 +127,7 @@ <Key latin:keyStyle="deleteKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsLeft="1%p" latin:keyEdgeFlags="right" /> </Row> <include latin:keyboardLayout="@xml/kbd_symbols_row4" /> diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml index b99d97084..cde07333b 100644 --- a/java/res/xml/kbd_symbols_shift.xml +++ b/java/res/xml/kbd_symbols_shift.xml @@ -21,7 +21,8 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyboardHeight="@dimen/keyboardHeight" - latin:maxKeyboardHeight="50%p" + latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" + latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" latin:keyWidth="10%p" latin:horizontalGap="@dimen/key_horizontal_gap" @@ -99,6 +100,7 @@ <Key latin:keyStyle="shiftKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsRight="1%p" latin:keyEdgeFlags="left" /> <Key latin:keyStyle="nonPasswordSymbolKeyStyle" @@ -124,6 +126,7 @@ <Key latin:keyStyle="deleteKeyStyle" latin:keyWidth="15%p" + latin:visualInsetsLeft="1%p" latin:keyEdgeFlags="right" /> </Row> <include latin:keyboardLayout="@xml/kbd_symbols_shift_row4" /> diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/kbd_symbols_shift_row4.xml index e4b5403b5..4f8567d58 100644 --- a/java/res/xml/kbd_symbols_shift_row4.xml +++ b/java/res/xml/kbd_symbols_shift_row4.xml @@ -34,6 +34,7 @@ latin:keyEdgeFlags="left" /> <Key latin:keyLabel="„" + latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" latin:keyStyle="nonPasswordFunctionalKeyStyle" /> <Key latin:keyStyle="spaceKeyStyle" @@ -69,6 +70,7 @@ latin:keyStyle="settingsKeyStyle" /> <Key latin:keyLabel="„" + latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" latin:keyStyle="nonPasswordFunctionalKeyStyle" /> <Key latin:keyStyle="spaceKeyStyle" diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 8dec7abec..aba6974a8 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -24,6 +24,7 @@ <!-- Voice: af, cs, da, de, en, es, fr, it, ja, ko, nl, pl, pt, ru, tr, yue, zh, zu --> <!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. --> <!-- TODO: use <lang>_mic icon instead of a common mic icon. --> +<!-- TODO: remove all comment outed voice subtypes --> <!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default subtype.--> <input-method xmlns:android="http://schemas.android.com/apk/res/android" @@ -34,28 +35,34 @@ android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_en_voice" - android:imeSubtypeLocale="en" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_en_voice" --> +<!-- android:imeSubtypeLocale="en" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_en_GB_keyboard" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" /> + <!-- The file for Arabic layout is an alpha version. It needs to be run through UX. --> <subtype android:icon="@drawable/ic_subtype_keyboard" - android:label="@string/subtype_mode_cs_keyboard" - android:imeSubtypeLocale="cs" + android:label="@string/subtype_mode_ar_keyboard" + android:imeSubtypeLocale="ar" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_cs_voice" + <subtype android:icon="@drawable/ic_subtype_keyboard" + android:label="@string/subtype_mode_cs_keyboard" android:imeSubtypeLocale="cs" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" + android:imeSubtypeMode="keyboard" /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_cs_voice" --> +<!-- android:imeSubtypeLocale="cs" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_da_keyboard" android:imeSubtypeLocale="da" @@ -65,36 +72,35 @@ android:label="@string/subtype_mode_de_keyboard" android:imeSubtypeLocale="de" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="requiresGermanUmlautProcessing" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_de_voice" - android:imeSubtypeLocale="de" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_de_voice" --> +<!-- android:imeSubtypeLocale="de" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_es_keyboard" android:imeSubtypeLocale="es" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_es_voice" - android:imeSubtypeLocale="es" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_es_voice" --> +<!-- android:imeSubtypeLocale="es" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_fr_keyboard" android:imeSubtypeLocale="fr" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_fr_voice" - android:imeSubtypeLocale="fr" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_fr_voice" --> +<!-- android:imeSubtypeLocale="fr" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_fr_CA_keyboard" android:imeSubtypeLocale="fr_CA" @@ -110,12 +116,19 @@ android:imeSubtypeLocale="it" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_it_voice" - android:imeSubtypeLocale="it" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" + <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. --> + <!-- The file for Hebrew layout is an alpha version. It needs to be run through UX. --> + <subtype android:icon="@drawable/ic_subtype_keyboard" + android:label="@string/subtype_mode_iw_keyboard" + android:imeSubtypeLocale="iw" + android:imeSubtypeMode="keyboard" /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_it_voice" --> +<!-- android:imeSubtypeLocale="it" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_nb_keyboard" android:imeSubtypeLocale="nb" @@ -126,11 +139,21 @@ android:imeSubtypeLocale="nl" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_nl_voice" - android:imeSubtypeLocale="nl" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_nl_voice" --> +<!-- android:imeSubtypeLocale="nl" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> + <subtype android:icon="@drawable/ic_subtype_keyboard" + android:label="@string/subtype_mode_pl_keyboard" + android:imeSubtypeLocale="pl" + android:imeSubtypeMode="keyboard" + /> + <subtype android:icon="@drawable/ic_subtype_keyboard" + android:label="@string/subtype_mode_pt_keyboard" + android:imeSubtypeLocale="pt" + android:imeSubtypeMode="keyboard" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_mode_ru_keyboard" @@ -147,64 +170,64 @@ android:imeSubtypeLocale="sv" android:imeSubtypeMode="keyboard" /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_af_voice" - android:imeSubtypeLocale="af" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_ja_voice" - android:imeSubtypeLocale="ja" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_ko_voice" - android:imeSubtypeLocale="ko" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_pl_voice" - android:imeSubtypeLocale="pl" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_pt_voice" - android:imeSubtypeLocale="pt" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_ru_voice" - android:imeSubtypeLocale="ru" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_tr_voice" - android:imeSubtypeLocale="tr" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_yue_voice" - android:imeSubtypeLocale="yue" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_zh_voice" - android:imeSubtypeLocale="zh" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> - <subtype android:icon="@drawable/ic_subtype_mic" - android:label="@string/subtype_mode_zu_voice" - android:imeSubtypeLocale="zu" - android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" - /> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_af_voice" --> +<!-- android:imeSubtypeLocale="af" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_ja_voice" --> +<!-- android:imeSubtypeLocale="ja" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_ko_voice" --> +<!-- android:imeSubtypeLocale="ko" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_pl_voice" --> +<!-- android:imeSubtypeLocale="pl" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_pt_voice" --> +<!-- android:imeSubtypeLocale="pt" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_ru_voice" --> +<!-- android:imeSubtypeLocale="ru" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_tr_voice" --> +<!-- android:imeSubtypeLocale="tr" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_yue_voice" --> +<!-- android:imeSubtypeLocale="yue" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_zh_voice" --> +<!-- android:imeSubtypeLocale="zh" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> +<!-- <subtype android:icon="@drawable/ic_subtype_mic" --> +<!-- android:label="@string/subtype_mode_zu_voice" --> +<!-- android:imeSubtypeLocale="zu" --> +<!-- android:imeSubtypeMode="voice" --> +<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" --> +<!-- /> --> </input-method> diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml index d031415d7..b0497a51c 100644 --- a/java/res/xml/prefs.xml +++ b/java/res/xml/prefs.xml @@ -14,86 +14,66 @@ limitations under the License. --> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" - android:title="@string/english_ime_settings" - android:key="english_ime_settings"> - +<PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android" + android:title="@string/english_ime_settings" + android:key="english_ime_settings"> <PreferenceCategory - android:title="@string/general_category" - android:key="general_settings"> - + android:title="@string/general_category" + android:key="general_settings"> <CheckBoxPreference - android:key="auto_cap" - android:title="@string/auto_cap" - android:persistent="true" - android:defaultValue="true" - /> - + android:key="auto_cap" + android:title="@string/auto_cap" + android:persistent="true" + android:defaultValue="true" /> <CheckBoxPreference - android:key="vibrate_on" - android:title="@string/vibrate_on_keypress" - android:persistent="true" - /> - + android:key="vibrate_on" + android:title="@string/vibrate_on_keypress" + android:persistent="true" /> <CheckBoxPreference - android:key="sound_on" - android:title="@string/sound_on_keypress" - android:defaultValue="@bool/config_default_sound_enabled" - android:persistent="true" - /> - + android:key="sound_on" + android:title="@string/sound_on_keypress" + android:defaultValue="@bool/config_default_sound_enabled" + android:persistent="true" /> <CheckBoxPreference - android:key="popup_on" - android:title="@string/popup_on_keypress" - android:persistent="true" - android:defaultValue="@bool/config_default_popup_preview" - /> - + android:key="popup_on" + android:title="@string/popup_on_keypress" + android:persistent="true" + android:defaultValue="@bool/config_default_popup_preview" /> <CheckBoxPreference - android:key="recorrection_enabled" - android:title="@string/prefs_enable_recorrection" - android:summary="@string/prefs_enable_recorrection_summary" - android:persistent="true" - android:defaultValue="@bool/config_default_recorrection_enabled" - /> - + android:key="recorrection_enabled" + android:title="@string/prefs_enable_recorrection" + android:summary="@string/prefs_enable_recorrection_summary" + android:persistent="true" + android:defaultValue="@bool/config_default_recorrection_enabled" /> <ListPreference - android:key="settings_key" - android:title="@string/prefs_settings_key" - android:persistent="true" - android:entryValues="@array/settings_key_modes_values" - android:entries="@array/settings_key_modes" - android:defaultValue="@string/settings_key_mode_auto" - /> - + android:key="settings_key" + android:title="@string/prefs_settings_key" + android:persistent="true" + android:entryValues="@array/settings_key_modes_values" + android:entries="@array/settings_key_modes" + android:defaultValue="@string/settings_key_mode_auto" /> <ListPreference - android:key="voice_mode" - android:title="@string/voice_input" - android:persistent="true" - android:entryValues="@array/voice_input_modes_values" - android:entries="@array/voice_input_modes" - android:defaultValue="@string/voice_mode_main" - /> - + android:key="voice_mode" + android:title="@string/voice_input" + 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" /> - + android:key="subtype_settings" + android:title="@string/language_selection_title" + android:summary="@string/language_selection_summary" /> </PreferenceCategory> - <PreferenceCategory - android:title="@string/prediction_category" - android:key="prediction_settings"> - + android:title="@string/correction_category" + android:key="correction_settings"> <CheckBoxPreference android:key="quick_fixes" android:title="@string/quick_fixes" android:summary="@string/quick_fixes_summary" android:persistent="true" - android:defaultValue="true" - /> - + android:defaultValue="true" /> <ListPreference android:key="auto_correction_threshold" android:title="@string/auto_correction" @@ -101,9 +81,7 @@ android:persistent="true" android:entryValues="@array/auto_correction_threshold_mode_indexes" android:entries="@array/auto_correction_threshold_modes" - 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" @@ -111,23 +89,62 @@ android:persistent="true" android:entryValues="@array/prefs_suggestion_visibility_values" android:entries="@array/prefs_suggestion_visibilities" - android:defaultValue="@string/prefs_suggestion_visibility_default_value" - /> - + android:defaultValue="@string/prefs_suggestion_visibility_default_value" /> + </PreferenceCategory> + <PreferenceCategory + android:title="@string/ngram_category" + android:key="ngram_settings"> <CheckBoxPreference android:key="bigram_suggestion" android:title="@string/bigram_suggestion" android:summary="@string/bigram_suggestion_summary" android:persistent="true" - android:defaultValue="true" - /> - </PreferenceCategory> - - <CheckBoxPreference - android:key="usability_study_mode" - android:title="@string/prefs_usability_study_mode" + android:defaultValue="true" /> + <CheckBoxPreference + android:key="bigram_prediction" + android:dependency="bigram_suggestion" + android:title="@string/bigram_prediction" + android:summary="@string/bigram_prediction_summary" android:persistent="true" - android:defaultValue="false" - /> - + android:defaultValue="false" /> + </PreferenceCategory> + <PreferenceCategory + android:title="@string/misc_category" + android:key="misc_settings"> + <CheckBoxPreference + android:key="usability_study_mode" + android:title="@string/prefs_usability_study_mode" + android:persistent="true" + android:defaultValue="false" /> + <CheckBoxPreference + android:key="enable_logging" + android:title="@string/prefs_enable_log" + android:summary="@string/prefs_description_log" + android:persistent="true" + android:defaultValue="true" /> + <ListPreference + android:key="pref_keyboard_layout_20100902" + android:title="@string/keyboard_layout" + android:persistent="true" + android:entryValues="@array/keyboard_layout_modes_values" + android:entries="@array/keyboard_layout_modes" + android:defaultValue="@string/config_default_keyboard_theme_id" /> + </PreferenceCategory> + <PreferenceScreen + android:key="pref_advanced_settings" + android:title="@string/advanced_settings" + android:summary="@string/advanced_settings_summary"> + <!-- Values for popup dismiss delay are added programatically --> + <ListPreference + android:key="pref_key_preview_popup_dismiss_delay" + android:title="@string/key_preview_popup_dismiss_delay" /> + </PreferenceScreen> + <!-- <Preference + android:title="Debug Settings" + android:key="debug_settings"> + <intent + android:action="android.intent.action.MAIN" + android:targetPackage="com.android.inputmethod.latin" + android:targetClass="com.android.inputmethod.latin.DebugSettings" /> + </Preference>--> </PreferenceScreen> diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml index 2dad17148..477461df4 100644 --- a/java/res/xml/prefs_for_debug.xml +++ b/java/res/xml/prefs_for_debug.xml @@ -36,6 +36,13 @@ /> <CheckBoxPreference + android:key="use_spacebar_language_switch" + android:title="@string/prefs_use_spacebar_language_switch" + android:persistent="true" + android:defaultValue="false" + /> + + <CheckBoxPreference android:key="debug_mode" android:title="@string/prefs_debug_mode" android:persistent="true" diff --git a/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java new file mode 100644 index 000000000..65949357f --- /dev/null +++ b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java @@ -0,0 +1,39 @@ +/* + * 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.compat; + +import android.util.Log; + +public abstract class AbstractCompatWrapper { + private static final String TAG = AbstractCompatWrapper.class.getSimpleName(); + protected final Object mObj; + + public AbstractCompatWrapper(Object obj) { + if (obj == null) { + Log.e(TAG, "Invalid input to AbstructCompatWrapper"); + } + mObj = obj; + } + + public Object getOriginalObject() { + return mObj; + } + + public boolean hasOriginalObject() { + return mObj != null; + } +} diff --git a/java/src/com/android/inputmethod/compat/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java new file mode 100644 index 000000000..10b2a106f --- /dev/null +++ b/java/src/com/android/inputmethod/compat/CompatUtils.java @@ -0,0 +1,160 @@ +/* + * 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.compat; + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +public class CompatUtils { + private static final String TAG = CompatUtils.class.getSimpleName(); + private static final String EXTRA_INPUT_METHOD_ID = "input_method_id"; + // TODO: Can these be constants instead of literal String constants? + private static final String INPUT_METHOD_SUBTYPE_SETTINGS = + "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; + private static final String INPUT_LANGUAGE_SELECTION = + "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION"; + + public static Intent getInputLanguageSelectionIntent(String inputMethodId, + int flagsForSubtypeSettings) { + final String action; + Intent intent; + if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED + /* android.os.Build.VERSION_CODES.HONEYCOMB */ + && android.os.Build.VERSION.SDK_INT >= 11) { + // Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS + action = INPUT_METHOD_SUBTYPE_SETTINGS; + intent = new Intent(action); + if (!TextUtils.isEmpty(inputMethodId)) { + intent.putExtra(EXTRA_INPUT_METHOD_ID, inputMethodId); + } + if (flagsForSubtypeSettings > 0) { + intent.setFlags(flagsForSubtypeSettings); + } + } else { + action = INPUT_LANGUAGE_SELECTION; + intent = new Intent(action); + } + return intent; + } + + public static Class<?> getClass(String className) { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + return null; + } + } + + public static Method getMethod(Class<?> targetClass, String name, + Class<?>... parameterTypes) { + if (targetClass == null || TextUtils.isEmpty(name)) return null; + try { + return targetClass.getMethod(name, parameterTypes); + } catch (SecurityException e) { + // ignore + return null; + } catch (NoSuchMethodException e) { + // ignore + return null; + } + } + + public static Field getField(Class<?> targetClass, String name) { + try { + return targetClass.getField(name); + } catch (SecurityException e) { + // ignore + return null; + } catch (NoSuchFieldException e) { + // ignore + return null; + } + } + + public static Constructor<?> getConstructor(Class<?> targetClass, Class<?>[] types) { + if (targetClass == null || types == null) return null; + try { + return targetClass.getConstructor(types); + } catch (SecurityException e) { + // ignore + return null; + } catch (NoSuchMethodException e) { + // ignore + return null; + } + } + + public static Object invoke( + Object receiver, Object defaultValue, Method method, Object... args) { + if (method == null) return defaultValue; + try { + return method.invoke(receiver, args); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Exception in invoke: IllegalArgumentException"); + return defaultValue; + } catch (IllegalAccessException e) { + Log.e(TAG, "Exception in invoke: IllegalAccessException"); + return defaultValue; + } catch (InvocationTargetException e) { + Log.e(TAG, "Exception in invoke: IllegalTargetException"); + return defaultValue; + } + } + + public static Object getFieldValue(Object receiver, Object defaultValue, Field field) { + if (field == null) return defaultValue; + try { + return field.get(receiver); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Exception in getFieldValue: IllegalArgumentException"); + return defaultValue; + } catch (IllegalAccessException e) { + Log.e(TAG, "Exception in getFieldValue: IllegalAccessException"); + return defaultValue; + } + } + + public static void setFieldValue(Object receiver, Field field, Object value) { + if (field == null) return; + try { + field.set(receiver, value); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Exception in setFieldValue: IllegalArgumentException"); + } catch (IllegalAccessException e) { + Log.e(TAG, "Exception in setFieldValue: IllegalAccessException"); + } + } + + public static List<InputMethodSubtypeCompatWrapper> copyInputMethodSubtypeListToWrapper( + Object listObject) { + if (!(listObject instanceof List<?>)) return null; + final List<InputMethodSubtypeCompatWrapper> subtypes = + new ArrayList<InputMethodSubtypeCompatWrapper>(); + for (Object o: (List<?>)listObject) { + subtypes.add(new InputMethodSubtypeCompatWrapper(o)); + } + return subtypes; + } +} diff --git a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java new file mode 100644 index 000000000..2789bcb39 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java @@ -0,0 +1,102 @@ +/* + * 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.compat; + +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; + +import java.lang.reflect.Field; + +public class EditorInfoCompatUtils { + private static final Field FIELD_IME_FLAG_NAVIGATE_NEXT = CompatUtils.getField( + EditorInfo.class, "IME_FLAG_NAVIGATE_NEXT"); + private static final Field FIELD_IME_FLAG_NAVIGATE_PREVIOUS = CompatUtils.getField( + EditorInfo.class, "IME_FLAG_NAVIGATE_PREVIOUS"); + private static final Field FIELD_IME_ACTION_PREVIOUS = CompatUtils.getField( + EditorInfo.class, "IME_FLAG_ACTION_PREVIOUS"); + private static final Integer OBJ_IME_FLAG_NAVIGATE_NEXT = (Integer) CompatUtils + .getFieldValue(null, null, FIELD_IME_FLAG_NAVIGATE_NEXT); + private static final Integer OBJ_IME_FLAG_NAVIGATE_PREVIOUS = (Integer) CompatUtils + .getFieldValue(null, null, FIELD_IME_FLAG_NAVIGATE_PREVIOUS); + private static final Integer OBJ_IME_ACTION_PREVIOUS = (Integer) CompatUtils + .getFieldValue(null, null, FIELD_IME_ACTION_PREVIOUS); + + public static boolean hasFlagNavigateNext(int imeOptions) { + if (OBJ_IME_FLAG_NAVIGATE_NEXT == null) + return false; + return (imeOptions & OBJ_IME_FLAG_NAVIGATE_NEXT) != 0; + } + + public static boolean hasFlagNavigatePrevious(int imeOptions) { + if (OBJ_IME_FLAG_NAVIGATE_PREVIOUS == null) + return false; + return (imeOptions & OBJ_IME_FLAG_NAVIGATE_PREVIOUS) != 0; + } + + public static void performEditorActionNext(InputConnection ic) { + ic.performEditorAction(EditorInfo.IME_ACTION_NEXT); + } + + public static void performEditorActionPrevious(InputConnection ic) { + if (OBJ_IME_ACTION_PREVIOUS == null) + return; + ic.performEditorAction(OBJ_IME_ACTION_PREVIOUS); + } + + public static String imeOptionsName(int imeOptions) { + if (imeOptions == -1) + return null; + final int actionId = imeOptions & EditorInfo.IME_MASK_ACTION; + final String action; + switch (actionId) { + case EditorInfo.IME_ACTION_UNSPECIFIED: + action = "actionUnspecified"; + break; + case EditorInfo.IME_ACTION_NONE: + action = "actionNone"; + break; + case EditorInfo.IME_ACTION_GO: + action = "actionGo"; + break; + case EditorInfo.IME_ACTION_SEARCH: + action = "actionSearch"; + break; + case EditorInfo.IME_ACTION_SEND: + action = "actionSend"; + break; + case EditorInfo.IME_ACTION_NEXT: + action = "actionNext"; + break; + case EditorInfo.IME_ACTION_DONE: + action = "actionDone"; + break; + default: { + if (OBJ_IME_ACTION_PREVIOUS != null && actionId == OBJ_IME_ACTION_PREVIOUS) { + action = "actionPrevious"; + } else { + action = "actionUnknown(" + actionId + ")"; + } + break; + } + } + if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) { + return "flagNoEnterAction|" + action; + } else { + return action; + } + } +} diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java new file mode 100644 index 000000000..c926be06f --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java @@ -0,0 +1,91 @@ +/* + * 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.compat; + +import com.android.inputmethod.latin.EditingUtils.SelectedWord; + +import android.util.Log; +import android.view.inputmethod.InputConnection; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class InputConnectionCompatUtils { + private static final String TAG = InputConnectionCompatUtils.class.getSimpleName(); + private static final Class<?> CLASS_CorrectionInfo = CompatUtils + .getClass("android.view.inputmethod.CorrectionInfo"); + private static final Class<?>[] INPUT_TYPE_CorrectionInfo = new Class<?>[] { int.class, + CharSequence.class, CharSequence.class }; + private static final Constructor<?> CONSTRUCTOR_CorrectionInfo = CompatUtils + .getConstructor(CLASS_CorrectionInfo, INPUT_TYPE_CorrectionInfo); + private static final Method METHOD_InputConnection_commitCorrection = CompatUtils + .getMethod(InputConnection.class, "commitCorrection", CLASS_CorrectionInfo); + private static final Method METHOD_getSelectedText = CompatUtils + .getMethod(InputConnection.class, "getSelectedText", int.class); + private static final Method METHOD_setComposingRegion = CompatUtils + .getMethod(InputConnection.class, "setComposingRegion", int.class, int.class); + public static final boolean RECORRECTION_SUPPORTED; + + static { + RECORRECTION_SUPPORTED = METHOD_getSelectedText != null + && METHOD_setComposingRegion != null; + } + + public static void commitCorrection(InputConnection ic, int offset, CharSequence oldText, + CharSequence newText) { + if (ic == null || CONSTRUCTOR_CorrectionInfo == null + || METHOD_InputConnection_commitCorrection == null) { + return; + } + Object[] args = { offset, oldText, newText }; + try { + Object correctionInfo = CONSTRUCTOR_CorrectionInfo.newInstance(args); + CompatUtils.invoke(ic, null, METHOD_InputConnection_commitCorrection, + correctionInfo); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Error in commitCorrection: IllegalArgumentException"); + } catch (InstantiationException e) { + Log.e(TAG, "Error in commitCorrection: InstantiationException"); + } catch (IllegalAccessException e) { + Log.e(TAG, "Error in commitCorrection: IllegalAccessException"); + } catch (InvocationTargetException e) { + Log.e(TAG, "Error in commitCorrection: InvocationTargetException"); + } + } + + + /** + * Returns the selected text between the selStart and selEnd positions. + */ + public static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) { + // Use reflection, for backward compatibility + return (CharSequence) CompatUtils.invoke( + ic, null, METHOD_getSelectedText, 0); + } + + /** + * Tries to set the text into composition mode if there is support for it in the framework. + */ + public static void underlineWord(InputConnection ic, SelectedWord word) { + // Use reflection, for backward compatibility + // If method not found, there's nothing we can do. It still works but just wont underline + // the word. + CompatUtils.invoke( + ic, null, METHOD_setComposingRegion, word.mStart, word.mEnd); + } +} diff --git a/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java new file mode 100644 index 000000000..8e22bbc79 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java @@ -0,0 +1,59 @@ +/* + * 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.compat; + +import android.content.pm.ServiceInfo; +import android.view.inputmethod.InputMethodInfo; + +import java.lang.reflect.Method; + +public class InputMethodInfoCompatWrapper { + private final InputMethodInfo mImi; + private static final Method METHOD_getSubtypeAt = CompatUtils.getMethod( + InputMethodInfo.class, "getSubtypeAt", int.class); + private static final Method METHOD_getSubtypeCount = CompatUtils.getMethod( + InputMethodInfo.class, "getSubtypeCount"); + + public InputMethodInfoCompatWrapper(InputMethodInfo imi) { + mImi = imi; + } + + public InputMethodInfo getInputMethodInfo() { + return mImi; + } + + public String getId() { + return mImi.getId(); + } + + public String getPackageName() { + return mImi.getPackageName(); + } + + public ServiceInfo getServiceInfo() { + return mImi.getServiceInfo(); + } + + public int getSubtypeCount() { + return (Integer) CompatUtils.invoke(mImi, 0, METHOD_getSubtypeCount); + } + + public InputMethodSubtypeCompatWrapper getSubtypeAt(int index) { + return new InputMethodSubtypeCompatWrapper(CompatUtils.invoke(mImi, null, + METHOD_getSubtypeAt, index)); + } +} diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java new file mode 100644 index 000000000..1cc13f249 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -0,0 +1,227 @@ +/* + * 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.compat; + +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.Utils; + +import android.content.Context; +import android.os.IBinder; +import android.text.TextUtils; +import android.util.Log; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +// TODO: Override this class with the concrete implementation if we need to take care of the +// performance. +public class InputMethodManagerCompatWrapper { + private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName(); + private static final Method METHOD_getCurrentInputMethodSubtype = + CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype"); + private static final Method METHOD_getEnabledInputMethodSubtypeList = + CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList", + InputMethodInfo.class, boolean.class); + private static final Method METHOD_getShortcutInputMethodsAndSubtypes = + CompatUtils.getMethod(InputMethodManager.class, "getShortcutInputMethodsAndSubtypes"); + private static final Method METHOD_setInputMethodAndSubtype = + CompatUtils.getMethod( + InputMethodManager.class, "setInputMethodAndSubtype", IBinder.class, + String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype); + private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod( + InputMethodManager.class, "switchToLastInputMethod", IBinder.class); + + private static final InputMethodManagerCompatWrapper sInstance = + new InputMethodManagerCompatWrapper(); + + public static final boolean SUBTYPE_SUPPORTED; + + static { + // This static initializer guarantees that METHOD_getShortcutInputMethodsAndSubtypes is + // already instantiated. + SUBTYPE_SUPPORTED = METHOD_getShortcutInputMethodsAndSubtypes != null; + } + + // For the compatibility, IMM will create dummy subtypes if subtypes are not found. + // This is required to be false if the current behavior is broken. For now, it's ok to be true. + public static final boolean FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES = + !InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED; + private static final String VOICE_MODE = "voice"; + private static final String KEYBOARD_MODE = "keyboard"; + + private InputMethodManager mImm; + private LanguageSwitcherProxy mLanguageSwitcherProxy; + private String mLatinImePackageName; + + private InputMethodManagerCompatWrapper() { + } + + public static InputMethodManagerCompatWrapper getInstance(Context context) { + if (sInstance.mImm == null) { + sInstance.init(context); + } + return sInstance; + } + + private synchronized void init(Context context) { + mImm = (InputMethodManager) context.getSystemService( + Context.INPUT_METHOD_SERVICE); + if (context instanceof LatinIME) { + mLatinImePackageName = context.getPackageName(); + } + mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance(); + } + + public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { + if (!SUBTYPE_SUPPORTED) { + return new InputMethodSubtypeCompatWrapper( + 0, 0, mLanguageSwitcherProxy.getInputLocale().toString(), KEYBOARD_MODE, ""); + } + Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype); + return new InputMethodSubtypeCompatWrapper(o); + } + + public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList( + InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { + if (!SUBTYPE_SUPPORTED) { + String[] languages = mLanguageSwitcherProxy.getEnabledLanguages( + allowsImplicitlySelectedSubtypes); + List<InputMethodSubtypeCompatWrapper> subtypeList = + new ArrayList<InputMethodSubtypeCompatWrapper>(); + for (String lang: languages) { + subtypeList.add(new InputMethodSubtypeCompatWrapper(0, 0, lang, KEYBOARD_MODE, "")); + } + return subtypeList; + } + Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, + (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes); + if (retval == null || !(retval instanceof List<?>) || ((List<?>)retval).isEmpty()) { + if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { + // Returns an empty list + return Collections.emptyList(); + } + // Creates dummy subtypes + @SuppressWarnings("unused") + List<InputMethodSubtypeCompatWrapper> subtypeList = + new ArrayList<InputMethodSubtypeCompatWrapper>(); + InputMethodSubtypeCompatWrapper keyboardSubtype = getLastResortSubtype(KEYBOARD_MODE); + InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); + if (keyboardSubtype != null) { + subtypeList.add(keyboardSubtype); + } + if (voiceSubtype != null) { + subtypeList.add(voiceSubtype); + } + return subtypeList; + } + return CompatUtils.copyInputMethodSubtypeListToWrapper(retval); + } + + private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() { + if (TextUtils.isEmpty(mLatinImePackageName)) + return null; + return Utils.getInputMethodInfo(this, mLatinImePackageName); + } + + @SuppressWarnings("unused") + private InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { + if (VOICE_MODE.equals(mode) && !FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) + return null; + Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale(); + if (inputLocale == null) + return null; + return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, ""); + } + + public Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> + getShortcutInputMethodsAndSubtypes() { + Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes); + if (retval == null || !(retval instanceof Map<?, ?>) || ((Map<?, ?>)retval).isEmpty()) { + if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { + // Returns an empty map + return Collections.emptyMap(); + } + // Creates dummy subtypes + @SuppressWarnings("unused") + InputMethodInfoCompatWrapper imi = getLatinImeInputMethodInfo(); + InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); + if (imi != null && voiceSubtype != null) { + Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> + shortcutMap = + new HashMap<InputMethodInfoCompatWrapper, + List<InputMethodSubtypeCompatWrapper>>(); + List<InputMethodSubtypeCompatWrapper> subtypeList = + new ArrayList<InputMethodSubtypeCompatWrapper>(); + subtypeList.add(voiceSubtype); + shortcutMap.put(imi, subtypeList); + return shortcutMap; + } else { + return Collections.emptyMap(); + } + } + Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcutMap = + new HashMap<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>(); + final Map<?, ?> retvalMap = (Map<?, ?>)retval; + for (Object key : retvalMap.keySet()) { + if (!(key instanceof InputMethodInfo)) { + Log.e(TAG, "Class type error."); + return null; + } + shortcutMap.put(new InputMethodInfoCompatWrapper((InputMethodInfo)key), + CompatUtils.copyInputMethodSubtypeListToWrapper(retvalMap.get(key))); + } + return shortcutMap; + } + + public void setInputMethodAndSubtype( + IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { + if (subtype != null && subtype.hasOriginalObject()) { + CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, + token, id, subtype.getOriginalObject()); + } + } + + public boolean switchToLastInputMethod(IBinder token) { + if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) { + return true; + } + return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token); + } + + public List<InputMethodInfoCompatWrapper> getEnabledInputMethodList() { + if (mImm == null) return null; + List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>(); + for (InputMethodInfo imi : mImm.getEnabledInputMethodList()) { + imis.add(new InputMethodInfoCompatWrapper(imi)); + } + return imis; + } + + public void showInputMethodPicker() { + if (mImm == null) return; + mImm.showInputMethodPicker(); + } +} diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java new file mode 100644 index 000000000..828aea41f --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java @@ -0,0 +1,84 @@ +/* + * 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.compat; + +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; +import com.android.inputmethod.latin.SubtypeSwitcher; + +import android.inputmethodservice.InputMethodService; +import android.view.inputmethod.InputMethodSubtype; + +public class InputMethodServiceCompatWrapper extends InputMethodService { + // CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10 + // or previous. Note that InputMethodSubtype was added in the API level 11. + // For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged(). + // For the API level 10 or previous, we handle the "subtype changed" events by ourselves + // without having support from framework -- onCurrentInputMethodSubtypeChanged(). + public static final boolean CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED = true; + + private InputMethodManagerCompatWrapper mImm; + + @Override + public void onCreate() { + super.onCreate(); + mImm = InputMethodManagerCompatWrapper.getInstance(this); + } + + // When the API level is 10 or previous, notifyOnCurrentInputMethodSubtypeChanged should + // handle the event the current subtype was changed. LatinIME calls + // notifyOnCurrentInputMethodSubtypeChanged every time LatinIME + // changes the current subtype. + // This call is required to let LatinIME itself know a subtype changed + // event when the API level is 10 or previous. + @SuppressWarnings("unused") + public void notifyOnCurrentInputMethodSubtypeChanged(InputMethodSubtypeCompatWrapper subtype) { + // Do nothing when the API level is 11 or later + // and FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES is not true + if (CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED && !InputMethodManagerCompatWrapper. + FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { + return; + } + if (subtype == null) { + subtype = mImm.getCurrentInputMethodSubtype(); + } + if (subtype != null) { + if (!InputMethodManagerCompatWrapper.FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES + && !subtype.isDummy()) return; + if (!InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) { + LanguageSwitcherProxy.getInstance().setLocale(subtype.getLocale()); + } + SubtypeSwitcher.getInstance().updateSubtype(subtype); + } + } + + ////////////////////////////////////// + // Functions using API v11 or later // + ////////////////////////////////////// + @Override + public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { + // Do nothing when the API level is 10 or previous + if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) return; + SubtypeSwitcher.getInstance().updateSubtype( + new InputMethodSubtypeCompatWrapper(subtype)); + } + + protected static void setTouchableRegionCompat(InputMethodService.Insets outInsets, + int x, int y, int width, int height) { + outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; + outInsets.touchableRegion.set(x, y, width, height); + } +} diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java new file mode 100644 index 000000000..806c355a9 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java @@ -0,0 +1,155 @@ +/* + * 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.compat; + +import com.android.inputmethod.latin.LatinImeLogger; + +import android.text.TextUtils; +import android.util.Log; + +import java.lang.reflect.Method; +import java.util.Arrays; + +// TODO: Override this class with the concrete implementation if we need to take care of the +// performance. +public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper { + private static final boolean DBG = LatinImeLogger.sDBG; + private static final String TAG = InputMethodSubtypeCompatWrapper.class.getSimpleName(); + private static final String DEFAULT_LOCALE = "en_US"; + private static final String DEFAULT_MODE = "keyboard"; + + public static final Class<?> CLASS_InputMethodSubtype = + CompatUtils.getClass("android.view.inputmethod.InputMethodSubtype"); + private static final Method METHOD_getNameResId = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "getNameResId"); + private static final Method METHOD_getIconResId = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "getIconResId"); + private static final Method METHOD_getLocale = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "getLocale"); + private static final Method METHOD_getMode = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "getMode"); + private static final Method METHOD_getExtraValue = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValue"); + private static final Method METHOD_containsExtraValueKey = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "containsExtraValueKey", String.class); + private static final Method METHOD_getExtraValueOf = + CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class); + + private final int mDummyNameResId; + private final int mDummyIconResId; + private final String mDummyLocale; + private final String mDummyMode; + private final String mDummyExtraValues; + + public InputMethodSubtypeCompatWrapper(Object subtype) { + super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype)) + ? subtype : null); + mDummyNameResId = 0; + mDummyIconResId = 0; + mDummyLocale = DEFAULT_LOCALE; + mDummyMode = DEFAULT_MODE; + mDummyExtraValues = ""; + } + + // Constructor for creating a dummy subtype. + public InputMethodSubtypeCompatWrapper(int nameResId, int iconResId, String locale, + String mode, String extraValues) { + super(null); + if (DBG) { + Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper"); + } + mDummyNameResId = nameResId; + mDummyIconResId = iconResId; + mDummyLocale = locale != null ? locale : ""; + mDummyMode = mode != null ? mode : ""; + mDummyExtraValues = extraValues != null ? extraValues : ""; + } + + public int getNameResId() { + if (mObj == null) return mDummyNameResId; + return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getNameResId); + } + + public int getIconResId() { + if (mObj == null) return mDummyIconResId; + return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getIconResId); + } + + public String getLocale() { + if (mObj == null) return mDummyLocale; + final String s = (String)CompatUtils.invoke(mObj, null, METHOD_getLocale); + if (TextUtils.isEmpty(s)) return DEFAULT_LOCALE; + return s; + } + + public String getMode() { + if (mObj == null) return mDummyMode; + String s = (String)CompatUtils.invoke(mObj, null, METHOD_getMode); + if (TextUtils.isEmpty(s)) return DEFAULT_MODE; + return s; + } + + public String getExtraValue() { + if (mObj == null) return mDummyExtraValues; + return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValue); + } + + public boolean containsExtraValueKey(String key) { + return (Boolean)CompatUtils.invoke(mObj, false, METHOD_containsExtraValueKey, key); + } + + public String getExtraValueOf(String key) { + return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValueOf, key); + } + + public boolean isDummy() { + return !hasOriginalObject(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof InputMethodSubtypeCompatWrapper) { + InputMethodSubtypeCompatWrapper subtype = (InputMethodSubtypeCompatWrapper)o; + if (mObj == null) { + // easy check of dummy subtypes + return (mDummyNameResId == subtype.mDummyNameResId + && mDummyIconResId == subtype.mDummyIconResId + && mDummyLocale.equals(subtype.mDummyLocale) + && mDummyMode.equals(subtype.mDummyMode) + && mDummyExtraValues.equals(subtype.mDummyExtraValues)); + } + return mObj.equals(subtype.getOriginalObject()); + } else { + return mObj.equals(o); + } + } + + @Override + public int hashCode() { + if (mObj == null) { + return hashCodeInternal(mDummyNameResId, mDummyIconResId, mDummyLocale, + mDummyMode, mDummyExtraValues); + } + return mObj.hashCode(); + } + + private static int hashCodeInternal(int nameResId, int iconResId, String locale, + String mode, String extraValue) { + return Arrays + .hashCode(new Object[] { nameResId, iconResId, locale, mode, extraValue }); + } +} diff --git a/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java new file mode 100644 index 000000000..d85174188 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java @@ -0,0 +1,95 @@ +/* + * 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.compat; + +import android.text.InputType; + +import java.lang.reflect.Field; + +public class InputTypeCompatUtils { + private static final Field FIELD_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS = + CompatUtils.getField(InputType.class, "TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS"); + private static final Field FIELD_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD = CompatUtils + .getField(InputType.class, "TYPE_TEXT_VARIATION_WEB_PASSWORD"); + private static final Field FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD = CompatUtils + .getField(InputType.class, "TYPE_NUMBER_VARIATION_PASSWORD"); + private static final Integer OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS = + (Integer) CompatUtils.getFieldValue(null, null, + FIELD_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS); + private static final Integer OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD = + (Integer) CompatUtils.getFieldValue(null, null, + FIELD_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD); + private static final Integer OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD = + (Integer) CompatUtils.getFieldValue(null, null, + FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD); + private static final int WEB_TEXT_PASSWORD_INPUT_TYPE; + private static final int NUMBER_PASSWORD_INPUT_TYPE; + private static final int TEXT_PASSWORD_INPUT_TYPE = + InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD; + private static final int TEXT_VISIBLE_PASSWORD_INPUT_TYPE = + InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; + + static { + WEB_TEXT_PASSWORD_INPUT_TYPE = + OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD != null + ? InputType.TYPE_CLASS_TEXT | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD + : 0; + NUMBER_PASSWORD_INPUT_TYPE = + OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD != null + ? InputType.TYPE_CLASS_NUMBER | OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD + : 0; + } + + private static boolean isWebPasswordInputType(int inputType) { + return WEB_TEXT_PASSWORD_INPUT_TYPE != 0 + && inputType == WEB_TEXT_PASSWORD_INPUT_TYPE; + } + + private static boolean isNumberPasswordInputType(int inputType) { + return NUMBER_PASSWORD_INPUT_TYPE != 0 + && inputType == NUMBER_PASSWORD_INPUT_TYPE; + } + + private static boolean isTextPasswordInputType(int inputType) { + return inputType == TEXT_PASSWORD_INPUT_TYPE; + } + + private static boolean isWebEmailAddressVariation(int variation) { + return OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != null + && variation == OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; + } + + public static boolean isEmailVariation(int variation) { + return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + || isWebEmailAddressVariation(variation); + } + + // Please refer to TextView.isPasswordInputType + public static boolean isPasswordInputType(int inputType) { + final int maskedInputType = + inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); + return isTextPasswordInputType(maskedInputType) || isWebPasswordInputType(maskedInputType) + || isNumberPasswordInputType(maskedInputType); + } + + // Please refer to TextView.isVisiblePasswordInputType + public static boolean isVisiblePasswordInputType(int inputType) { + final int maskedInputType = + inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); + return maskedInputType == TEXT_VISIBLE_PASSWORD_INPUT_TYPE; + } +} diff --git a/java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java b/java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java new file mode 100644 index 000000000..8e2a2e0b8 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java @@ -0,0 +1,47 @@ +/* + * 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.compat; + +import android.content.Context; +import android.os.Vibrator; + +import java.lang.reflect.Method; + +public class VibratorCompatWrapper { + private static final Method METHOD_hasVibrator = CompatUtils.getMethod(Vibrator.class, + "hasVibrator", int.class); + + private static final VibratorCompatWrapper sInstance = new VibratorCompatWrapper(); + private Vibrator mVibrator; + + private VibratorCompatWrapper() { + } + + public static VibratorCompatWrapper getInstance(Context context) { + if (sInstance.mVibrator == null) { + sInstance.mVibrator = + (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + } + return sInstance; + } + + public boolean hasVibrator() { + if (mVibrator == null) + return false; + return (Boolean) CompatUtils.invoke(mVibrator, true, METHOD_hasVibrator); + } +} diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java new file mode 100644 index 000000000..290e6b554 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java @@ -0,0 +1,90 @@ +/* + * 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.deprecated; + +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.Settings; + +import android.content.SharedPreferences; +import android.content.res.Configuration; + +import java.util.Locale; + +// This class is used only when the IME doesn't use method.xml for language switching. +public class LanguageSwitcherProxy implements SharedPreferences.OnSharedPreferenceChangeListener { + private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy(); + private LatinIME mService; + private LanguageSwitcher mLanguageSwitcher; + private SharedPreferences mPrefs; + + public static LanguageSwitcherProxy getInstance() { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return null; + return sInstance; + } + + public static void init(LatinIME service, SharedPreferences prefs) { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + final Configuration conf = service.getResources().getConfiguration(); + sInstance.mLanguageSwitcher = new LanguageSwitcher(service); + sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale); + sInstance.mPrefs = prefs; + sInstance.mService = service; + prefs.registerOnSharedPreferenceChangeListener(sInstance); + } + + public static void onConfigurationChanged(Configuration conf) { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + sInstance.mLanguageSwitcher.onConfigurationChanged(conf, sInstance.mPrefs); + } + + public static void loadSettings() { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + sInstance.mLanguageSwitcher.loadLocales(sInstance.mPrefs, null); + } + + public int getLocaleCount() { + return mLanguageSwitcher.getLocaleCount(); + } + + public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) { + return mLanguageSwitcher.getEnabledLanguages(allowImplicitlySelectedLanguages); + } + + public Locale getInputLocale() { + return mLanguageSwitcher.getInputLocale(); + } + + public void setLocale(String localeStr) { + mLanguageSwitcher.setLocale(localeStr); + mLanguageSwitcher.persist(mPrefs); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + // PREF_SELECTED_LANGUAGES: enabled input subtypes + // PREF_INPUT_LANGUAGE: current input subtype + if (key.equals(Settings.PREF_SELECTED_LANGUAGES) + || key.equals(Settings.PREF_INPUT_LANGUAGE)) { + mLanguageSwitcher.loadLocales(prefs, null); + if (mService != null) { + mService.onRefreshKeyboard(); + } + } + } +} diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index a244c9e41..85993ea4d 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java @@ -14,8 +14,14 @@ * the License. */ -package com.android.inputmethod.voice; - +package com.android.inputmethod.deprecated; + +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.deprecated.voice.FieldContext; +import com.android.inputmethod.deprecated.voice.Hints; +import com.android.inputmethod.deprecated.voice.SettingsUtil; +import com.android.inputmethod.deprecated.voice.VoiceInput; +import com.android.inputmethod.deprecated.voice.VoiceInputLogger; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.EditingUtils; import com.android.inputmethod.latin.LatinIME; @@ -28,6 +34,7 @@ import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.Utils; import android.app.AlertDialog; +import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -54,7 +61,6 @@ import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; import android.widget.TextView; import java.util.ArrayList; @@ -62,8 +68,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class VoiceIMEConnector implements VoiceInput.UiListener { - private static final VoiceIMEConnector sInstance = new VoiceIMEConnector(); +public class VoiceProxy implements VoiceInput.UiListener { + private static final VoiceProxy sInstance = new VoiceProxy(); public static final boolean VOICE_INSTALLED = true; private static final boolean ENABLE_VOICE_BUTTON = true; @@ -76,8 +82,10 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE = "has_used_voice_input_unsupported_locale"; private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6; + // TODO: Adjusted on phones for now + private static final int RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP = 244; - private static final String TAG = VoiceIMEConnector.class.getSimpleName(); + private static final String TAG = VoiceProxy.class.getSimpleName(); private static final boolean DEBUG = LatinImeLogger.sDBG; private boolean mAfterVoiceInput; @@ -93,7 +101,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private boolean mVoiceButtonOnPrimary; private boolean mVoiceInputHighlighted; - private InputMethodManager mImm; + private int mMinimumVoiceRecognitionViewHeightPixel; + private InputMethodManagerCompatWrapper mImm; private LatinIME mService; private AlertDialog mVoiceWarningDialog; private VoiceInput mVoiceInput; @@ -101,23 +110,26 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private Hints mHints; private UIHandler mHandler; private SubtypeSwitcher mSubtypeSwitcher; + // For each word, a list of potential replacements, usually from voice. private final Map<String, List<CharSequence>> mWordToSuggestions = new HashMap<String, List<CharSequence>>(); - public static VoiceIMEConnector init(LatinIME context, SharedPreferences prefs, UIHandler h) { + public static VoiceProxy init(LatinIME context, SharedPreferences prefs, UIHandler h) { sInstance.initInternal(context, prefs, h); return sInstance; } - public static VoiceIMEConnector getInstance() { + public static VoiceProxy getInstance() { return sInstance; } private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) { mService = service; mHandler = h; - mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE); + mMinimumVoiceRecognitionViewHeightPixel = Utils.dipToPixel( + Utils.getDipScale(service), RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP); + mImm = InputMethodManagerCompatWrapper.getInstance(service); mSubtypeSwitcher = SubtypeSwitcher.getInstance(); if (VOICE_INSTALLED) { mVoiceInput = new VoiceInput(service, this); @@ -125,15 +137,15 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { @Override public void showHint(int viewResource) { View view = LayoutInflater.from(mService).inflate(viewResource, null); - mService.setCandidatesView(view); - mService.setCandidatesViewShown(true); +// mService.setCandidatesView(view); +// mService.setCandidatesViewShown(true); mIsShowingHint = true; } }); } } - private VoiceIMEConnector() { + private VoiceProxy() { // Intentional empty constructor for singleton. } @@ -429,7 +441,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } builder.setTypedWordValid(true).setHasMinimalSuggestion(true); mService.setSuggestions(builder.build()); - mService.setCandidatesViewShown(true); +// mService.setCandidatesViewShown(true); return true; } return false; @@ -514,7 +526,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mHandler.post(new Runnable() { @Override public void run() { - mService.setCandidatesViewShown(false); +// mService.setCandidatesViewShown(false); mRecognizing = true; mVoiceInput.newView(); View v = mVoiceInput.getView(); @@ -524,7 +536,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { ((ViewGroup) p).removeView(v); } - View keyboardView = KeyboardSwitcher.getInstance().getInputView(); + View keyboardView = KeyboardSwitcher.getInstance().getKeyboardView(); // The full height of the keyboard is difficult to calculate // as the dimension is expressed in "mm" and not in "pixel" @@ -536,7 +548,11 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mService.getResources().getDisplayMetrics().heightPixels; final int currentHeight = popupLayout.getLayoutParams().height; final int keyboardHeight = keyboardView.getHeight(); - if (keyboardHeight > currentHeight || keyboardHeight + if (mMinimumVoiceRecognitionViewHeightPixel > keyboardHeight + || mMinimumVoiceRecognitionViewHeightPixel > currentHeight) { + popupLayout.getLayoutParams().height = + mMinimumVoiceRecognitionViewHeightPixel; + } else if (keyboardHeight > currentHeight || keyboardHeight > (displayHeight / RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO)) { popupLayout.getLayoutParams().height = keyboardHeight; } @@ -560,14 +576,24 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { @Override protected void onPostExecute(Boolean result) { + // Calls in this method need to be done in the same thread as the thread which + // called switchToLastInputMethod() if (!result) { if (DEBUG) { Log.d(TAG, "Couldn't switch back to last IME."); } - // Needs to reset here because LatinIME failed to back to any IME and - // the same voice subtype will be triggered in the next time. + // Because the current IME and subtype failed to switch to any other IME and + // subtype by switchToLastInputMethod, the current IME and subtype should keep + // being LatinIME and voice subtype in the next time. And for re-showing voice + // mode, the state of voice input should be reset and the voice view should be + // hidden. mVoiceInput.reset(); mService.requestHideSelf(0); + } else { + // Notify an event that the current subtype was changed. This event will be + // handled if "onCurrentInputMethodSubtypeChanged" can't be implemented + // when the API level is 10 or previous. + mService.notifyOnCurrentInputMethodSubtypeChanged(null); } } }.execute(); @@ -624,6 +650,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) { + @SuppressWarnings("deprecation") final boolean noMic = Utils.inPrivateImeOptions(null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, attribute) || Utils.inPrivateImeOptions(mService.getPackageName(), @@ -664,7 +691,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) { // Close keyboard view if it is been shown. if (KeyboardSwitcher.getInstance().isInputViewShown()) - KeyboardSwitcher.getInstance().getInputView().purgeKeyboardAndClosing(); + KeyboardSwitcher.getInstance().getKeyboardView().purgeKeyboardAndClosing(); startListening(false, windowToken); } // If we have no token, onAttachedToWindow will take care of showing dialog and start @@ -674,7 +701,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { public void onAttachedToWindow() { // After onAttachedToWindow, we can show the voice warning dialog. See startListening() // above. - mSubtypeSwitcher.setVoiceInput(mVoiceInput); + VoiceInputWrapper.getInstance().setVoiceInput(mVoiceInput, mSubtypeSwitcher); } public void onConfigurationChanged(Configuration configuration) { @@ -725,4 +752,91 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { List<String> candidates; Map<String, List<CharSequence>> alternatives; } + + public static class VoiceLoggerWrapper { + private static final VoiceLoggerWrapper sLoggerWrapperInstance = new VoiceLoggerWrapper(); + private VoiceInputLogger mLogger; + + public static VoiceLoggerWrapper getInstance(Context context) { + if (sLoggerWrapperInstance.mLogger == null) { + // Not thread safe, but it's ok. + sLoggerWrapperInstance.mLogger = VoiceInputLogger.getLogger(context); + } + return sLoggerWrapperInstance; + } + + // private for the singleton + private VoiceLoggerWrapper() { + } + + public void settingsWarningDialogCancel() { + mLogger.settingsWarningDialogCancel(); + } + + public void settingsWarningDialogOk() { + mLogger.settingsWarningDialogOk(); + } + + public void settingsWarningDialogShown() { + mLogger.settingsWarningDialogShown(); + } + + public void settingsWarningDialogDismissed() { + mLogger.settingsWarningDialogDismissed(); + } + + public void voiceInputSettingEnabled(boolean enabled) { + if (enabled) { + mLogger.voiceInputSettingEnabled(); + } else { + mLogger.voiceInputSettingDisabled(); + } + } + } + + public static class VoiceInputWrapper { + private static final VoiceInputWrapper sInputWrapperInstance = new VoiceInputWrapper(); + private VoiceInput mVoiceInput; + public static VoiceInputWrapper getInstance() { + return sInputWrapperInstance; + } + public void setVoiceInput(VoiceInput voiceInput, SubtypeSwitcher switcher) { + if (mVoiceInput == null && voiceInput != null) { + mVoiceInput = voiceInput; + } + switcher.setVoiceInputWrapper(this); + } + + private VoiceInputWrapper() { + } + + public void cancel() { + if (mVoiceInput != null) mVoiceInput.cancel(); + } + + public void reset() { + if (mVoiceInput != null) mVoiceInput.reset(); + } + } + + // A list of locales which are supported by default for voice input, unless we get a + // different list from Gservices. + private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = + "en " + + "en_US " + + "en_GB " + + "en_AU " + + "en_CA " + + "en_IE " + + "en_IN " + + "en_NZ " + + "en_SG " + + "en_ZA "; + + public static String getSupportedLocalesString (ContentResolver resolver) { + return SettingsUtil.getSettingsString( + resolver, + SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, + DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); + } } diff --git a/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java b/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java new file mode 100644 index 000000000..488390fbc --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java @@ -0,0 +1,36 @@ +/* + * 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.deprecated.compat; + +import com.android.common.userhappiness.UserHappinessSignals; +import com.android.inputmethod.compat.CompatUtils; + +import java.lang.reflect.Method; + +public class VoiceInputLoggerCompatUtils { + public static final String EXTRA_TEXT_REPLACED_LENGTH = "length"; + public static final String EXTRA_BEFORE_N_BEST_CHOOSE = "before"; + public static final String EXTRA_AFTER_N_BEST_CHOOSE = "after"; + private static final Method METHOD_UserHappinessSignals_setHasVoiceLoggingInfo = + CompatUtils.getMethod(UserHappinessSignals.class, "setHasVoiceLoggingInfo", + boolean.class); + + public static void setHasVoiceLoggingInfoCompat(boolean hasLoggingInfo) { + CompatUtils.invoke(null, null, METHOD_UserHappinessSignals_setHasVoiceLoggingInfo, + hasLoggingInfo); + } +} diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java new file mode 100644 index 000000000..fe70eef96 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2008-2009 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.deprecated.languageswitcher; + +import com.android.inputmethod.keyboard.KeyboardParser; +import com.android.inputmethod.latin.DictionaryFactory; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SharedPreferencesCompat; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.Utils; + +import org.xmlpull.v1.XmlPullParserException; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.res.Resources; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceGroup; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.util.Pair; + +import java.io.IOException; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map.Entry; +import java.util.TreeMap; + +public class InputLanguageSelection extends PreferenceActivity { + + private SharedPreferences mPrefs; + private String mSelectedLanguages; + private HashMap<CheckBoxPreference, Locale> mLocaleMap = + new HashMap<CheckBoxPreference, Locale>(); + + private static class LocaleEntry implements Comparable<Object> { + private static Collator sCollator = Collator.getInstance(); + + private String mLabel; + public final Locale mLocale; + + public LocaleEntry(String label, Locale locale) { + this.mLabel = label; + this.mLocale = locale; + } + + @Override + public String toString() { + return this.mLabel; + } + + @Override + public int compareTo(Object o) { + return sCollator.compare(this.mLabel, ((LocaleEntry) o).mLabel); + } + } + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + addPreferencesFromResource(R.xml.language_prefs); + // Get the settings preferences + mPrefs = PreferenceManager.getDefaultSharedPreferences(this); + mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, ""); + String[] languageList = mSelectedLanguages.split(","); + ArrayList<LocaleEntry> availableLanguages = getUniqueLocales(); + PreferenceGroup parent = getPreferenceScreen(); + final HashMap<Long, LocaleEntry> dictionaryIdLocaleMap = new HashMap<Long, LocaleEntry>(); + final TreeMap<LocaleEntry, Boolean> localeHasDictionaryMap = + new TreeMap<LocaleEntry, Boolean>(); + for (int i = 0; i < availableLanguages.size(); i++) { + LocaleEntry loc = availableLanguages.get(i); + Locale locale = loc.mLocale; + final Pair<Long, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale); + final Long dictionaryId = hasDictionaryOrLayout.first; + final boolean hasLayout = hasDictionaryOrLayout.second; + final boolean hasDictionary = dictionaryId != null; + // Add this locale to the supported list if: + // 1) this locale has a layout/ 2) this locale has a dictionary + // If some locales have no layout but have a same dictionary, the shortest locale + // will be added to the supported list. + if (!hasLayout && !hasDictionary) { + continue; + } + if (hasLayout) { + localeHasDictionaryMap.put(loc, hasDictionary); + } + if (!hasDictionary) { + continue; + } + if (dictionaryIdLocaleMap.containsKey(dictionaryId)) { + final String newLocale = locale.toString(); + final String oldLocale = + dictionaryIdLocaleMap.get(dictionaryId).mLocale.toString(); + // Check if this locale is more appropriate to be the candidate of the input locale. + if (oldLocale.length() <= newLocale.length() && !hasLayout) { + // Don't add this new locale to the map<dictionary id, locale> if: + // 1) the new locale's name is longer than the existing one, and + // 2) the new locale doesn't have its layout + continue; + } + } + dictionaryIdLocaleMap.put(dictionaryId, loc); + } + + for (LocaleEntry localeEntry : dictionaryIdLocaleMap.values()) { + if (!localeHasDictionaryMap.containsKey(localeEntry)) { + localeHasDictionaryMap.put(localeEntry, true); + } + } + + for (Entry<LocaleEntry, Boolean> entry : localeHasDictionaryMap.entrySet()) { + final LocaleEntry localeEntry = entry.getKey(); + final Locale locale = localeEntry.mLocale; + final Boolean hasDictionary = entry.getValue(); + CheckBoxPreference pref = new CheckBoxPreference(this); + pref.setTitle(localeEntry.mLabel); + boolean checked = isLocaleIn(locale, languageList); + pref.setChecked(checked); + if (hasDictionary) { + pref.setSummary(R.string.has_dictionary); + } + mLocaleMap.put(pref, locale); + parent.addPreference(pref); + } + } + + private boolean isLocaleIn(Locale locale, String[] list) { + String lang = get5Code(locale); + for (int i = 0; i < list.length; i++) { + if (lang.equalsIgnoreCase(list[i])) return true; + } + return false; + } + + private Pair<Long, Boolean> hasDictionaryOrLayout(Locale locale) { + if (locale == null) return new Pair<Long, Boolean>(null, false); + final Resources res = getResources(); + final Locale saveLocale = Utils.setSystemLocale(res, locale); + final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale); + boolean hasLayout = false; + + try { + final String localeStr = locale.toString(); + final String[] layoutCountryCodes = KeyboardParser.parseKeyboardLocale( + this, R.xml.kbd_qwerty).split(",", -1); + if (!TextUtils.isEmpty(localeStr) && layoutCountryCodes.length > 0) { + for (String s : layoutCountryCodes) { + if (s.equals(localeStr)) { + hasLayout = true; + break; + } + } + } + } catch (XmlPullParserException e) { + } catch (IOException e) { + } + Utils.setSystemLocale(res, saveLocale); + return new Pair<Long, Boolean>(dictionaryId, hasLayout); + } + + private String get5Code(Locale locale) { + String country = locale.getCountry(); + return locale.getLanguage() + + (TextUtils.isEmpty(country) ? "" : "_" + country); + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + // Save the selected languages + String checkedLanguages = ""; + PreferenceGroup parent = getPreferenceScreen(); + int count = parent.getPreferenceCount(); + for (int i = 0; i < count; i++) { + CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); + if (pref.isChecked()) { + checkedLanguages += get5Code(mLocaleMap.get(pref)) + ","; + } + } + if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null + Editor editor = mPrefs.edit(); + editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages); + SharedPreferencesCompat.apply(editor); + } + + public ArrayList<LocaleEntry> getUniqueLocales() { + String[] locales = getAssets().getLocales(); + Arrays.sort(locales); + ArrayList<LocaleEntry> uniqueLocales = new ArrayList<LocaleEntry>(); + + final int origSize = locales.length; + LocaleEntry[] preprocess = new LocaleEntry[origSize]; + int finalSize = 0; + for (int i = 0 ; i < origSize; i++ ) { + String s = locales[i]; + int len = s.length(); + String language = ""; + String country = ""; + if (len == 5) { + language = s.substring(0, 2); + country = s.substring(3, 5); + } else if (len < 5) { + language = s; + } + Locale l = new Locale(language, country); + + // Exclude languages that are not relevant to LatinIME + if (TextUtils.isEmpty(language)) { + continue; + } + + if (finalSize == 0) { + preprocess[finalSize++] = + new LocaleEntry(SubtypeSwitcher.getFullDisplayName(l, false), l); + } else { + if (s.equals("zz_ZZ")) { + // ignore this locale + } else { + final String displayName = SubtypeSwitcher.getFullDisplayName(l, false); + preprocess[finalSize++] = new LocaleEntry(displayName, l); + } + } + } + for (int i = 0; i < finalSize ; i++) { + uniqueLocales.add(preprocess[i]); + } + return uniqueLocales; + } +} diff --git a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java index 2dd3038f9..1eedb5ee1 100644 --- a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java @@ -14,11 +14,19 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.deprecated.languageswitcher; + +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.LatinImeLogger; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SharedPreferencesCompat; +import com.android.inputmethod.latin.Utils; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import android.content.res.Configuration; import android.text.TextUtils; +import android.util.Log; import java.util.ArrayList; import java.util.Locale; @@ -28,10 +36,15 @@ import java.util.Locale; * input language that the user has selected. */ public class LanguageSwitcher { + private static final String TAG = LanguageSwitcher.class.getSimpleName(); + + @SuppressWarnings("unused") + private static final String KEYBOARD_MODE = "keyboard"; + private static final String[] EMPTY_STIRNG_ARRAY = new String[0]; private final ArrayList<Locale> mLocales = new ArrayList<Locale>(); private final LatinIME mIme; - private String[] mSelectedLanguageArray; + private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; private String mSelectedLanguages; private int mCurrentIndex = 0; private String mDefaultInputLanguage; @@ -46,15 +59,32 @@ public class LanguageSwitcher { return mLocales.size(); } + public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) { + final Locale newLocale = conf.locale; + if (!getSystemLocale().toString().equals(newLocale.toString())) { + loadLocales(prefs, newLocale); + } + } + /** * Loads the currently selected input languages from shared preferences. - * @param sp + * @param sp shared preference for getting the current input language and enabled languages + * @param systemLocale the current system locale, stored for changing the current input language + * based on the system current system locale. * @return whether there was any change */ - public boolean loadLocales(SharedPreferences sp) { + public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { + if (LatinImeLogger.sDBG) { + Log.d(TAG, "load locales"); + } + if (systemLocale != null) { + setSystemLocale(systemLocale); + } String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); - if (selectedLanguages == null || selectedLanguages.length() < 1) { + if (TextUtils.isEmpty(selectedLanguages)) { + mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; + mSelectedLanguages = null; loadDefaults(); if (mLocales.size() == 0) { return false; @@ -84,6 +114,9 @@ public class LanguageSwitcher { } private void loadDefaults() { + if (LatinImeLogger.sDBG) { + Log.d(TAG, "load default locales:"); + } mDefaultInputLocale = mIme.getResources().getConfiguration().locale; String country = mDefaultInputLocale.getCountry(); mDefaultInputLanguage = mDefaultInputLocale.getLanguage() + @@ -93,8 +126,7 @@ public class LanguageSwitcher { private void constructLocales() { mLocales.clear(); for (final String lang : mSelectedLanguageArray) { - final Locale locale = new Locale(lang.substring(0, 2), - lang.length() > 4 ? lang.substring(3, 5) : ""); + final Locale locale = Utils.constructLocaleFromString(lang); mLocales.add(locale); } } @@ -112,14 +144,16 @@ public class LanguageSwitcher { /** * Returns the list of enabled language codes. */ - public String[] getEnabledLanguages() { + public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) { + if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) { + return new String[] { mDefaultInputLanguage }; + } return mSelectedLanguageArray; } /** * Returns the currently selected input locale, or the display locale if no specific * locale was selected for input. - * @return */ public Locale getInputLocale() { if (getLocaleCount() == 0) return mDefaultInputLocale; @@ -140,7 +174,6 @@ public class LanguageSwitcher { /** * Returns the next input locale in the list. Wraps around to the beginning of the * list if we're at the end of the list. - * @return */ public Locale getNextInputLocale() { if (getLocaleCount() == 0) return mDefaultInputLocale; @@ -151,7 +184,7 @@ public class LanguageSwitcher { * Sets the system locale (display UI) used for comparing with the input language. * @param locale the locale of the system */ - public void setSystemLocale(Locale locale) { + private void setSystemLocale(Locale locale) { mSystemLocale = locale; } @@ -159,14 +192,13 @@ public class LanguageSwitcher { * Returns the system locale. * @return the system locale */ - public Locale getSystemLocale() { + private Locale getSystemLocale() { return mSystemLocale; } /** * Returns the previous input locale in the list. Wraps around to the end of the * list if we're at the beginning of the list. - * @return */ public Locale getPrevInputLocale() { if (getLocaleCount() == 0) return mDefaultInputLocale; @@ -185,6 +217,15 @@ public class LanguageSwitcher { mCurrentIndex = prevLocaleIndex(); } + public void setLocale(String localeStr) { + final int N = mLocales.size(); + for (int i = 0; i < N; ++i) { + if (mLocales.get(i).toString().equals(localeStr)) { + mCurrentIndex = i; + } + } + } + public void persist(SharedPreferences prefs) { Editor editor = prefs.edit(); editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); diff --git a/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java new file mode 100644 index 000000000..bf69d5ced --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java @@ -0,0 +1,287 @@ +/* + * 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.deprecated.recorrection; + +import com.android.inputmethod.compat.InputConnectionCompatUtils; +import com.android.inputmethod.deprecated.VoiceProxy; +import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.latin.AutoCorrection; +import com.android.inputmethod.latin.CandidateView; +import com.android.inputmethod.latin.EditingUtils; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.Suggest; +import com.android.inputmethod.latin.SuggestedWords; +import com.android.inputmethod.latin.TextEntryState; +import com.android.inputmethod.latin.WordComposer; + +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.text.TextUtils; +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +import java.util.ArrayList; + +/** + * Manager of re-correction functionalities + */ +public class Recorrection implements SharedPreferences.OnSharedPreferenceChangeListener { + public static final boolean USE_LEGACY_RECORRECTION = true; + private static final Recorrection sInstance = new Recorrection(); + + private LatinIME mService; + private boolean mRecorrectionEnabled = false; + private final ArrayList<RecorrectionSuggestionEntries> mRecorrectionSuggestionsList = + new ArrayList<RecorrectionSuggestionEntries>(); + + public static Recorrection getInstance() { + return sInstance; + } + + public static void init(LatinIME context, SharedPreferences prefs) { + if (context == null || prefs == null) { + return; + } + sInstance.initInternal(context, prefs); + } + + private Recorrection() { + } + + public boolean isRecorrectionEnabled() { + return mRecorrectionEnabled; + } + + private void initInternal(LatinIME context, SharedPreferences prefs) { + if (!USE_LEGACY_RECORRECTION) { + mRecorrectionEnabled = false; + return; + } + updateRecorrectionEnabled(context.getResources(), prefs); + mService = context; + prefs.registerOnSharedPreferenceChangeListener(this); + } + + public void checkRecorrectionOnStart() { + if (!USE_LEGACY_RECORRECTION || !mRecorrectionEnabled) return; + + final InputConnection ic = mService.getCurrentInputConnection(); + if (ic == null) return; + // There could be a pending composing span. Clean it up first. + ic.finishComposingText(); + + if (mService.isShowingSuggestionsStrip() && mService.isSuggestionsRequested()) { + // First get the cursor position. This is required by setOldSuggestions(), so that + // it can pass the correct range to setComposingRegion(). At this point, we don't + // have valid values for mLastSelectionStart/End because onUpdateSelection() has + // not been called yet. + ExtractedTextRequest etr = new ExtractedTextRequest(); + etr.token = 0; // anything is fine here + ExtractedText et = ic.getExtractedText(etr, 0); + if (et == null) return; + mService.setLastSelection( + et.startOffset + et.selectionStart, et.startOffset + et.selectionEnd); + + // Then look for possible corrections in a delayed fashion + if (!TextUtils.isEmpty(et.text) && mService.isCursorTouchingWord()) { + mService.mHandler.postUpdateOldSuggestions(); + } + } + } + + public void updateRecorrectionSelection(KeyboardSwitcher keyboardSwitcher, + CandidateView candidateView, int candidatesStart, int candidatesEnd, + int newSelStart, int newSelEnd, int oldSelStart, int lastSelectionStart, + int lastSelectionEnd, boolean hasUncommittedTypedChars) { + if (!USE_LEGACY_RECORRECTION || !mRecorrectionEnabled) return; + if (!mService.isShowingSuggestionsStrip()) return; + if (!keyboardSwitcher.isInputViewShown()) return; + if (!mService.isSuggestionsRequested()) return; + // Don't look for corrections if the keyboard is not visible + // Check if we should go in or out of correction mode. + if ((candidatesStart == candidatesEnd || newSelStart != oldSelStart || TextEntryState + .isRecorrecting()) + && (newSelStart < newSelEnd - 1 || !hasUncommittedTypedChars)) { + if (mService.isCursorTouchingWord() || lastSelectionStart < lastSelectionEnd) { + mService.mHandler.cancelUpdateBigramPredictions(); + mService.mHandler.postUpdateOldSuggestions(); + } else { + abortRecorrection(false); + // If showing the "touch again to save" hint, do not replace it. Else, + // show the bigrams if we are at the end of the text, punctuation + // otherwise. + if (candidateView != null && !candidateView.isShowingAddToDictionaryHint()) { + InputConnection ic = mService.getCurrentInputConnection(); + if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) { + if (!mService.isShowingPunctuationList()) { + mService.setPunctuationSuggestions(); + } + } else { + mService.mHandler.postUpdateBigramPredictions(); + } + } + } + } + } + + public void saveRecorrectionSuggestion(WordComposer word, CharSequence result) { + if (!USE_LEGACY_RECORRECTION || !mRecorrectionEnabled) return; + if (word.size() <= 1) { + return; + } + // Skip if result is null. It happens in some edge case. + if (TextUtils.isEmpty(result)) { + return; + } + + // Make a copy of the CharSequence, since it is/could be a mutable CharSequence + final String resultCopy = result.toString(); + RecorrectionSuggestionEntries entry = new RecorrectionSuggestionEntries( + resultCopy, new WordComposer(word)); + mRecorrectionSuggestionsList.add(entry); + } + + public void clearWordsInHistory() { + mRecorrectionSuggestionsList.clear(); + } + + /** + * Tries to apply any typed alternatives for the word if we have any cached alternatives, + * otherwise tries to find new corrections and completions for the word. + * @param touching The word that the cursor is touching, with position information + * @return true if an alternative was found, false otherwise. + */ + public boolean applyTypedAlternatives(WordComposer word, Suggest suggest, + KeyboardSwitcher keyboardSwitcher, EditingUtils.SelectedWord touching) { + if (!USE_LEGACY_RECORRECTION || !mRecorrectionEnabled) return false; + // If we didn't find a match, search for result in typed word history + WordComposer foundWord = null; + RecorrectionSuggestionEntries alternatives = null; + // Search old suggestions to suggest re-corrected suggestions. + for (RecorrectionSuggestionEntries entry : mRecorrectionSuggestionsList) { + if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) { + foundWord = entry.mWordComposer; + alternatives = entry; + break; + } + } + // If we didn't find a match, at least suggest corrections as re-corrected suggestions. + if (foundWord == null + && (AutoCorrection.isValidWord(suggest.getUnigramDictionaries(), + touching.mWord, true))) { + foundWord = new WordComposer(); + for (int i = 0; i < touching.mWord.length(); i++) { + foundWord.add(touching.mWord.charAt(i), + new int[] { touching.mWord.charAt(i) }, WordComposer.NOT_A_COORDINATE, + WordComposer.NOT_A_COORDINATE); + } + foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0))); + } + // Found a match, show suggestions + if (foundWord != null || alternatives != null) { + if (alternatives == null) { + alternatives = new RecorrectionSuggestionEntries(touching.mWord, foundWord); + } + showRecorrections(suggest, keyboardSwitcher, alternatives); + if (foundWord != null) { + word.init(foundWord); + } else { + word.reset(); + } + return true; + } + return false; + } + + + private void showRecorrections(Suggest suggest, KeyboardSwitcher keyboardSwitcher, + RecorrectionSuggestionEntries entries) { + SuggestedWords.Builder builder = entries.getAlternatives(suggest, keyboardSwitcher); + builder.setTypedWordValid(false).setHasMinimalSuggestion(false); + mService.showSuggestions(builder.build(), entries.getOriginalWord()); + } + + public void setRecorrectionSuggestions(VoiceProxy voiceProxy, CandidateView candidateView, + Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word, + boolean hasUncommittedTypedChars, int lastSelectionStart, int lastSelectionEnd, + String wordSeparators) { + if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) return; + if (!USE_LEGACY_RECORRECTION || !mRecorrectionEnabled) return; + voiceProxy.setShowingVoiceSuggestions(false); + if (candidateView != null && candidateView.isShowingAddToDictionaryHint()) { + return; + } + InputConnection ic = mService.getCurrentInputConnection(); + if (ic == null) return; + if (!hasUncommittedTypedChars) { + // Extract the selected or touching text + EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic, + lastSelectionStart, lastSelectionEnd, wordSeparators); + + if (touching != null && touching.mWord.length() > 1) { + ic.beginBatchEdit(); + + if (applyTypedAlternatives(word, suggest, keyboardSwitcher, touching) + || voiceProxy.applyVoiceAlternatives(touching)) { + TextEntryState.selectedForRecorrection(); + InputConnectionCompatUtils.underlineWord(ic, touching); + } else { + abortRecorrection(true); + } + + ic.endBatchEdit(); + } else { + abortRecorrection(true); + mService.setPunctuationSuggestions(); // Show the punctuation suggestions list + } + } else { + abortRecorrection(true); + } + } + + public void abortRecorrection(boolean force) { + if (!USE_LEGACY_RECORRECTION) return; + if (force || TextEntryState.isRecorrecting()) { + TextEntryState.onAbortRecorrection(); + mService.setCandidatesViewShown(mService.isCandidateStripVisible()); + mService.getCurrentInputConnection().finishComposingText(); + mService.clearSuggestions(); + } + } + + public void updateRecorrectionEnabled(Resources res, SharedPreferences prefs) { + // If the option should not be shown, do not read the re-correction 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.config_default_recorrection_enabled)); + } else { + mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled); + } + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if (!USE_LEGACY_RECORRECTION) return; + if (key.equals(Settings.PREF_RECORRECTION_ENABLED)) { + updateRecorrectionEnabled(mService.getResources(), prefs); + } + } +} diff --git a/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java new file mode 100644 index 000000000..5e6c87044 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java @@ -0,0 +1,62 @@ +/* + * 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.deprecated.recorrection; + +import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.latin.Suggest; +import com.android.inputmethod.latin.SuggestedWords; +import com.android.inputmethod.latin.WordComposer; + +import android.text.TextUtils; + +public class RecorrectionSuggestionEntries { + public final CharSequence mChosenWord; + public final WordComposer mWordComposer; + + public RecorrectionSuggestionEntries(CharSequence chosenWord, WordComposer wordComposer) { + mChosenWord = chosenWord; + mWordComposer = wordComposer; + } + + public CharSequence getChosenWord() { + return mChosenWord; + } + + public CharSequence getOriginalWord() { + return mWordComposer.getTypedWord(); + } + + public SuggestedWords.Builder getAlternatives( + Suggest suggest, KeyboardSwitcher keyboardSwitcher) { + return getTypedSuggestions(suggest, keyboardSwitcher, mWordComposer); + } + + @Override + public int hashCode() { + return mChosenWord.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o instanceof CharSequence && TextUtils.equals(mChosenWord, (CharSequence)o); + } + + private static SuggestedWords.Builder getTypedSuggestions( + Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word) { + return suggest.getSuggestedWordBuilder(keyboardSwitcher.getKeyboardView(), word, null); + } +} diff --git a/java/src/com/android/inputmethod/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java index 95c7f5be0..3c79cc218 100644 --- a/java/src/com/android/inputmethod/voice/FieldContext.java +++ b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import android.os.Bundle; import android.util.Log; diff --git a/java/src/com/android/inputmethod/voice/Hints.java b/java/src/com/android/inputmethod/deprecated/voice/Hints.java index f5689092f..06b234381 100644 --- a/java/src/com/android/inputmethod/voice/Hints.java +++ b/java/src/com/android/inputmethod/deprecated/voice/Hints.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SharedPreferencesCompat; diff --git a/java/src/com/android/inputmethod/voice/RecognitionView.java b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java index d26a877d5..dcb826e8f 100644 --- a/java/src/com/android/inputmethod/voice/RecognitionView.java +++ b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; @@ -50,7 +50,6 @@ import java.util.Locale; * plays beeps, shows errors, etc. */ public class RecognitionView { - @SuppressWarnings("unused") private static final String TAG = "RecognitionView"; private Handler mUiHandler; // Reference to UI thread diff --git a/java/src/com/android/inputmethod/voice/SettingsUtil.java b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java index 372e8d6da..855a09a1d 100644 --- a/java/src/com/android/inputmethod/voice/SettingsUtil.java +++ b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import android.content.ContentResolver; import android.provider.Settings; diff --git a/java/src/com/android/inputmethod/voice/SoundIndicator.java b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java index 40b68996a..25b314085 100644 --- a/java/src/com/android/inputmethod/voice/SoundIndicator.java +++ b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import android.content.Context; import android.graphics.Bitmap; diff --git a/java/src/com/android/inputmethod/voice/VoiceInput.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java index 392eea364..92cc1c3b9 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInput.java +++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import com.android.inputmethod.latin.EditingUtils; import com.android.inputmethod.latin.LatinImeLogger; @@ -192,7 +192,7 @@ public class VoiceInput implements OnClickListener { } mBlacklist = new Whitelist(); - mBlacklist.addApp("com.android.setupwizard"); + mBlacklist.addApp("com.google.android.setupwizard"); } public void setCursorPos(int pos) { diff --git a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java index 07f2bd1c5..22e8207bf 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java +++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java @@ -14,10 +14,10 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import com.android.common.speech.LoggingEvents; -import com.android.common.userhappiness.UserHappinessSignals; +import com.android.inputmethod.deprecated.compat.VoiceInputLoggerCompatUtils; import android.content.Context; import android.content.Intent; @@ -212,13 +212,12 @@ public class VoiceInputLogger { setHasLoggingInfo(true); Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, suggestionLength); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_REPLACED_LENGTH, replacedPhraseLength); + i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_TEXT_REPLACED_LENGTH, replacedPhraseLength); i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_CHOOSE_SUGGESTION); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_N_BEST_CHOOSE_INDEX, index); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_BEFORE_N_BEST_CHOOSE, before); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_AFTER_N_BEST_CHOOSE, after); + i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_BEFORE_N_BEST_CHOOSE, before); + i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_AFTER_N_BEST_CHOOSE, after); mContext.sendBroadcast(i); } @@ -257,7 +256,7 @@ public class VoiceInputLogger { // 2. type subject in subject field // 3. speak message in message field // 4. press send - UserHappinessSignals.setHasVoiceLoggingInfo(hasLoggingInfo); + VoiceInputLoggerCompatUtils.setHasVoiceLoggingInfoCompat(hasLoggingInfo); } private boolean hasLoggingInfo(){ diff --git a/java/src/com/android/inputmethod/voice/WaveformImage.java b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java index b0ea99b79..8ed279f42 100644 --- a/java/src/com/android/inputmethod/voice/WaveformImage.java +++ b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import android.graphics.Bitmap; import android.graphics.Canvas; diff --git a/java/src/com/android/inputmethod/voice/Whitelist.java b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java index adbd59135..6c5f52ae2 100644 --- a/java/src/com/android/inputmethod/voice/Whitelist.java +++ b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java @@ -14,7 +14,7 @@ * the License. */ -package com.android.inputmethod.voice; +package com.android.inputmethod.deprecated.voice; import android.os.Bundle; diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index 8eadf4ba4..ef86d66ad 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -61,8 +61,11 @@ public class Key { public final int mWidth; /** Height of the key, not including the gap */ public final int mHeight; - /** The horizontal gap before this key */ + /** The horizontal gap around this key */ public final int mGap; + /** The visual insets */ + public final int mVisualInsetsLeft; + public final int mVisualInsetsRight; /** Whether this key is sticky, i.e., a toggle key */ public final boolean mSticky; /** X coordinate of the key in the keyboard layout */ @@ -83,8 +86,8 @@ public class Key { * {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}. */ public final int mEdgeFlags; - /** Whether this is a modifier key, such as Shift or Alt */ - public final boolean mModifier; + /** Whether this is a functional key which has different key top than normal key */ + public final boolean mFunctional; /** Whether this key repeats itself when held down */ public final boolean mRepeatable; @@ -93,8 +96,8 @@ public class Key { /** The current pressed state of this key */ public boolean mPressed; - /** If this is a sticky key, is it on? */ - public boolean mOn; + /** If this is a sticky key, is its highlight on? */ + public boolean mHighlightOn; /** Key is enabled and responds on press */ public boolean mEnabled = true; @@ -144,13 +147,14 @@ public class Key { mKeyboard = keyboard; mHeight = height - keyboard.getVerticalGap(); mGap = keyboard.getHorizontalGap(); + mVisualInsetsLeft = mVisualInsetsRight = 0; mWidth = width - mGap; mEdgeFlags = edgeFlags; mHintIcon = null; mManualTemporaryUpperCaseHintIcon = null; mManualTemporaryUpperCaseCode = Keyboard.CODE_DUMMY; mLabelOption = 0; - mModifier = false; + mFunctional = false; mSticky = false; mRepeatable = false; mPopupCharacters = null; @@ -224,12 +228,16 @@ public class Key { mKeyboard.getMaxPopupKeyboardColumn()); mRepeatable = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable, false); - mModifier = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isModifier, false); + mFunctional = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isFunctional, false); mSticky = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isSticky, false); mEnabled = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_enabled, true); mEdgeFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyEdgeFlags, 0) | row.mRowEdgeFlags; + mVisualInsetsLeft = KeyboardParser.getDimensionOrFraction(keyAttr, + R.styleable.Keyboard_Key_visualInsetsLeft, mKeyboard.getDisplayHeight(), 0); + mVisualInsetsRight = KeyboardParser.getDimensionOrFraction(keyAttr, + R.styleable.Keyboard_Key_visualInsetsRight, mKeyboard.getDisplayHeight(), 0); mPreviewIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_iconPreview); Keyboard.setDefaultBounds(mPreviewIcon); mIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_keyIcon); @@ -315,26 +323,19 @@ public class Key { /** * Informs the key that it has been pressed, in case it needs to change its appearance or * state. - * @see #onReleased(boolean) + * @see #onReleased() */ public void onPressed() { - mPressed = !mPressed; + mPressed = true; } /** - * Changes the pressed state of the key. If it is a sticky key, it will also change the - * toggled state of the key if the finger was release inside. - * @param inside whether the finger was released inside the key + * Informs the key that it has been released, in case it needs to change its appearance or + * state. * @see #onPressed() */ - public void onReleased(boolean inside) { - mPressed = !mPressed; - if (mSticky && !mKeyboard.isShiftLockEnabled(this)) - mOn = !mOn; - } - - public boolean isInside(int x, int y) { - return mKeyboard.isInside(this, x, y); + public void onReleased() { + mPressed = false; } /** @@ -377,20 +378,14 @@ public class Key { return dx * dx + dy * dy; } - // sticky is used for shift key. If a key is not sticky and is modifier, - // the key will be treated as functional. - private boolean isFunctionalKey() { - return !mSticky && mModifier; - } - /** * Returns the drawable state for the key, based on the current state and type of the key. * @return the drawable state of the key. * @see android.graphics.drawable.StateListDrawable#setState(int[]) */ public int[] getCurrentDrawableState() { - final boolean pressed = mEnabled && mPressed; - if (isFunctionalKey()) { + final boolean pressed = mPressed; + if (!mSticky && mFunctional) { if (pressed) { return KEY_STATE_FUNCTIONAL_PRESSED; } else { @@ -400,7 +395,7 @@ public class Key { int[] states = KEY_STATE_NORMAL; - if (mOn) { + if (mHighlightOn) { if (pressed) { states = KEY_STATE_PRESSED_ON; } else { diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java index a8346c581..7add43a6d 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java @@ -16,36 +16,35 @@ package com.android.inputmethod.keyboard; +import android.util.Log; + import java.util.Arrays; -import java.util.HashMap; import java.util.List; -public abstract class KeyDetector { - public static final int NOT_A_KEY = -1; - public static final int NOT_A_CODE = -1; - - protected Keyboard mKeyboard; - - private Key[] mKeys; +public class KeyDetector { + private static final String TAG = KeyDetector.class.getSimpleName(); + private static final boolean DEBUG = false; - protected int mCorrectionX; - - protected int mCorrectionY; + public static final int NOT_A_CODE = -1; + public static final int NOT_A_KEY = -1; - protected boolean mProximityCorrectOn; + private Keyboard mKeyboard; + private int mCorrectionX; + private int mCorrectionY; + private boolean mProximityCorrectOn; + private int mProximityThresholdSquare; - protected int mProximityThresholdSquare; + // working area + private static final int MAX_NEARBY_KEYS = 12; + private final int[] mDistances = new int[MAX_NEARBY_KEYS]; + private final int[] mIndices = new int[MAX_NEARBY_KEYS]; - public Key[] setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { + public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { if (keyboard == null) throw new NullPointerException(); mCorrectionX = (int)correctionX; mCorrectionY = (int)correctionY; mKeyboard = keyboard; - List<Key> keys = mKeyboard.getKeys(); - Key[] array = keys.toArray(new Key[keys.size()]); - mKeys = array; - return array; } protected int getTouchX(int x) { @@ -56,11 +55,11 @@ public abstract class KeyDetector { return y + mCorrectionY; } - protected Key[] getKeys() { - if (mKeys == null) + protected List<Key> getKeys() { + if (mKeyboard == null) throw new IllegalStateException("keyboard isn't set"); // mKeyboard is guaranteed not to be null at setKeybaord() method if mKeys is not null - return mKeys; + return mKeyboard.getKeys(); } public void setProximityCorrectionEnabled(boolean enabled) { @@ -76,6 +75,17 @@ public abstract class KeyDetector { } /** + * Computes maximum size of the array that can contain all nearby key indices returned by + * {@link #getKeyIndexAndNearbyCodes}. + * + * @return Returns maximum size of the array that can contain all nearby key indices returned + * by {@link #getKeyIndexAndNearbyCodes}. + */ + protected int getMaxNearbyKeys() { + return MAX_NEARBY_KEYS; + } + + /** * Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes} * method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}. * @@ -89,14 +99,64 @@ public abstract class KeyDetector { return codes; } + private void initializeNearbyKeys() { + Arrays.fill(mDistances, Integer.MAX_VALUE); + Arrays.fill(mIndices, NOT_A_KEY); + } + /** - * Computes maximum size of the array that can contain all nearby key indices returned by - * {@link #getKeyIndexAndNearbyCodes}. + * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance. + * If the distance of two keys are the same, the key which the point is on should be considered + * as a closer one. * - * @return Returns maximum size of the array that can contain all nearby key indices returned - * by {@link #getKeyIndexAndNearbyCodes}. + * @param keyIndex index of the key. + * @param distance distance between the key's edge and user touched point. + * @param isOnKey true if the point is on the key. + * @return order of the key in the nearby buffer, 0 if it is the nearest key. */ - abstract protected int getMaxNearbyKeys(); + private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) { + final int[] distances = mDistances; + final int[] indices = mIndices; + for (int insertPos = 0; insertPos < distances.length; insertPos++) { + final int comparingDistance = distances[insertPos]; + if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) { + final int nextPos = insertPos + 1; + if (nextPos < distances.length) { + System.arraycopy(distances, insertPos, distances, nextPos, + distances.length - nextPos); + System.arraycopy(indices, insertPos, indices, nextPos, + indices.length - nextPos); + } + distances[insertPos] = distance; + indices[insertPos] = keyIndex; + return insertPos; + } + } + return distances.length; + } + + private void getNearbyKeyCodes(final int[] allCodes) { + final List<Key> keys = getKeys(); + final int[] indices = mIndices; + + // allCodes[0] should always have the key code even if it is a non-letter key. + if (indices[0] == NOT_A_KEY) { + allCodes[0] = NOT_A_CODE; + return; + } + + int numCodes = 0; + for (int j = 0; j < indices.length && numCodes < allCodes.length; j++) { + final int index = indices[j]; + if (index == NOT_A_KEY) + break; + final int code = keys.get(index).mCode; + // filter out a non-letter key from nearby keys + if (code < Keyboard.CODE_SPACE) + continue; + allCodes[numCodes++] = code; + } + } /** * Finds all possible nearby key indices around a touch event point and returns the nearest key @@ -109,32 +169,34 @@ public abstract class KeyDetector { * @param allCodes All nearby key code except functional key are returned in this array * @return The nearest key index */ - abstract public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes); + public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) { + final List<Key> keys = getKeys(); + final int touchX = getTouchX(x); + final int touchY = getTouchY(y); + + initializeNearbyKeys(); + int primaryIndex = NOT_A_KEY; + for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) { + final Key key = keys.get(index); + final boolean isOnKey = key.isOnKey(touchX, touchY); + final int distance = key.squaredDistanceToEdge(touchX, touchY); + if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) { + final int insertedPosition = sortNearbyKeys(index, distance, isOnKey); + if (insertedPosition == 0 && isOnKey) + primaryIndex = index; + } + } - /** - * Compute the most common key width in order to use it as proximity key detection threshold. - * - * @param keyboard The keyboard to compute the most common key width - * @return The most common key width in the keyboard - */ - public static int getMostCommonKeyWidth(final Keyboard keyboard) { - if (keyboard == null) return 0; - final List<Key> keys = keyboard.getKeys(); - if (keys == null || keys.size() == 0) return 0; - final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>(); - int maxCount = 0; - int mostCommonWidth = 0; - for (final Key key : keys) { - final Integer width = key.mWidth + key.mGap; - Integer count = histogram.get(width); - if (count == null) - count = 0; - histogram.put(width, ++count); - if (count > maxCount) { - maxCount = count; - mostCommonWidth = width; + if (allCodes != null && allCodes.length > 0) { + getNearbyKeyCodes(allCodes); + if (DEBUG) { + Log.d(TAG, "x=" + x + " y=" + y + + " primary=" + + (primaryIndex == NOT_A_KEY ? "none" : keys.get(primaryIndex).mCode) + + " codes=" + Arrays.toString(allCodes)); } } - return mostCommonWidth; + + return primaryIndex; } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/KeyStyles.java index 8d9b1b41e..d53df788f 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/KeyStyles.java @@ -185,7 +185,7 @@ public class KeyStyles { readDrawable(keyAttr, R.styleable.Keyboard_Key_iconPreview); readDrawable(keyAttr, R.styleable.Keyboard_Key_keyHintIcon); readDrawable(keyAttr, R.styleable.Keyboard_Key_shiftedIcon); - readBoolean(keyAttr, R.styleable.Keyboard_Key_isModifier); + readBoolean(keyAttr, R.styleable.Keyboard_Key_isFunctional); readBoolean(keyAttr, R.styleable.Keyboard_Key_isSticky); readBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable); readBoolean(keyAttr, R.styleable.Keyboard_Key_enabled); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 0b545d9c2..267abccb3 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -63,24 +63,22 @@ public class Keyboard { public static final int CODE_TAB = '\t'; public static final int CODE_SPACE = ' '; public static final int CODE_PERIOD = '.'; + public static final int CODE_DASH = '-'; + public static final int CODE_SINGLE_QUOTE = '\''; + public static final int CODE_DOUBLE_QUOTE = '"'; /** Special keys code. These should be aligned with values/keycodes.xml */ public static final int CODE_DUMMY = 0; public static final int CODE_SHIFT = -1; public static final int CODE_SWITCH_ALPHA_SYMBOL = -2; - public static final int CODE_CANCEL = -3; - public static final int CODE_DONE = -4; + public static final int CODE_CAPSLOCK = -3; + public static final int CODE_CANCEL = -4; public static final int CODE_DELETE = -5; - public static final int CODE_ALT = -6; + public static final int CODE_SETTINGS = -6; + public static final int CODE_SETTINGS_LONGPRESS = -7; + public static final int CODE_SHORTCUT = -8; // Code value representing the code is not specified. public static final int CODE_UNSPECIFIED = -99; - public static final int CODE_SETTINGS = -100; - public static final int CODE_SETTINGS_LONGPRESS = -101; - // TODO: remove this once LatinIME stops referring to this. - public static final int CODE_VOICE = -102; - public static final int CODE_CAPSLOCK = -103; - public static final int CODE_NEXT_LANGUAGE = -104; - public static final int CODE_PREV_LANGUAGE = -105; /** Horizontal gap default for all rows */ private int mDefaultHorizontalGap; @@ -128,6 +126,8 @@ public class Keyboard { /** Height of keyboard */ private int mKeyboardHeight; + private int mMostCommonKeyWidth = 0; + public final KeyboardId mId; // Variables for pre-computing nearest keys. @@ -151,22 +151,20 @@ public class Keyboard { * @param context the application or service context * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. * @param id keyboard identifier + * @param width keyboard width */ - public Keyboard(Context context, int xmlLayoutResId, KeyboardId id) { - this(context, xmlLayoutResId, id, - context.getResources().getDisplayMetrics().widthPixels, - context.getResources().getDisplayMetrics().heightPixels); - } - private Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width, - int height) { - Resources res = context.getResources(); + public Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width) { + final Resources res = context.getResources(); GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width); GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height); GRID_SIZE = GRID_WIDTH * GRID_HEIGHT; - mDisplayWidth = width; - mDisplayHeight = height; + final int horizontalEdgesPadding = (int)res.getDimension( + R.dimen.keyboard_horizontal_edges_padding); + mDisplayWidth = width - horizontalEdgesPadding * 2; + // TODO: Adjust the height by referring to the height of area available for drawing as well. + mDisplayHeight = res.getDisplayMetrics().heightPixels; mDefaultHorizontalGap = 0; setKeyWidth(mDisplayWidth / 10); @@ -293,7 +291,7 @@ public class Keyboard { public boolean setShiftLocked(boolean newShiftLockState) { final Map<Key, Drawable> shiftedIcons = getShiftedIcons(); for (final Key key : getShiftKeys()) { - key.mOn = newShiftLockState; + key.mHighlightOn = newShiftLockState; key.setIcon(newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key)); } mShiftState.setShiftLocked(newShiftLockState); @@ -381,10 +379,6 @@ public class Keyboard { mProximityInfo.setProximityInfo(mGridNeighbors, getMinWidth(), getHeight(), mKeys); } - public boolean isInside(Key key, int x, int y) { - return key.isOnKey(x, y); - } - /** * Returns the indices of the keys that are closest to the given point. * @param x the x-coordinate of the point @@ -403,6 +397,41 @@ public class Keyboard { return EMPTY_INT_ARRAY; } + /** + * Compute the most common key width in order to use it as proximity key detection threshold. + * + * @return The most common key width in the keyboard + */ + public int getMostCommonKeyWidth() { + if (mMostCommonKeyWidth == 0) { + final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>(); + int maxCount = 0; + int mostCommonWidth = 0; + for (final Key key : mKeys) { + final Integer width = key.mWidth + key.mGap; + Integer count = histogram.get(width); + if (count == null) + count = 0; + histogram.put(width, ++count); + if (count > maxCount) { + maxCount = count; + mostCommonWidth = width; + } + } + mMostCommonKeyWidth = mostCommonWidth; + } + return mMostCommonKeyWidth; + } + + /** + * Return true if spacebar needs showing preview even when "popup on keypress" is off. + * @param keyIndex index of the pressing key + * @return true if spacebar needs showing preview + */ + public boolean needSpacebarPreview(int keyIndex) { + return false; + } + private void loadKeyboard(Context context, int xmlLayoutResId) { try { KeyboardParser parser = new KeyboardParser(this, context.getResources()); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index 97ef687bd..2a5e17771 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -16,8 +16,9 @@ package com.android.inputmethod.keyboard; +import com.android.inputmethod.compat.EditorInfoCompatUtils; +import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Utils; import android.view.inputmethod.EditorInfo; @@ -39,6 +40,7 @@ public class KeyboardId { public final Locale mLocale; public final int mOrientation; + public final int mWidth; public final int mMode; public final int mXmlId; public final int mColorScheme; @@ -48,22 +50,25 @@ public class KeyboardId { public final boolean mHasVoiceKey; public final int mImeAction; public final boolean mEnableShiftLock; + public final String mXmlName; + public final EditorInfo mAttribute; private final int mHashCode; public KeyboardId(String xmlName, int xmlId, int colorScheme, Locale locale, int orientation, - int mode, EditorInfo attribute, boolean hasSettingsKey, boolean voiceKeyEnabled, - boolean hasVoiceKey, boolean enableShiftLock) { + int width, int mode, EditorInfo attribute, boolean hasSettingsKey, + boolean voiceKeyEnabled, boolean hasVoiceKey, boolean enableShiftLock) { final int inputType = (attribute != null) ? attribute.inputType : 0; final int imeOptions = (attribute != null) ? attribute.imeOptions : 0; this.mLocale = locale; this.mOrientation = orientation; + this.mWidth = width; this.mMode = mode; this.mXmlId = xmlId; this.mColorScheme = colorScheme; - this.mPasswordInput = Utils.isPasswordInputType(inputType) - || Utils.isVisiblePasswordInputType(inputType); + this.mPasswordInput = InputTypeCompatUtils.isPasswordInputType(inputType) + || InputTypeCompatUtils.isVisiblePasswordInputType(inputType); this.mHasSettingsKey = hasSettingsKey; this.mVoiceKeyEnabled = voiceKeyEnabled; this.mHasVoiceKey = hasVoiceKey; @@ -72,11 +77,14 @@ public class KeyboardId { this.mImeAction = imeOptions & ( EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION); this.mEnableShiftLock = enableShiftLock; + this.mXmlName = xmlName; + this.mAttribute = attribute; this.mHashCode = Arrays.hashCode(new Object[] { locale, orientation, + width, mode, xmlId, colorScheme, @@ -89,6 +97,18 @@ public class KeyboardId { }); } + public KeyboardId cloneWithNewLayout(String xmlName, int xmlId) { + return new KeyboardId(xmlName, xmlId, mColorScheme, mLocale, mOrientation, mWidth, mMode, + mAttribute, mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock); + } + + public KeyboardId cloneWithNewGeometry(int width) { + if (mWidth == width) + return this; + return new KeyboardId(mXmlName, mXmlId, mColorScheme, mLocale, mOrientation, width, mMode, + mAttribute, mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock); + } + public int getXmlId() { return mXmlId; } @@ -117,6 +137,7 @@ public class KeyboardId { boolean equals(KeyboardId other) { return other.mLocale.equals(this.mLocale) && other.mOrientation == this.mOrientation + && other.mWidth == this.mWidth && other.mMode == this.mMode && other.mXmlId == this.mXmlId && other.mColorScheme == this.mColorScheme @@ -135,12 +156,12 @@ public class KeyboardId { @Override public String toString() { - return String.format("[%s.xml %s %s %s imeAction=%s %s%s%s%s%s%s]", + return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s]", mXmlName, mLocale, - (mOrientation == 1 ? "port" : "land"), + (mOrientation == 1 ? "port" : "land"), mWidth, modeName(mMode), - imeOptionsName(mImeAction), + EditorInfoCompatUtils.imeOptionsName(mImeAction), (mPasswordInput ? " passwordInput" : ""), (mHasSettingsKey ? " hasSettingsKey" : ""), (mVoiceKeyEnabled ? " voiceKeyEnabled" : ""), @@ -170,26 +191,4 @@ public class KeyboardId { } return null; } - - public static String imeOptionsName(int imeOptions) { - if (imeOptions == -1) return null; - final int actionNo = imeOptions & EditorInfo.IME_MASK_ACTION; - final String action; - switch (actionNo) { - case EditorInfo.IME_ACTION_UNSPECIFIED: action = "actionUnspecified"; break; - case EditorInfo.IME_ACTION_NONE: action = "actionNone"; break; - case EditorInfo.IME_ACTION_GO: action = "actionGo"; break; - case EditorInfo.IME_ACTION_SEARCH: action = "actionSearch"; break; - case EditorInfo.IME_ACTION_SEND: action = "actionSend"; break; - case EditorInfo.IME_ACTION_DONE: action = "actionDone"; break; - case EditorInfo.IME_ACTION_PREVIOUS: action = "actionPrevious"; break; - default: action = "actionUnknown(" + actionNo + ")"; break; - } - if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) { - return "flagNoEnterAction|" + action; - } else { - return action; - } - } } - diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java index 6af0d537c..5980f0255 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java @@ -16,11 +16,13 @@ package com.android.inputmethod.keyboard; +import com.android.inputmethod.compat.EditorInfoCompatUtils; import com.android.inputmethod.latin.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; @@ -121,6 +123,7 @@ public class KeyboardParser { private final Keyboard mKeyboard; private final Resources mResources; + private int mHorizontalEdgesPadding; private int mCurrentX = 0; private int mCurrentY = 0; private int mMaxRowWidth = 0; @@ -131,6 +134,7 @@ public class KeyboardParser { public KeyboardParser(Keyboard keyboard, Resources res) { mKeyboard = keyboard; mResources = res; + mHorizontalEdgesPadding = (int)res.getDimension(R.dimen.keyboard_horizontal_edges_padding); } public int getMaxRowWidth() { @@ -150,6 +154,7 @@ public class KeyboardParser { final String tag = parser.getName(); if (TAG_KEYBOARD.equals(tag)) { parseKeyboardAttributes(parser); + startKeyboard(); parseKeyboardContent(parser, mKeyboard.getKeys()); break; } else { @@ -159,6 +164,27 @@ public class KeyboardParser { } } + public static String parseKeyboardLocale( + Context context, int resId) throws XmlPullParserException, IOException { + final Resources res = context.getResources(); + final XmlResourceParser parser = res.getXml(resId); + if (parser == null) return ""; + int event; + while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (event == XmlPullParser.START_TAG) { + final String tag = parser.getName(); + if (TAG_KEYBOARD.equals(tag)) { + final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.Keyboard); + return keyboardAttr.getString(R.styleable.Keyboard_keyboardLocale); + } else { + throw new IllegalStartTag(parser, TAG_KEYBOARD); + } + } + } + return ""; + } + private void parseKeyboardAttributes(XmlResourceParser parser) { final Keyboard keyboard = mKeyboard; final TypedArray keyboardAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser), @@ -170,9 +196,20 @@ public class KeyboardParser { final int keyboardHeight = (int)keyboardAttr.getDimension( R.styleable.Keyboard_keyboardHeight, displayHeight / 2); final int maxKeyboardHeight = getDimensionOrFraction(keyboardAttr, - R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2); - // Keyboard height will not exceed maxKeyboardHeight. - final int height = Math.min(keyboardHeight, maxKeyboardHeight); + R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2); + int minKeyboardHeight = getDimensionOrFraction(keyboardAttr, + R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2); + if (minKeyboardHeight < 0) { + // Specified fraction was negative, so it should be calculated against display + // width. + final int displayWidth = keyboard.getDisplayWidth(); + minKeyboardHeight = -getDimensionOrFraction(keyboardAttr, + R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2); + } + // Keyboard height will not exceed maxKeyboardHeight and will not be less than + // minKeyboardHeight. + final int height = Math.max( + Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight); final int width = keyboard.getDisplayWidth(); keyboard.setKeyboardHeight(height); @@ -453,7 +490,7 @@ public class KeyboardParser { booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"), booleanAttr(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"), booleanAttr(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"), - textAttr(KeyboardId.imeOptionsName( + textAttr(EditorInfoCompatUtils.imeOptionsName( a.getInt(R.styleable.Keyboard_Case_imeAction, -1)), "imeAction"), textAttr(a.getString(R.styleable.Keyboard_Case_languageCode), "languageCode"), textAttr(a.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"), @@ -519,25 +556,32 @@ public class KeyboardParser { throw new NonEmptyTag(tag, parser); } + private void startKeyboard() { + mCurrentY += (int)mResources.getDimension(R.dimen.keyboard_top_padding); + } + private void startRow(Row row) { mCurrentX = 0; + setSpacer(mHorizontalEdgesPadding); mCurrentRow = row; } private void endRow() { if (mCurrentRow == null) throw new InflateException("orphant end row tag"); + setSpacer(mHorizontalEdgesPadding); + if (mCurrentX > mMaxRowWidth) + mMaxRowWidth = mCurrentX; mCurrentY += mCurrentRow.mDefaultHeight; mCurrentRow = null; } private void endKey(Key key) { mCurrentX += key.mGap + key.mWidth; - if (mCurrentX > mMaxRowWidth) - mMaxRowWidth = mCurrentX; } private void endKeyboard(int defaultVerticalGap) { + mCurrentY += (int)mResources.getDimension(R.dimen.keyboard_bottom_padding); mTotalHeight = mCurrentY - defaultVerticalGap; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 64a23ab92..33e76d83f 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -16,20 +16,22 @@ package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Settings; -import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.Utils; - import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.util.Log; import android.view.InflateException; +import android.view.LayoutInflater; +import android.view.View; import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; + +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.LatinImeLogger; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.Utils; import java.lang.ref.SoftReference; import java.util.HashMap; @@ -37,7 +39,7 @@ import java.util.Locale; public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "KeyboardSwitcher"; - private static final boolean DEBUG = false; + private static final boolean DEBUG_CACHE = false; public static final boolean DEBUG_STATE = false; private static String sConfigDefaultKeyboardThemeId; @@ -54,9 +56,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private SubtypeSwitcher mSubtypeSwitcher; private SharedPreferences mPrefs; - private LatinKeyboardView mInputView; + private View mInputView; + private LatinKeyboardView mKeyboardView; private LatinIME mInputMethodService; + // TODO: Combine these key state objects with auto mode switch state. private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift"); private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol"); @@ -75,13 +79,17 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private boolean mVoiceKeyEnabled; private boolean mVoiceButtonOnPrimary; - private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0; - private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1; - private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2; + // TODO: Encapsulate these state handling to separate class and combine with ShiftKeyState + // and ModifierKeyState. + private static final int SWITCH_STATE_ALPHA = 0; + private static final int SWITCH_STATE_SYMBOL_BEGIN = 1; + private static final int SWITCH_STATE_SYMBOL = 2; // The following states are used only on the distinct multi-touch panel devices. - private static final int AUTO_MODE_SWITCH_STATE_MOMENTARY = 3; - private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4; - private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; + private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 3; + private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 4; + private static final int SWITCH_STATE_CHORDING_ALPHA = 5; + private static final int SWITCH_STATE_CHORDING_SYMBOL = 6; + private int mSwitchState = SWITCH_STATE_ALPHA; // Indicates whether or not we have the settings key in option of settings private boolean mSettingsKeyEnabledInSettings; @@ -94,6 +102,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO; private int mLayoutId; + private int mKeyboardWidth; private static final KeyboardSwitcher sInstance = new KeyboardSwitcher(); @@ -124,7 +133,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha public void loadKeyboard(EditorInfo attribute, boolean voiceKeyEnabled, boolean voiceButtonOnPrimary) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; + mSwitchState = SWITCH_STATE_ALPHA; try { loadKeyboardInternal(attribute, voiceKeyEnabled, voiceButtonOnPrimary, false); } catch (RuntimeException e) { @@ -137,7 +146,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private void loadKeyboardInternal(EditorInfo attribute, boolean voiceButtonEnabled, boolean voiceButtonOnPrimary, boolean isSymbols) { - if (mInputView == null) return; + if (mKeyboardView == null) return; mAttribute = attribute; mVoiceKeyEnabled = voiceButtonEnabled; @@ -147,19 +156,38 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService); final KeyboardId id = getKeyboardId(attribute, isSymbols); - final Keyboard oldKeyboard = mInputView.getKeyboard(); - if (oldKeyboard != null && oldKeyboard.mId.equals(id)) - return; + // Note: This comment is only applied for phone number keyboard layout. + // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch + // between "phone keyboard" and "phone symbols keyboard". But on xlarge device, + // "@integer/key_shift" key code is used for that purpose in order to properly display + // "more" and "locked more" key labels. To achieve these behavior, we should initialize + // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard" + // respectively here for xlarge device's layout switching. + mSymbolsId = makeSiblingKeyboardId(id, R.xml.kbd_symbols, R.xml.kbd_phone); + mSymbolsShiftedId = makeSiblingKeyboardId( + id, R.xml.kbd_symbols_shift, R.xml.kbd_phone_symbols); - makeSymbolsKeyboardIds(id.mMode, attribute); - mCurrentId = id; - mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); setKeyboard(getKeyboard(id)); } + public void onSizeChanged() { + final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth(); + if (width == 0) + return; + mKeyboardWidth = width; + // Set keyboard with new width. + final KeyboardId newId = mCurrentId.cloneWithNewGeometry(width); + setKeyboard(getKeyboard(newId)); + } + private void setKeyboard(final Keyboard newKeyboard) { - final Keyboard oldKeyboard = mInputView.getKeyboard(); - mInputView.setKeyboard(newKeyboard); + final Keyboard oldKeyboard = mKeyboardView.getKeyboard(); + mKeyboardView.setKeyboard(newKeyboard); + mCurrentId = newKeyboard.mId; + final Resources res = mInputMethodService.getResources(); + mKeyboardView.setKeyPreviewPopupEnabled( + Settings.Values.isKeyPreviewPopupEnabled(mPrefs, res), + Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, res)); final boolean localeChanged = (oldKeyboard == null) || !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged); @@ -169,22 +197,23 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id); LatinKeyboard keyboard = (ref == null) ? null : ref.get(); if (keyboard == null) { - final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale( + final Resources res = mInputMethodService.getResources(); + final Locale savedLocale = Utils.setSystemLocale(res, mSubtypeSwitcher.getInputLocale()); - keyboard = new LatinKeyboard(mInputMethodService, id); + keyboard = new LatinKeyboard(mInputMethodService, id, id.mWidth); if (id.mEnableShiftLock) { keyboard.enableShiftLock(); } mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard)); - if (DEBUG) + if (DEBUG_CACHE) Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": " + ((ref == null) ? "LOAD" : "GCed") + " id=" + id); - mSubtypeSwitcher.changeSystemLocale(savedLocale); - } else if (DEBUG) { + Utils.setSystemLocale(res, savedLocale); + } else if (DEBUG_CACHE) { Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id); } @@ -195,6 +224,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // we should reset the text fade factor. It is also applicable to shortcut key. keyboard.setSpacebarTextFadeFactor(0.0f, null); keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady(), null); + keyboard.setSpacebarSlidingLanguageSwitchDiff(0); return keyboard; } @@ -240,33 +270,19 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final boolean hasSettingsKey = hasSettingsKey(attribute); final Resources res = mInputMethodService.getResources(); final int orientation = res.getConfiguration().orientation; + if (mKeyboardWidth == 0) + mKeyboardWidth = res.getDisplayMetrics().widthPixels; final Locale locale = mSubtypeSwitcher.getInputLocale(); return new KeyboardId( - res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation, mode, - attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, enableShiftLock); + res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation, + mKeyboardWidth, mode, attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, + enableShiftLock); } - private void makeSymbolsKeyboardIds(final int mode, EditorInfo attribute) { - final Locale locale = mSubtypeSwitcher.getInputLocale(); - final Resources res = mInputMethodService.getResources(); - final int orientation = res.getConfiguration().orientation; - final int colorScheme = getColorScheme(); - final boolean hasVoiceKey = mVoiceKeyEnabled && !mVoiceButtonOnPrimary; - final boolean hasSettingsKey = hasSettingsKey(attribute); - // Note: This comment is only applied for phone number keyboard layout. - // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch - // between "phone keyboard" and "phone symbols keyboard". But on xlarge device, - // "@integer/key_shift" key code is used for that purpose in order to properly display - // "more" and "locked more" key labels. To achieve these behavior, we should initialize - // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard" - // respectively here for xlarge device's layout switching. - int xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols; - final String xmlName = res.getResourceEntryName(xmlId); - mSymbolsId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode, - attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, true); - xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift; - mSymbolsShiftedId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode, - attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, true); + private KeyboardId makeSiblingKeyboardId(KeyboardId base, int alphabet, int phone) { + final int xmlId = base.mMode == KeyboardId.MODE_PHONE ? phone : alphabet; + final String xmlName = mInputMethodService.getResources().getResourceEntryName(xmlId); + return base.cloneWithNewLayout(xmlName, xmlId); } public int getKeyboardMode() { @@ -278,30 +294,24 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } public boolean isInputViewShown() { - return mInputView != null && mInputView.isShown(); + return mKeyboardView != null && mKeyboardView.isShown(); } public boolean isKeyboardAvailable() { - if (mInputView != null) - return mInputView.getKeyboard() != null; + if (mKeyboardView != null) + return mKeyboardView.getKeyboard() != null; return false; } public LatinKeyboard getLatinKeyboard() { - if (mInputView != null) { - final Keyboard keyboard = mInputView.getKeyboard(); + if (mKeyboardView != null) { + final Keyboard keyboard = mKeyboardView.getKeyboard(); if (keyboard instanceof LatinKeyboard) return (LatinKeyboard)keyboard; } return null; } - public void keyReleased() { - LatinKeyboard latinKeyboard = getLatinKeyboard(); - if (latinKeyboard != null) - latinKeyboard.keyReleased(); - } - public boolean isShiftedOrShiftLocked() { LatinKeyboard latinKeyboard = getLatinKeyboard(); if (latinKeyboard != null) @@ -344,12 +354,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // state when shift key is pressed to go to normal mode. // On the other hand, on distinct multi touch panel device, turning off the shift locked // state with shift key pressing is handled by onReleaseShift(). - if ((!hasDistinctMultitouch() || isAccessibilityEnabled()) - && !shifted && latinKeyboard.isShiftLocked()) { + if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) { latinKeyboard.setShiftLocked(false); } if (latinKeyboard.setShifted(shifted)) { - mInputView.invalidateAllKeys(); + mKeyboardView.invalidateAllKeys(); } } } @@ -357,7 +366,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private void setShiftLocked(boolean shiftLocked) { LatinKeyboard latinKeyboard = getLatinKeyboard(); if (latinKeyboard != null && latinKeyboard.setShiftLocked(shiftLocked)) { - mInputView.invalidateAllKeys(); + mKeyboardView.invalidateAllKeys(); } } @@ -399,7 +408,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha LatinKeyboard latinKeyboard = getLatinKeyboard(); if (latinKeyboard != null) { latinKeyboard.setAutomaticTemporaryUpperCase(); - mInputView.invalidateAllKeys(); + mKeyboardView.invalidateAllKeys(); } } @@ -443,9 +452,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha public void onPressShift(boolean withSliding) { if (!isKeyboardAvailable()) return; - // If accessibility is enabled, disable momentary shift lock. - if (isAccessibilityEnabled()) - return; ShiftKeyState shiftKeyState = mShiftKeyState; if (DEBUG_STATE) Log.d(TAG, "onPressShift:" @@ -475,15 +481,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // In symbol mode, just toggle symbol and symbol more keyboard. shiftKeyState.onPress(); toggleShift(); + mSwitchState = SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE; } } public void onReleaseShift(boolean withSliding) { if (!isKeyboardAvailable()) return; - // If accessibility is enabled, disable momentary shift lock. - if (isAccessibilityEnabled()) - return; ShiftKeyState shiftKeyState = mShiftKeyState; if (DEBUG_STATE) Log.d(TAG, "onReleaseShift:" @@ -496,6 +500,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } else if (isShiftLocked() && !shiftKeyState.isIgnoring() && !withSliding) { // Shift has been pressed without chording while caps lock state. toggleCapsLock(); + // To be able to turn off caps lock by "double tap" on shift key, we should ignore + // the second tap of the "double tap" from now for a while because we just have + // already turned off caps lock above. + mKeyboardView.startIgnoringDoubleTap(); } else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted() && !withSliding) { // Shift has been pressed without chording while shifted state. @@ -506,42 +514,40 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // transited from automatic temporary upper case. toggleShift(); } + } else { + // In symbol mode, snap back to the previous keyboard mode if the user chords the shift + // key and another key, then releases the shift key. + if (mSwitchState == SWITCH_STATE_CHORDING_SYMBOL) { + toggleShift(); + } } shiftKeyState.onRelease(); } public void onPressSymbol() { - // If accessibility is enabled, disable momentary symbol lock. - if (isAccessibilityEnabled()) - return; if (DEBUG_STATE) Log.d(TAG, "onPressSymbol:" + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() + " symbolKeyState=" + mSymbolKeyState); changeKeyboardMode(); mSymbolKeyState.onPress(); - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY; + mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL; } public void onReleaseSymbol() { - // If accessibility is enabled, disable momentary symbol lock. - if (isAccessibilityEnabled()) - return; if (DEBUG_STATE) Log.d(TAG, "onReleaseSymbol:" + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() + " symbolKeyState=" + mSymbolKeyState); // Snap back to the previous keyboard mode if the user chords the mode change key and - // other key, then released the mode change key. - if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING) + // another key, then releases the mode change key. + if (mSwitchState == SWITCH_STATE_CHORDING_ALPHA) { changeKeyboardMode(); + } mSymbolKeyState.onRelease(); } public void onOtherKeyPressed() { - // If accessibility is enabled, disable momentary mode locking. - if (isAccessibilityEnabled()) - return; if (DEBUG_STATE) Log.d(TAG, "onOtherKeyPressed:" + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() @@ -553,8 +559,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha public void onCancelInput() { // Snap back to the previous keyboard mode if the user cancels sliding input. - if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY && getPointerCount() == 1) - changeKeyboardMode(); + if (getPointerCount() == 1) { + if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) { + changeKeyboardMode(); + } else if (mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE) { + toggleShift(); + } + } } private void toggleShiftInSymbol() { @@ -562,74 +573,91 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha return; final LatinKeyboard keyboard; if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) { - mCurrentId = mSymbolsShiftedId; - keyboard = getKeyboard(mCurrentId); + keyboard = getKeyboard(mSymbolsShiftedId); // Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To - // enable the indicator, we need to call enableShiftLock() and setShiftLocked(true). - // Thus we can keep the ALT key's Key.on value true while LatinKey.onRelease() is - // called. + // enable the indicator, we need to call setShiftLocked(true). keyboard.setShiftLocked(true); } else { - mCurrentId = mSymbolsId; - keyboard = getKeyboard(mCurrentId); + keyboard = getKeyboard(mSymbolsId); // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the - // indicator, we need to call enableShiftLock() and setShiftLocked(false). - keyboard.setShifted(false); + // indicator, we need to call setShiftLocked(false). + keyboard.setShiftLocked(false); } setKeyboard(keyboard); } - public boolean isInMomentaryAutoModeSwitchState() { - return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY; + public boolean isInMomentarySwitchState() { + return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL + || mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE; } public boolean isVibrateAndSoundFeedbackRequired() { - return mInputView == null || !mInputView.isInSlidingKeyInput(); + return mKeyboardView == null || !mKeyboardView.isInSlidingKeyInput(); } private int getPointerCount() { - return mInputView == null ? 0 : mInputView.getPointerCount(); + return mKeyboardView == null ? 0 : mKeyboardView.getPointerCount(); } private void toggleKeyboardMode() { loadKeyboardInternal(mAttribute, mVoiceKeyEnabled, mVoiceButtonOnPrimary, !mIsSymbols); if (mIsSymbols) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN; + mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; } else { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; + mSwitchState = SWITCH_STATE_ALPHA; } } - public boolean isAccessibilityEnabled() { - return mInputView != null && mInputView.isAccessibilityEnabled(); - } - public boolean hasDistinctMultitouch() { - return mInputView != null && mInputView.hasDistinctMultitouch(); + return mKeyboardView != null && mKeyboardView.hasDistinctMultitouch(); + } + + private static boolean isSpaceCharacter(int c) { + return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER; + } + + private static boolean isQuoteCharacter(int c) { + // Apostrophe, quotation mark. + if (c == Keyboard.CODE_SINGLE_QUOTE || c == Keyboard.CODE_DOUBLE_QUOTE) + return true; + // \u2018: Left single quotation mark + // \u2019: Right single quotation mark + // \u201a: Single low-9 quotation mark + // \u201b: Single high-reversed-9 quotation mark + // \u201c: Left double quotation mark + // \u201d: Right double quotation mark + // \u201e: Double low-9 quotation mark + // \u201f: Double high-reversed-9 quotation mark + if (c >= '\u2018' && c <= '\u201f') + return true; + // \u00ab: Left-pointing double angle quotation mark + // \u00bb: Right-pointing double angle quotation mark + if (c == '\u00ab' || c == '\u00bb') + return true; + return false; } /** * Updates state machine to figure out when to automatically snap back to the previous mode. */ - public void onKey(int key) { + public void onKey(int code) { if (DEBUG_STATE) - Log.d(TAG, "onKey: code=" + key + " autoModeSwitchState=" + mAutoModeSwitchState + Log.d(TAG, "onKey: code=" + code + " switchState=" + mSwitchState + " pointers=" + getPointerCount()); - switch (mAutoModeSwitchState) { - case AUTO_MODE_SWITCH_STATE_MOMENTARY: + switch (mSwitchState) { + case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL: // Only distinct multi touch devices can be in this state. // On non-distinct multi touch devices, mode change key is handled by // {@link LatinIME#onCodeInput}, not by {@link LatinIME#onPress} and - // {@link LatinIME#onRelease}. So, on such devices, {@link #mAutoModeSwitchState} starts - // from {@link #AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN}, or - // {@link #AUTO_MODE_SWITCH_STATE_ALPHA}, not from - // {@link #AUTO_MODE_SWITCH_STATE_MOMENTARY}. - if (key == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { + // {@link LatinIME#onRelease}. So, on such devices, {@link #mSwitchState} starts + // from {@link #SWITCH_STATE_SYMBOL_BEGIN}, or {@link #SWITCH_STATE_ALPHA}, not from + // {@link #SWITCH_STATE_MOMENTARY}. + if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { // Detected only the mode change key has been pressed, and then released. if (mIsSymbols) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN; + mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; } else { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; + mSwitchState = SWITCH_STATE_ALPHA; } } else if (getPointerCount() == 1) { // Snap back to the previous keyboard mode if the user pressed the mode change key @@ -640,38 +668,58 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } else { // Chording input is being started. The keyboard mode will be snapped back to the // previous mode in {@link onReleaseSymbol} when the mode change key is released. - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING; + mSwitchState = SWITCH_STATE_CHORDING_ALPHA; + } + break; + case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE: + if (code == Keyboard.CODE_SHIFT) { + // Detected only the shift key has been pressed on symbol layout, and then released. + mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; + } else if (getPointerCount() == 1) { + // Snap back to the previous keyboard mode if the user pressed the shift key on + // symbol mode and slid to other key, then released the finger. + toggleShift(); + mSwitchState = SWITCH_STATE_SYMBOL; + } else { + // Chording input is being started. The keyboard mode will be snapped back to the + // previous mode in {@link onReleaseShift} when the shift key is released. + mSwitchState = SWITCH_STATE_CHORDING_SYMBOL; } break; - case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN: - if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key >= 0) { - mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL; + case SWITCH_STATE_SYMBOL_BEGIN: + if (!isSpaceCharacter(code) && code >= 0) { + mSwitchState = SWITCH_STATE_SYMBOL; + } + // Snap back to alpha keyboard mode immediately if user types a quote character. + if (isQuoteCharacter(code)) { + changeKeyboardMode(); } break; - case AUTO_MODE_SWITCH_STATE_SYMBOL: + case SWITCH_STATE_SYMBOL: + case SWITCH_STATE_CHORDING_SYMBOL: // Snap back to alpha keyboard mode if user types one or more non-space/enter - // characters followed by a space/enter. - if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) { + // characters followed by a space/enter or a quote character. + if (isSpaceCharacter(code) || isQuoteCharacter(code)) { changeKeyboardMode(); } break; } } - public LatinKeyboardView getInputView() { - return mInputView; + public LatinKeyboardView getKeyboardView() { + return mKeyboardView; } - public LatinKeyboardView onCreateInputView() { + public View onCreateInputView() { createInputViewInternal(mLayoutId, true); return mInputView; } private void createInputViewInternal(int newLayout, boolean forceReset) { int layoutId = newLayout; - if (mLayoutId != layoutId || mInputView == null || forceReset) { - if (mInputView != null) { - mInputView.closing(); + if (mLayoutId != layoutId || mKeyboardView == null || forceReset) { + if (mKeyboardView != null) { + mKeyboardView.closing(); } if (KEYBOARD_THEMES.length <= layoutId) { layoutId = Integer.valueOf(sConfigDefaultKeyboardThemeId); @@ -681,8 +729,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha boolean tryGC = true; for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { try { - mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater( - ).inflate(KEYBOARD_THEMES[layoutId], null); + mInputView = LayoutInflater.from(mInputMethodService).inflate( + KEYBOARD_THEMES[layoutId], null); tryGC = false; } catch (OutOfMemoryError e) { Log.w(TAG, "load keyboard failed: " + e); @@ -694,7 +742,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha mLayoutId + "," + layoutId, e); } } - mInputView.setOnKeyboardActionListener(mInputMethodService); + mKeyboardView = (LatinKeyboardView)mInputView.findViewById(R.id.latin_keyboard_view); + mKeyboardView.setOnKeyboardActionListener(mInputMethodService); mLayoutId = layoutId; } } @@ -703,8 +752,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha mInputMethodService.mHandler.post(new Runnable() { @Override public void run() { - if (mInputView != null) { - mInputMethodService.setInputView(mInputView); + if (mKeyboardView != null) { + mInputMethodService.setInputView(mKeyboardView); } mInputMethodService.updateInputViewShown(); } @@ -727,13 +776,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } private int getColorScheme() { - return (mInputView != null) - ? mInputView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE; + return (mKeyboardView != null) + ? mKeyboardView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE; } public void onAutoCorrectionStateChanged(boolean isAutoCorrection) { if (isAutoCorrection != mIsAutoCorrectionActive) { - LatinKeyboardView keyboardView = getInputView(); + LatinKeyboardView keyboardView = getKeyboardView(); mIsAutoCorrectionActive = isAutoCorrection; keyboardView.invalidateKey(((LatinKeyboard) keyboardView.getKeyboard()) .onAutoCorrectionStateChanged(isAutoCorrection)); @@ -752,8 +801,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha if (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW)) || (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_AUTO)) && Utils.hasMultipleEnabledIMEsOrSubtypes( - ((InputMethodManager) context.getSystemService( - Context.INPUT_METHOD_SERVICE))))) { + (InputMethodManagerCompatWrapper.getInstance(context))))) { return true; } return false; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index e33e76251..1df6444a0 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeSwitcher; import android.content.Context; import android.content.pm.PackageManager; @@ -36,44 +35,52 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; -import android.os.SystemClock; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.GestureDetector; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; +import android.widget.FrameLayout; +import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.TextView; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.WeakHashMap; /** * A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key * presses and touch movements. * + * @attr ref R.styleable#KeyboardView_backgroundDimAmount + * @attr ref R.styleable#KeyboardView_colorScheme * @attr ref R.styleable#KeyboardView_keyBackground + * @attr ref R.styleable#KeyboardView_keyHysteresisDistance + * @attr ref R.styleable#KeyboardView_keyLetterRatio + * @attr ref R.styleable#KeyboardView_keyLetterStyle * @attr ref R.styleable#KeyboardView_keyPreviewLayout * @attr ref R.styleable#KeyboardView_keyPreviewOffset - * @attr ref R.styleable#KeyboardView_labelTextSize - * @attr ref R.styleable#KeyboardView_keyTextSize + * @attr ref R.styleable#KeyboardView_keyPreviewHeight * @attr ref R.styleable#KeyboardView_keyTextColor + * @attr ref R.styleable#KeyboardView_keyTextColorDisabled + * @attr ref R.styleable#KeyboardView_labelTextRatio * @attr ref R.styleable#KeyboardView_verticalCorrection * @attr ref R.styleable#KeyboardView_popupLayout + * @attr ref R.styleable#KeyboardView_shadowColor + * @attr ref R.styleable#KeyboardView_shadowRadius */ public class KeyboardView extends View implements PointerTracker.UIProxy { private static final String TAG = KeyboardView.class.getSimpleName(); private static final boolean DEBUG_SHOW_ALIGN = false; private static final boolean DEBUG_KEYBOARD_GRID = false; - private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = false; + private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = true; private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true; public static final int COLOR_SCHEME_WHITE = 0; @@ -87,53 +94,44 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private static final int HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL = -1; // XML attribute - private int mKeyLetterSize; - private int mKeyTextColor; - private int mKeyTextColorDisabled; - private Typeface mKeyLetterStyle = Typeface.DEFAULT; - private int mLabelTextSize; - private int mColorScheme = COLOR_SCHEME_WHITE; - private int mShadowColor; - private float mShadowRadius; - private Drawable mKeyBackground; - private float mBackgroundDimAmount; - private float mKeyHysteresisDistance; - private float mVerticalCorrection; - private int mPreviewOffset; - private int mPreviewHeight; - private int mPopupLayout; + private final float mKeyLetterRatio; + private final int mKeyTextColor; + private final int mKeyTextColorDisabled; + private final Typeface mKeyLetterStyle; + private final float mLabelTextRatio; + private final int mColorScheme; + private final int mShadowColor; + private final float mShadowRadius; + private final Drawable mKeyBackground; + private final float mBackgroundDimAmount; + private final float mKeyHysteresisDistance; + private final float mVerticalCorrection; + private final int mPreviewOffset; + private final int mPreviewHeight; + private final int mPopupLayout; // Main keyboard private Keyboard mKeyboard; - private Key[] mKeys; + private int mKeyLetterSize; + private int mLabelTextSize; - // Key preview popup + // Key preview private boolean mInForeground; private TextView mPreviewText; - private PopupWindow mPreviewPopup; - private int mPreviewTextSizeLarge; - private int[] mOffsetInWindow; - private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY; - private boolean mShowPreview = true; - private int mPopupPreviewOffsetX; - private int mPopupPreviewOffsetY; - private int mWindowY; - private int mPopupPreviewDisplayedY; + private float mPreviewTextRatio; + private int mPreviewTextSize; + private boolean mShowKeyPreviewPopup = true; + private int mKeyPreviewPopupDisplayedY; private final int mDelayBeforePreview; - private final int mDelayAfterPreview; - - // Popup mini keyboard - private PopupWindow mMiniKeyboardPopup; - private KeyboardView mMiniKeyboardView; - private View mMiniKeyboardParent; - private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>(); - private int mMiniKeyboardOriginX; - private int mMiniKeyboardOriginY; - private long mMiniKeyboardPopupTime; - private int[] mWindowOffset; - private final float mMiniKeyboardSlideAllowance; - private int mMiniKeyboardTrackerId; - private final boolean mConfigShowMiniKeyboardAtTouchedPoint; + private int mDelayAfterPreview; + private ViewGroup mPreviewPlacer; + private final int[] mCoordinates = new int[2]; + + // Mini keyboard + private PopupWindow mPopupWindow; + private PopupPanel mPopupMiniKeyboardPanel; + private final WeakHashMap<Key, PopupPanel> mPopupPanelCache = + new WeakHashMap<Key, PopupPanel>(); /** Listener for {@link KeyboardActionListener}. */ private KeyboardActionListener mKeyboardActionListener; @@ -145,14 +143,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private final boolean mHasDistinctMultitouch; private int mOldPointerCount = 1; + private int mOldKeyIndex; - // Accessibility - private boolean mIsAccessibilityEnabled; - - protected KeyDetector mKeyDetector = new ProximityKeyDetector(); + protected KeyDetector mKeyDetector = new KeyDetector(); // Swipe gesture detector - private GestureDetector mGestureDetector; + protected GestureDetector mGestureDetector; private final SwipeTracker mSwipeTracker = new SwipeTracker(); private final int mSwipeThreshold; private final boolean mDisambiguateSwipe; @@ -189,65 +185,67 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private final UIHandler mHandler = new UIHandler(); class UIHandler extends Handler { - private static final int MSG_POPUP_PREVIEW = 1; - private static final int MSG_DISMISS_PREVIEW = 2; + private static final int MSG_SHOW_KEY_PREVIEW = 1; + private static final int MSG_DISMISS_KEY_PREVIEW = 2; private static final int MSG_REPEAT_KEY = 3; private static final int MSG_LONGPRESS_KEY = 4; private static final int MSG_LONGPRESS_SHIFT_KEY = 5; + private static final int MSG_IGNORE_DOUBLE_TAP = 6; private boolean mInKeyRepeat; @Override public void handleMessage(Message msg) { + final PointerTracker tracker = (PointerTracker) msg.obj; switch (msg.what) { - case MSG_POPUP_PREVIEW: - showKey(msg.arg1, (PointerTracker)msg.obj); - break; - case MSG_DISMISS_PREVIEW: - mPreviewPopup.dismiss(); - break; - case MSG_REPEAT_KEY: { - final PointerTracker tracker = (PointerTracker)msg.obj; - tracker.repeatKey(msg.arg1); - startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker); - break; - } - case MSG_LONGPRESS_KEY: { - final PointerTracker tracker = (PointerTracker)msg.obj; - openPopupIfRequired(msg.arg1, tracker); - break; - } - case MSG_LONGPRESS_SHIFT_KEY: { - final PointerTracker tracker = (PointerTracker)msg.obj; - onLongPressShiftKey(tracker); - break; - } + case MSG_SHOW_KEY_PREVIEW: + showKey(msg.arg1, tracker); + break; + case MSG_DISMISS_KEY_PREVIEW: + mPreviewText.setVisibility(View.INVISIBLE); + break; + case MSG_REPEAT_KEY: + tracker.onRepeatKey(msg.arg1); + startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker); + break; + case MSG_LONGPRESS_KEY: + openMiniKeyboardIfRequired(msg.arg1, tracker); + break; + case MSG_LONGPRESS_SHIFT_KEY: + onLongPressShiftKey(tracker); + break; } } - public void popupPreview(long delay, int keyIndex, PointerTracker tracker) { - removeMessages(MSG_POPUP_PREVIEW); - if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) { + public void showKeyPreview(long delay, int keyIndex, PointerTracker tracker) { + removeMessages(MSG_SHOW_KEY_PREVIEW); + if (mPreviewText.getVisibility() == VISIBLE || delay == 0) { // Show right away, if it's already visible and finger is moving around showKey(keyIndex, tracker); } else { - sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), - delay); + sendMessageDelayed( + obtainMessage(MSG_SHOW_KEY_PREVIEW, keyIndex, 0, tracker), delay); } } - public void cancelPopupPreview() { - removeMessages(MSG_POPUP_PREVIEW); + public void cancelShowKeyPreview(PointerTracker tracker) { + removeMessages(MSG_SHOW_KEY_PREVIEW, tracker); } - public void dismissPreview(long delay) { - if (mPreviewPopup.isShowing()) { - sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); - } + public void cancelAllShowKeyPreviews() { + removeMessages(MSG_SHOW_KEY_PREVIEW); } - public void cancelDismissPreview() { - removeMessages(MSG_DISMISS_PREVIEW); + public void dismissKeyPreview(long delay, PointerTracker tracker) { + sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay); + } + + public void cancelDismissKeyPreview(PointerTracker tracker) { + removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker); + } + + public void cancelAllDismissKeyPreviews() { + removeMessages(MSG_DISMISS_KEY_PREVIEW); } public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) { @@ -285,12 +283,22 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public void cancelKeyTimers() { cancelKeyRepeatTimer(); cancelLongPressTimers(); + removeMessages(MSG_IGNORE_DOUBLE_TAP); + } + + public void startIgnoringDoubleTap() { + sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP), + ViewConfiguration.getDoubleTapTimeout()); + } + + public boolean isIgnoringDoubleTap() { + return hasMessages(MSG_IGNORE_DOUBLE_TAP); } public void cancelAllMessages() { cancelKeyTimers(); - cancelPopupPreview(); - cancelDismissPreview(); + cancelAllShowKeyPreviews(); + cancelAllDismissKeyPreviews(); } } @@ -303,95 +311,44 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView); - int previewLayout = 0; - int keyTextSize = 0; - - int n = a.getIndexCount(); - for (int i = 0; i < n; i++) { - int attr = a.getIndex(i); - - switch (attr) { - case R.styleable.KeyboardView_keyBackground: - mKeyBackground = a.getDrawable(attr); - break; - case R.styleable.KeyboardView_keyHysteresisDistance: - mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0); - break; - case R.styleable.KeyboardView_verticalCorrection: - mVerticalCorrection = a.getDimensionPixelOffset(attr, 0); - break; - case R.styleable.KeyboardView_keyPreviewLayout: - previewLayout = a.getResourceId(attr, 0); - break; - case R.styleable.KeyboardView_keyPreviewOffset: - mPreviewOffset = a.getDimensionPixelOffset(attr, 0); - break; - case R.styleable.KeyboardView_keyPreviewHeight: - mPreviewHeight = a.getDimensionPixelSize(attr, 80); - break; - case R.styleable.KeyboardView_keyLetterSize: - mKeyLetterSize = a.getDimensionPixelSize(attr, 18); - break; - case R.styleable.KeyboardView_keyTextColor: - mKeyTextColor = a.getColor(attr, 0xFF000000); - break; - case R.styleable.KeyboardView_keyTextColorDisabled: - mKeyTextColorDisabled = a.getColor(attr, 0xFF000000); - break; - case R.styleable.KeyboardView_labelTextSize: - mLabelTextSize = a.getDimensionPixelSize(attr, 14); - break; - case R.styleable.KeyboardView_popupLayout: - mPopupLayout = a.getResourceId(attr, 0); - break; - case R.styleable.KeyboardView_shadowColor: - mShadowColor = a.getColor(attr, 0); - break; - case R.styleable.KeyboardView_shadowRadius: - mShadowRadius = a.getFloat(attr, 0f); - break; - // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount) - case R.styleable.KeyboardView_backgroundDimAmount: - mBackgroundDimAmount = a.getFloat(attr, 0.5f); - break; - case R.styleable.KeyboardView_keyLetterStyle: - mKeyLetterStyle = Typeface.defaultFromStyle(a.getInt(attr, Typeface.NORMAL)); - break; - case R.styleable.KeyboardView_colorScheme: - mColorScheme = a.getInt(attr, COLOR_SCHEME_WHITE); - break; - } - } + mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground); + mKeyHysteresisDistance = a.getDimensionPixelOffset( + R.styleable.KeyboardView_keyHysteresisDistance, 0); + mVerticalCorrection = a.getDimensionPixelOffset( + R.styleable.KeyboardView_verticalCorrection, 0); + final int previewLayout = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0); + mPreviewOffset = a.getDimensionPixelOffset(R.styleable.KeyboardView_keyPreviewOffset, 0); + mPreviewHeight = a.getDimensionPixelSize(R.styleable.KeyboardView_keyPreviewHeight, 80); + mKeyLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLetterRatio); + mKeyTextColor = a.getColor(R.styleable.KeyboardView_keyTextColor, 0xFF000000); + mKeyTextColorDisabled = a.getColor( + R.styleable.KeyboardView_keyTextColorDisabled, 0xFF000000); + mLabelTextRatio = getRatio(a, R.styleable.KeyboardView_labelTextRatio); + mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0); + mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0); + mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f); + // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount) + mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f); + mKeyLetterStyle = Typeface.defaultFromStyle( + a.getInt(R.styleable.KeyboardView_keyLetterStyle, Typeface.NORMAL)); + mColorScheme = a.getInt(R.styleable.KeyboardView_colorScheme, COLOR_SCHEME_WHITE); final Resources res = getResources(); - mPreviewPopup = new PopupWindow(context); if (previewLayout != 0) { mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null); - mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large); - mPreviewPopup.setContentView(mPreviewText); - mPreviewPopup.setBackgroundDrawable(null); + mPreviewTextRatio = getRatio(res, R.fraction.key_preview_text_ratio); } else { - mShowPreview = false; + mShowKeyPreviewPopup = false; } - mPreviewPopup.setTouchable(false); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview); mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview); mKeyLabelHorizontalPadding = (int)res.getDimension( R.dimen.key_label_horizontal_alignment_padding); - mMiniKeyboardParent = this; - mMiniKeyboardPopup = new PopupWindow(context); - mMiniKeyboardPopup.setBackgroundDrawable(null); - mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation); - // Allow popup window to be drawn off the screen. - mMiniKeyboardPopup.setClippingEnabled(false); - mPaint = new Paint(); mPaint.setAntiAlias(true); - mPaint.setTextSize(keyTextSize); mPaint.setTextAlign(Align.CENTER); mPaint.setAlpha(255); @@ -399,11 +356,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mKeyBackground.getPadding(mPadding); mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density); - // TODO: Refer frameworks/base/core/res/res/values/config.xml + // TODO: Refer to frameworks/base/core/res/res/values/config.xml mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation); - mMiniKeyboardSlideAllowance = res.getDimension(R.dimen.mini_keyboard_slide_allowance); - mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean( - R.bool.config_show_mini_keyboard_at_touched_point); GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @@ -454,7 +408,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { final PointerTracker tracker = getPointerTracker(id); // If the second down event is also on shift key. if (tracker.isOnShiftKey((int)secondDown.getX(), (int)secondDown.getY())) { - onDoubleTapShiftKey(tracker); + // Detected a double tap on shift key. If we are in the ignoring double tap + // mode, it means we have already turned off caps lock in + // {@link KeyboardSwitcher#onReleaseShift} . + final boolean ignoringDoubleTap = mHandler.isIgnoringDoubleTap(); + if (!ignoringDoubleTap) + onDoubleTapShiftKey(tracker); return true; } // Otherwise these events should not be handled as double tap. @@ -473,6 +432,21 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval); } + // Read fraction value in TypedArray as float. + private static float getRatio(TypedArray a, int index) { + return a.getFraction(index, 1000, 1000, 1) / 1000.0f; + } + + // Read fraction value in resource as float. + private static float getRatio(Resources res, int id) { + return res.getFraction(id, 1000, 1000) / 1000.0f; + } + + public void startIgnoringDoubleTap() { + if (ENABLE_CAPSLOCK_BY_DOUBLETAP) + mHandler.startIgnoringDoubleTap(); + } + public void setOnKeyboardActionListener(KeyboardActionListener listener) { mKeyboardActionListener = listener; for (PointerTracker tracker : mPointerTrackers) { @@ -488,6 +462,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { return mKeyboardActionListener; } + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + // TODO: Should notify InputMethodService instead? + KeyboardSwitcher.getInstance().onSizeChanged(); + } + /** * Attaches a keyboard to this view. The keyboard can be switched at any time and the * view will re-layout itself to accommodate the keyboard. @@ -497,23 +477,27 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { */ public void setKeyboard(Keyboard keyboard) { if (mKeyboard != null) { - dismissKeyPreview(); + dismissAllKeyPreviews(); } // Remove any pending messages, except dismissing preview mHandler.cancelKeyTimers(); - mHandler.cancelPopupPreview(); + mHandler.cancelAllShowKeyPreviews(); mKeyboard = keyboard; LatinImeLogger.onSetKeyboard(keyboard); - mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), + mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); for (PointerTracker tracker : mPointerTrackers) { - tracker.setKeyboard(keyboard, mKeys, mKeyHysteresisDistance); + tracker.setKeyboard(keyboard, mKeyHysteresisDistance); } requestLayout(); mKeyboardChanged = true; invalidateAllKeys(); - mKeyDetector.setProximityThreshold(KeyDetector.getMostCommonKeyWidth(keyboard)); - mMiniKeyboardCache.clear(); + mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth()); + mPopupPanelCache.clear(); + final int keyHeight = keyboard.getRowHeight() - keyboard.getVerticalGap(); + mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio); + mLabelTextSize = (int)(keyHeight * mLabelTextRatio); + mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio); } /** @@ -535,56 +519,30 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } /** - * Enables or disables accessibility. - * @param accessibilityEnabled whether or not to enable accessibility - */ - public void setAccessibilityEnabled(boolean accessibilityEnabled) { - mIsAccessibilityEnabled = accessibilityEnabled; - - // Propagate this change to all existing pointer trackers. - for (PointerTracker tracker : mPointerTrackers) { - tracker.setAccessibilityEnabled(accessibilityEnabled); - } - } - - /** - * Returns whether the device has accessibility enabled. - * @return true if the device has accessibility enabled. - */ - @Override - public boolean isAccessibilityEnabled() { - return mIsAccessibilityEnabled; - } - - /** * Enables or disables the key feedback popup. This is a popup that shows a magnified * version of the depressed key. By default the preview is enabled. - * @param previewEnabled whether or not to enable the key feedback popup - * @see #isPreviewEnabled() + * @param previewEnabled whether or not to enable the key feedback preview + * @param delay the delay after which the preview is dismissed + * @see #isKeyPreviewPopupEnabled() */ - public void setPreviewEnabled(boolean previewEnabled) { - mShowPreview = previewEnabled; + public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) { + mShowKeyPreviewPopup = previewEnabled; + mDelayAfterPreview = delay; } /** - * Returns the enabled state of the key feedback popup. - * @return whether or not the key feedback popup is enabled - * @see #setPreviewEnabled(boolean) + * Returns the enabled state of the key feedback preview + * @return whether or not the key feedback preview is enabled + * @see #setKeyPreviewPopupEnabled(boolean, int) */ - public boolean isPreviewEnabled() { - return mShowPreview; + public boolean isKeyPreviewPopupEnabled() { + return mShowKeyPreviewPopup; } public int getColorScheme() { return mColorScheme; } - public void setPopupOffset(int x, int y) { - mPopupPreviewOffsetX = x; - mPopupPreviewOffsetY = y; - mPreviewPopup.dismiss(); - } - /** * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key * codes for adjacent keys. When disabled, only the primary key code will be @@ -650,152 +608,32 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } final Canvas canvas = mCanvas; canvas.clipRect(mDirtyRect, Op.REPLACE); + canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); if (mKeyboard == null) return; - final Paint paint = mPaint; - final Drawable keyBackground = mKeyBackground; - final Rect padding = mPadding; - final int kbdPaddingLeft = getPaddingLeft(); - final int kbdPaddingTop = getPaddingTop(); - final Key[] keys = mKeys; - final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase(); - final boolean drawSingleKey = (mInvalidatedKey != null - && mInvalidatedKeyRect.contains(mDirtyRect)); - - canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); - final int keyCount = keys.length; - for (int i = 0; i < keyCount; i++) { - final Key key = keys[i]; - if (drawSingleKey && key != mInvalidatedKey) { - continue; - } - int[] drawableState = key.getCurrentDrawableState(); - keyBackground.setState(drawableState); - - // Switch the character to uppercase if shift is pressed - String label = key.mLabel == null? null : adjustCase(key.mLabel).toString(); - - final Rect bounds = keyBackground.getBounds(); - if (key.mWidth != bounds.right || key.mHeight != bounds.bottom) { - keyBackground.setBounds(0, 0, key.mWidth, key.mHeight); - } - canvas.translate(key.mX + kbdPaddingLeft, key.mY + kbdPaddingTop); - keyBackground.draw(canvas); - - final int rowHeight = padding.top + key.mHeight; - // Draw key label - if (label != null) { - // For characters, use large font. For labels like "Done", use small font. - final int labelSize = getLabelSizeAndSetPaint(label, key.mLabelOption, paint); - final int labelCharHeight = getLabelCharHeight(labelSize, paint); - - // Vertical label text alignment. - final float baseline; - if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) { - baseline = key.mHeight - - + labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR; - if (DEBUG_SHOW_ALIGN) - drawHorizontalLine(canvas, (int)baseline, key.mWidth, 0xc0008000, - new Paint()); - } else { // Align center - final float centerY = (key.mHeight + padding.top - padding.bottom) / 2; - baseline = centerY - + labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER; - if (DEBUG_SHOW_ALIGN) - drawHorizontalLine(canvas, (int)baseline, key.mWidth, 0xc0008000, - new Paint()); - } - // Horizontal label text alignment - final int positionX; - if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { - positionX = mKeyLabelHorizontalPadding + padding.left; - paint.setTextAlign(Align.LEFT); - if (DEBUG_SHOW_ALIGN) - drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint()); - } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { - positionX = key.mWidth - mKeyLabelHorizontalPadding - padding.right; - paint.setTextAlign(Align.RIGHT); - if (DEBUG_SHOW_ALIGN) - drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint()); - } else { - positionX = (key.mWidth + padding.left - padding.right) / 2; - paint.setTextAlign(Align.CENTER); - if (DEBUG_SHOW_ALIGN) { - if (label.length() > 1) - drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint()); - } - } - if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) { - paint.setColor(mKeyTextColorDisabled); - } else { - paint.setColor(mKeyTextColor); - } - if (key.mEnabled) { - // Set a drop shadow for the text - paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor); - } else { - // Make label invisible - paint.setColor(Color.TRANSPARENT); - } - canvas.drawText(label, positionX, baseline, paint); - // Turn off drop shadow - paint.setShadowLayer(0, 0, 0, 0); - } - // Draw key icon - final Drawable icon = key.getIcon(); - if (key.mLabel == null && icon != null) { - final int drawableWidth = icon.getIntrinsicWidth(); - final int drawableHeight = icon.getIntrinsicHeight(); - final int drawableX; - final int drawableY = ( - key.mHeight + padding.top - padding.bottom - drawableHeight) / 2; - if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { - drawableX = padding.left + mKeyLabelHorizontalPadding; - if (DEBUG_SHOW_ALIGN) - drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint()); - } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { - drawableX = key.mWidth - padding.right - mKeyLabelHorizontalPadding - - drawableWidth; - if (DEBUG_SHOW_ALIGN) - drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight, - 0xc0808000, new Paint()); - } else { // Align center - drawableX = (key.mWidth + padding.left - padding.right - drawableWidth) / 2; - if (DEBUG_SHOW_ALIGN) - drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight, - 0xc0008080, new Paint()); - } - drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight); - if (DEBUG_SHOW_ALIGN) - drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, - 0x80c00000, new Paint()); - } - if (key.mHintIcon != null) { - final int drawableWidth = key.mWidth; - final int drawableHeight = key.mHeight; - final int drawableX = 0; - final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL; - Drawable hintIcon = (isManualTemporaryUpperCase - && key.mManualTemporaryUpperCaseHintIcon != null) - ? key.mManualTemporaryUpperCaseHintIcon : key.mHintIcon; - drawIcon(canvas, hintIcon, drawableX, drawableY, drawableWidth, drawableHeight); - if (DEBUG_SHOW_ALIGN) - drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, - 0x80c0c000, new Paint()); + if (mInvalidatedKey != null && mInvalidatedKeyRect.contains(mDirtyRect)) { + // Draw a single key. + onBufferDrawKey(canvas, mInvalidatedKey); + } else { + // Draw all keys. + for (final Key key : mKeyboard.getKeys()) { + onBufferDrawKey(canvas, key); } - canvas.translate(-key.mX - kbdPaddingLeft, -key.mY - kbdPaddingTop); } - // TODO: Move this function to ProximityInfo for getting rid of public declarations for + // TODO: Move this function to ProximityInfo for getting rid of + // public declarations for // GRID_WIDTH and GRID_HEIGHT if (DEBUG_KEYBOARD_GRID) { Paint p = new Paint(); p.setStyle(Paint.Style.STROKE); p.setStrokeWidth(1.0f); p.setColor(0x800000c0); - int cw = (mKeyboard.getMinWidth() + mKeyboard.GRID_WIDTH - 1) / mKeyboard.GRID_WIDTH; - int ch = (mKeyboard.getHeight() + mKeyboard.GRID_HEIGHT - 1) / mKeyboard.GRID_HEIGHT; + int cw = (mKeyboard.getMinWidth() + mKeyboard.GRID_WIDTH - 1) + / mKeyboard.GRID_WIDTH; + int ch = (mKeyboard.getHeight() + mKeyboard.GRID_HEIGHT - 1) + / mKeyboard.GRID_HEIGHT; for (int i = 0; i <= mKeyboard.GRID_WIDTH; i++) canvas.drawLine(i * cw, 0, i * cw, ch * mKeyboard.GRID_HEIGHT, p); for (int i = 0; i <= mKeyboard.GRID_HEIGHT; i++) @@ -803,9 +641,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } // Overlay a dark rectangle to dim the keyboard - if (mMiniKeyboardView != null) { - paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24); - canvas.drawRect(0, 0, width, height, paint); + if (mPopupMiniKeyboardPanel != null) { + mPaint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24); + canvas.drawRect(0, 0, width, height, mPaint); } mInvalidatedKey = null; @@ -813,6 +651,134 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mDirtyRect.setEmpty(); } + private void onBufferDrawKey(final Canvas canvas, final Key key) { + final Paint paint = mPaint; + final Drawable keyBackground = mKeyBackground; + final Rect padding = mPadding; + final int kbdPaddingLeft = getPaddingLeft(); + final int kbdPaddingTop = getPaddingTop(); + final int keyDrawX = key.mX + key.mVisualInsetsLeft; + final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight; + final int rowHeight = padding.top + key.mHeight; + final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase(); + + canvas.translate(keyDrawX + kbdPaddingLeft, key.mY + kbdPaddingTop); + + // Draw key background. + final int[] drawableState = key.getCurrentDrawableState(); + keyBackground.setState(drawableState); + final Rect bounds = keyBackground.getBounds(); + if (keyDrawWidth != bounds.right || key.mHeight != bounds.bottom) { + keyBackground.setBounds(0, 0, keyDrawWidth, key.mHeight); + } + keyBackground.draw(canvas); + + // Draw key label. + if (key.mLabel != null) { + // Switch the character to uppercase if shift is pressed + final String label = key.mLabel == null ? null : adjustCase(key.mLabel).toString(); + // For characters, use large font. For labels like "Done", use small font. + final int labelSize = getLabelSizeAndSetPaint(label, key.mLabelOption, paint); + final int labelCharHeight = getLabelCharHeight(labelSize, paint); + + // Vertical label text alignment. + final float baseline; + if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) { + baseline = key.mHeight - labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR; + if (DEBUG_SHOW_ALIGN) + drawHorizontalLine(canvas, (int)baseline, keyDrawWidth, 0xc0008000, + new Paint()); + } else { // Align center + final float centerY = (key.mHeight + padding.top - padding.bottom) / 2; + baseline = centerY + labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER; + if (DEBUG_SHOW_ALIGN) + drawHorizontalLine(canvas, (int)baseline, keyDrawWidth, 0xc0008000, + new Paint()); + } + // Horizontal label text alignment + final int positionX; + if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { + positionX = mKeyLabelHorizontalPadding + padding.left; + paint.setTextAlign(Align.LEFT); + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint()); + } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { + positionX = keyDrawWidth - mKeyLabelHorizontalPadding - padding.right; + paint.setTextAlign(Align.RIGHT); + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint()); + } else { + positionX = (keyDrawWidth + padding.left - padding.right) / 2; + paint.setTextAlign(Align.CENTER); + if (DEBUG_SHOW_ALIGN) { + if (label.length() > 1) + drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint()); + } + } + if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) { + paint.setColor(mKeyTextColorDisabled); + } else { + paint.setColor(mKeyTextColor); + } + if (key.mEnabled) { + // Set a drop shadow for the text + paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor); + } else { + // Make label invisible + paint.setColor(Color.TRANSPARENT); + } + canvas.drawText(label, positionX, baseline, paint); + // Turn off drop shadow + paint.setShadowLayer(0, 0, 0, 0); + } + + // Draw key icon. + final Drawable icon = key.getIcon(); + if (key.mLabel == null && icon != null) { + final int drawableWidth = icon.getIntrinsicWidth(); + final int drawableHeight = icon.getIntrinsicHeight(); + final int drawableX; + final int drawableY = (key.mHeight + padding.top - padding.bottom - drawableHeight) / 2; + if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { + drawableX = padding.left + mKeyLabelHorizontalPadding; + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint()); + } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { + drawableX = keyDrawWidth - padding.right - mKeyLabelHorizontalPadding + - drawableWidth; + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight, + 0xc0808000, new Paint()); + } else { // Align center + drawableX = (keyDrawWidth + padding.left - padding.right - drawableWidth) / 2; + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight, + 0xc0008080, new Paint()); + } + drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight); + if (DEBUG_SHOW_ALIGN) + drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, + 0x80c00000, new Paint()); + } + + // Draw hint icon. + if (key.mHintIcon != null) { + final int drawableWidth = keyDrawWidth; + final int drawableHeight = key.mHeight; + final int drawableX = 0; + final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL; + Drawable hintIcon = (isManualTemporaryUpperCase + && key.mManualTemporaryUpperCaseHintIcon != null) + ? key.mManualTemporaryUpperCaseHintIcon : key.mHintIcon; + drawIcon(canvas, hintIcon, drawableX, drawableY, drawableWidth, drawableHeight); + if (DEBUG_SHOW_ALIGN) + drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, + 0x80c0c000, new Paint()); + } + + canvas.translate(-keyDrawX - kbdPaddingLeft, -key.mY - kbdPaddingTop); + } + public int getLabelSizeAndSetPaint(CharSequence label, int keyLabelOption, Paint paint) { // For characters, use large font. For labels like "Done", use small font. final int labelSize; @@ -884,118 +850,119 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } // TODO: clean up this method. - private void dismissKeyPreview() { - for (PointerTracker tracker : mPointerTrackers) - tracker.releaseKey(); - showPreview(KeyDetector.NOT_A_KEY, null); + private void dismissAllKeyPreviews() { + for (PointerTracker tracker : mPointerTrackers) { + tracker.setReleasedKeyGraphics(); + dismissKeyPreview(tracker); + } + } + + @Override + public void showKeyPreview(int keyIndex, PointerTracker tracker) { + if (mShowKeyPreviewPopup) { + mHandler.showKeyPreview(mDelayBeforePreview, keyIndex, tracker); + } else if (mKeyboard.needSpacebarPreview(keyIndex)) { + // Show key preview (in this case, slide language switcher) without any delay. + showKey(keyIndex, tracker); + } } @Override - public void showPreview(int keyIndex, PointerTracker tracker) { - int oldKeyIndex = mOldPreviewKeyIndex; - mOldPreviewKeyIndex = keyIndex; - // 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 - // should hide the preview of the previous key. - final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null) - || (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() - && SubtypeSwitcher.getInstance().needsToDisplayLanguage() - && (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex))); - // If key changed and preview is on or the key is space (language switch is enabled) - if (oldKeyIndex != keyIndex && (mShowPreview || (hidePreviewOrShowSpaceKeyPreview))) { - if (keyIndex == KeyDetector.NOT_A_KEY) { - mHandler.cancelPopupPreview(); - mHandler.dismissPreview(mDelayAfterPreview); - } else if (tracker != null) { - mHandler.popupPreview(mDelayBeforePreview, keyIndex, tracker); + public void dismissKeyPreview(PointerTracker tracker) { + if (mShowKeyPreviewPopup) { + mHandler.cancelShowKeyPreview(tracker); + mHandler.dismissKeyPreview(mDelayAfterPreview, tracker); + } else if (mKeyboard.needSpacebarPreview(KeyDetector.NOT_A_KEY)) { + // Dismiss key preview (in this case, slide language switcher) without any delay. + mPreviewText.setVisibility(View.INVISIBLE); + } + } + + private void addKeyPreview(TextView keyPreview) { + ViewGroup placer = mPreviewPlacer; + if (placer == null) { + final FrameLayout screenContent = (FrameLayout) getRootView().findViewById( + android.R.id.content); + if (android.os.Build.VERSION.SDK_INT >= /* HONEYCOMB */11) { + placer = screenContent; + } else { + // Insert LinearLayout to be able to setMargin because pre-Honeycomb FrameLayout + // could not handle setMargin properly. + placer = new LinearLayout(getContext()); + screenContent.addView(placer); } + mPreviewPlacer = placer; + } + if (placer instanceof FrameLayout) { + // Honeycomb or later. + placer.addView(keyPreview, new FrameLayout.LayoutParams(0, 0)); + } else { + // Gingerbread or ealier. + placer.addView(keyPreview, new LinearLayout.LayoutParams(0, 0)); } } - // TODO Must fix popup preview on xlarge layout + // TODO: Introduce minimum duration for displaying key previews + // TODO: Display up to two key previews when the user presses two keys at the same time private void showKey(final int keyIndex, PointerTracker tracker) { - Key key = tracker.getKey(keyIndex); + final TextView previewText = mPreviewText; + // If the key preview has no parent view yet, add it to the ViewGroup which can place + // key preview absolutely in SoftInputWindow. + if (previewText.getParent() == null) { + addKeyPreview(previewText); + } + + final Key key = tracker.getKey(keyIndex); // If keyIndex is invalid or IME is already closed, we must not show key preview. - // Trying to show preview PopupWindow while root window is closed causes + // Trying to show key preview while root window is closed causes // WindowManager.BadTokenException. if (key == null || !mInForeground) return; + + mHandler.cancelAllDismissKeyPreviews(); + + final int keyDrawX = key.mX + key.mVisualInsetsLeft; + final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight; // What we show as preview should match what we show on key top in onBufferDraw(). if (key.mLabel != null) { // TODO Should take care of temporaryShiftLabel here. - mPreviewText.setCompoundDrawables(null, null, null, null); - mPreviewText.setText(adjustCase(tracker.getPreviewText(key))); + previewText.setCompoundDrawables(null, null, null, null); + previewText.setText(adjustCase(tracker.getPreviewText(key))); if (key.mLabel.length() > 1) { - mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize); - mPreviewText.setTypeface(Typeface.DEFAULT_BOLD); + previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize); + previewText.setTypeface(Typeface.DEFAULT_BOLD); } else { - mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge); - mPreviewText.setTypeface(mKeyLetterStyle); + previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSize); + previewText.setTypeface(mKeyLetterStyle); } } else { final Drawable previewIcon = key.getPreviewIcon(); - mPreviewText.setCompoundDrawables(null, null, null, + previewText.setCompoundDrawables(null, null, null, previewIcon != null ? previewIcon : key.getIcon()); - mPreviewText.setText(null); - } - mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.mWidth - + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); - final int popupHeight = mPreviewHeight; - LayoutParams lp = mPreviewText.getLayoutParams(); - if (lp != null) { - lp.width = popupWidth; - lp.height = popupHeight; - } - - int popupPreviewX = key.mX - (popupWidth - key.mWidth) / 2; - int popupPreviewY = key.mY - popupHeight + mPreviewOffset; - - mHandler.cancelDismissPreview(); - if (mOffsetInWindow == null) { - mOffsetInWindow = new int[2]; - getLocationInWindow(mOffsetInWindow); - mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero - mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero - int[] windowLocation = new int[2]; - getLocationOnScreen(windowLocation); - mWindowY = windowLocation[1]; + previewText.setText(null); } // Set the preview background state - mPreviewText.getBackground().setState( + previewText.getBackground().setState( key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); - popupPreviewX += mOffsetInWindow[0]; - popupPreviewY += mOffsetInWindow[1]; - - // If the popup cannot be shown above the key, put it on the side - if (popupPreviewY + mWindowY < 0) { - // If the key you're pressing is on the left side of the keyboard, show the popup on - // the right, offset by enough to see at least one key to the left/right. - if (key.mX + key.mWidth <= getWidth() / 2) { - popupPreviewX += (int) (key.mWidth * 2.5); - } else { - popupPreviewX -= (int) (key.mWidth * 2.5); - } - popupPreviewY += popupHeight; - } - try { - if (mPreviewPopup.isShowing()) { - mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight); - } else { - mPreviewPopup.setWidth(popupWidth); - mPreviewPopup.setHeight(popupHeight); - mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY, - popupPreviewX, popupPreviewY); - } - } catch (WindowManager.BadTokenException e) { - // Swallow the exception which will be happened when IME is already closed. - Log.w(TAG, "LatinIME is already closed when tried showing key preview."); - } - // Record popup preview position to display mini-keyboard later at the same positon - mPopupPreviewDisplayedY = popupPreviewY; - mPreviewText.setVisibility(VISIBLE); + previewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + final int previewWidth = Math.max(previewText.getMeasuredWidth(), keyDrawWidth + + previewText.getPaddingLeft() + previewText.getPaddingRight()); + final int previewHeight = mPreviewHeight; + getLocationInWindow(mCoordinates); + final int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + mCoordinates[0]; + final int previewY = key.mY - previewHeight + mCoordinates[1] + mPreviewOffset; + // Record key preview position to display mini-keyboard later at the same position + mKeyPreviewPopupDisplayedY = previewY; + + // Place the key preview. + // TODO: Adjust position of key previews which touch screen edges + final MarginLayoutParams lp = (MarginLayoutParams)previewText.getLayoutParams(); + lp.width = previewWidth; + lp.height = previewHeight; + lp.setMargins(previewX, previewY, 0, 0); + previewText.setVisibility(VISIBLE); } /** @@ -1022,70 +989,72 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { if (key == null) return; mInvalidatedKey = key; - mInvalidatedKeyRect.set(0, 0, key.mWidth, key.mHeight); - mInvalidatedKeyRect.offset(key.mX + getPaddingLeft(), key.mY + getPaddingTop()); + final int x = key.mX + getPaddingLeft(); + final int y = key.mY + getPaddingTop(); + mInvalidatedKeyRect.set(x, y, x + key.mWidth, y + key.mHeight); mDirtyRect.union(mInvalidatedKeyRect); onBufferDraw(); invalidate(mInvalidatedKeyRect); } - private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) { + private boolean openMiniKeyboardIfRequired(int keyIndex, PointerTracker tracker) { // Check if we have a popup layout specified first. if (mPopupLayout == 0) { return false; } - Key popupKey = tracker.getKey(keyIndex); - if (popupKey == null) + final Key parentKey = tracker.getKey(keyIndex); + if (parentKey == null) return false; - boolean result = onLongPress(popupKey, tracker); + boolean result = onLongPress(parentKey, tracker); if (result) { - dismissKeyPreview(); - mMiniKeyboardTrackerId = tracker.mPointerId; - // Mark this tracker "already processed" and remove it from the pointer queue - tracker.setAlreadyProcessed(); - mPointerQueue.remove(tracker); + dismissAllKeyPreviews(); + tracker.onLongPressed(mPointerQueue); } return result; } private void onLongPressShiftKey(PointerTracker tracker) { - tracker.setAlreadyProcessed(); - mPointerQueue.remove(tracker); + tracker.onLongPressed(mPointerQueue); mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0); } - private void onDoubleTapShiftKey(PointerTracker tracker) { + private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) { // When shift key is double tapped, the first tap is correctly processed as usual tap. And // the second tap is treated as this double tap event, so that we need not mark tracker // calling setAlreadyProcessed() nor remove the tracker from mPointerQueueueue. mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0); } - private View inflateMiniKeyboardContainer(Key popupKey) { + // This default implementation returns a popup mini keyboard panel. + // A derived class may return a language switcher popup panel, for instance. + protected PopupPanel onCreatePopupPanel(Key parentKey) { + if (parentKey.mPopupCharacters == null) + return null; + final View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null); if (container == null) throw new NullPointerException(); - final KeyboardView miniKeyboardView = - (KeyboardView)container.findViewById(R.id.KeyboardView); + final PopupMiniKeyboardView miniKeyboardView = + (PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view); miniKeyboardView.setOnKeyboardActionListener(new KeyboardActionListener() { @Override public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { mKeyboardActionListener.onCodeInput(primaryCode, keyCodes, x, y); - dismissPopupKeyboard(); + dismissMiniKeyboard(); } @Override public void onTextInput(CharSequence text) { mKeyboardActionListener.onTextInput(text); - dismissPopupKeyboard(); + dismissMiniKeyboard(); } @Override public void onCancelInput() { mKeyboardActionListener.onCancelInput(); - dismissPopupKeyboard(); + dismissMiniKeyboard(); } @Override @@ -1101,112 +1070,57 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mKeyboardActionListener.onRelease(primaryCode, withSliding); } }); - // Override default ProximityKeyDetector. - miniKeyboardView.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance); - // Remove gesture detector on mini-keyboard - miniKeyboardView.mGestureDetector = null; final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(), - popupKey, mKeyboard).build(); + parentKey, mKeyboard).build(); miniKeyboardView.setKeyboard(keyboard); - miniKeyboardView.mMiniKeyboardParent = this; container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST)); - return container; - } - - private static boolean isOneRowKeys(List<Key> keys) { - if (keys.size() == 0) return false; - final int edgeFlags = keys.get(0).mEdgeFlags; - // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows, - // does not have both top and bottom edge flags on at the same time. On the other hand, - // the first key of mini keyboard that was created with popupCharacters must have both top - // and bottom edge flags on. - // When you want to use one row mini-keyboard from xml file, make sure that the row has - // both top and bottom edge flags set. - return (edgeFlags & Keyboard.EDGE_TOP) != 0 - && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0; + return miniKeyboardView; } /** - * Called when a key is long pressed. By default this will open any popup keyboard associated - * with this key through the attributes popupLayout and popupCharacters. - * @param popupKey the key that was long pressed + * Called when a key is long pressed. By default this will open mini keyboard associated + * with this key. + * @param parentKey the key that was long pressed + * @param tracker the pointer tracker which pressed the parent key * @return true if the long press is handled, false otherwise. Subclasses should call the * method on the base class if the subclass doesn't wish to handle the call. */ - protected boolean onLongPress(Key popupKey, PointerTracker tracker) { - if (popupKey.mPopupCharacters == null) - return false; - - View container = mMiniKeyboardCache.get(popupKey); - if (container == null) { - container = inflateMiniKeyboardContainer(popupKey); - mMiniKeyboardCache.put(popupKey, container); - } - mMiniKeyboardView = (KeyboardView)container.findViewById(R.id.KeyboardView); - final MiniKeyboard miniKeyboard = (MiniKeyboard)mMiniKeyboardView.getKeyboard(); - - if (mWindowOffset == null) { - mWindowOffset = new int[2]; - getLocationInWindow(mWindowOffset); + protected boolean onLongPress(Key parentKey, PointerTracker tracker) { + PopupPanel popupPanel = mPopupPanelCache.get(parentKey); + if (popupPanel == null) { + popupPanel = onCreatePopupPanel(parentKey); + if (popupPanel == null) + return false; + mPopupPanelCache.put(parentKey, popupPanel); } - final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX() - : popupKey.mX + popupKey.mWidth / 2; - final int popupX = pointX - miniKeyboard.getDefaultCoordX() - - container.getPaddingLeft() - + getPaddingLeft() + mWindowOffset[0]; - final int popupY = popupKey.mY - mKeyboard.getVerticalGap() - - (container.getMeasuredHeight() - container.getPaddingBottom()) - + getPaddingTop() + mWindowOffset[1]; - final int x = popupX; - final int y = mShowPreview && isOneRowKeys(miniKeyboard.getKeys()) - ? mPopupPreviewDisplayedY : popupY; - - mMiniKeyboardOriginX = x + container.getPaddingLeft() - mWindowOffset[0]; - mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1]; - mMiniKeyboardView.setPopupOffset(x, y); - if (miniKeyboard.setShifted( - mKeyboard == null ? false : mKeyboard.isShiftedOrShiftLocked())) { - mMiniKeyboardView.invalidateAllKeys(); + if (mPopupWindow == null) { + mPopupWindow = new PopupWindow(getContext()); + mPopupWindow.setBackgroundDrawable(null); + mPopupWindow.setAnimationStyle(R.style.PopupMiniKeyboardAnimation); + // Allow popup window to be drawn off the screen. + mPopupWindow.setClippingEnabled(false); } - // Mini keyboard needs no pop-up key preview displayed. - mMiniKeyboardView.setPreviewEnabled(false); - mMiniKeyboardPopup.setContentView(container); - mMiniKeyboardPopup.setWidth(container.getMeasuredWidth()); - mMiniKeyboardPopup.setHeight(container.getMeasuredHeight()); - mMiniKeyboardPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y); - - // Inject down event on the key to mini keyboard. - final long eventTime = SystemClock.uptimeMillis(); - mMiniKeyboardPopupTime = eventTime; - final MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, - pointX, popupKey.mY + popupKey.mHeight / 2, eventTime); - mMiniKeyboardView.onTouchEvent(downEvent); - downEvent.recycle(); + mPopupMiniKeyboardPanel = popupPanel; + popupPanel.showPanel(this, parentKey, tracker, mKeyPreviewPopupDisplayedY, mPopupWindow); invalidateAllKeys(); return true; } - private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) { - return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action, - x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0); - } - private PointerTracker getPointerTracker(final int id) { final ArrayList<PointerTracker> pointers = mPointerTrackers; - final Key[] keys = mKeys; final KeyboardActionListener listener = mKeyboardActionListener; // Create pointer trackers until we can get 'id+1'-th tracker, if needed. for (int i = pointers.size(); i <= id; i++) { final PointerTracker tracker = - new PointerTracker(i, mHandler, mKeyDetector, this, getResources()); - if (keys != null) - tracker.setKeyboard(mKeyboard, keys, mKeyHysteresisDistance); + new PointerTracker(i, this, mHandler, mKeyDetector, this); + if (mKeyboard != null) + tracker.setKeyboard(mKeyboard, mKeyHysteresisDistance); if (listener != null) tracker.setOnKeyboardActionListener(listener); pointers.add(tracker); @@ -1216,8 +1130,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public boolean isInSlidingKeyInput() { - if (mMiniKeyboardView != null) { - return mMiniKeyboardView.isInSlidingKeyInput(); + if (mPopupMiniKeyboardPanel != null) { + return mPopupMiniKeyboardPanel.isInSlidingKeyInput(); } else { return mPointerQueue.isInSlidingKeyInput(); } @@ -1237,20 +1151,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // TODO: cleanup this code into a multi-touch to single-touch event converter class? // If the device does not have distinct multi-touch support panel, ignore all multi-touch // events except a transition from/to single-touch. - if ((!mHasDistinctMultitouch || mIsAccessibilityEnabled) - && pointerCount > 1 && oldPointerCount > 1) { + if (!mHasDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) { return true; } // Track the last few movements to look for spurious swipes. mSwipeTracker.addMovement(me); - // Gesture detector must be enabled only when mini-keyboard is not on the screen and - // accessibility is not enabled. - // TODO: Reconcile gesture detection and accessibility features. - if (mMiniKeyboardView == null && !mIsAccessibilityEnabled - && mGestureDetector != null && mGestureDetector.onTouchEvent(me)) { - dismissKeyPreview(); + // Gesture detector must be enabled only when mini-keyboard is not on the screen. + if (mPopupMiniKeyboardPanel == null && mGestureDetector != null + && mGestureDetector.onTouchEvent(me)) { + dismissAllKeyPreviews(); mHandler.cancelKeyTimers(); return true; } @@ -1261,26 +1172,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { final int x = (int)me.getX(index); final int y = (int)me.getY(index); - // Needs to be called after the gesture detector gets a turn, as it may have - // displayed the mini keyboard - if (mMiniKeyboardView != null) { - final int miniKeyboardPointerIndex = me.findPointerIndex(mMiniKeyboardTrackerId); - if (miniKeyboardPointerIndex >= 0 && miniKeyboardPointerIndex < pointerCount) { - final int miniKeyboardX = (int)me.getX(miniKeyboardPointerIndex); - final int miniKeyboardY = (int)me.getY(miniKeyboardPointerIndex); - MotionEvent translated = generateMiniKeyboardMotionEvent(action, - miniKeyboardX, miniKeyboardY, eventTime); - mMiniKeyboardView.onTouchEvent(translated); - translated.recycle(); - } - return true; + // Needs to be called after the gesture detector gets a turn, as it may have displayed the + // mini keyboard + if (mPopupMiniKeyboardPanel != null) { + return mPopupMiniKeyboardPanel.onTouchEvent(me); } if (mHandler.isInKeyRepeat()) { - // It will keep being in the key repeating mode while the key is being pressed. - if (action == MotionEvent.ACTION_MOVE) { - return true; - } final PointerTracker tracker = getPointerTracker(id); // Key repeating timer will be canceled if 2 or more keys are in action, and current // event (UP or DOWN) is non-modifier key. @@ -1293,17 +1191,26 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // TODO: cleanup this code into a multi-touch to single-touch event converter class? // Translate mutli-touch event to single-touch events on the device that has no distinct // multi-touch panel. - if (!mHasDistinctMultitouch || mIsAccessibilityEnabled) { + if (!mHasDistinctMultitouch) { // Use only main (id=0) pointer tracker. PointerTracker tracker = getPointerTracker(0); if (pointerCount == 1 && oldPointerCount == 2) { // Multi-touch to single touch transition. - // Send a down event for the latest pointer. - tracker.onDownEvent(x, y, eventTime, null); + // Send a down event for the latest pointer if the key is different from the + // previous key. + final int newKeyIndex = tracker.getKeyIndexOn(x, y); + if (mOldKeyIndex != newKeyIndex) { + tracker.onDownEvent(x, y, eventTime, null); + if (action == MotionEvent.ACTION_UP) + tracker.onUpEvent(x, y, eventTime, null); + } } else if (pointerCount == 2 && oldPointerCount == 1) { // Single-touch to multi-touch transition. // Send an up event for the last pointer. - tracker.onUpEvent(tracker.getLastX(), tracker.getLastY(), eventTime, null); + final int lastX = tracker.getLastX(); + final int lastY = tracker.getLastY(); + mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY); + tracker.onUpEvent(lastX, lastY, eventTime, null); } else if (pointerCount == 1 && oldPointerCount == 1) { tracker.onTouchEvent(action, x, y, eventTime, null); } else { @@ -1344,12 +1251,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public void closing() { - mPreviewPopup.dismiss(); + mPreviewText.setVisibility(View.GONE); mHandler.cancelAllMessages(); - dismissPopupKeyboard(); + dismissMiniKeyboard(); mDirtyRect.union(0, 0, getWidth(), getHeight()); - mMiniKeyboardCache.clear(); + mPopupPanelCache.clear(); requestLayout(); } @@ -1364,21 +1271,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { closing(); } - private void dismissPopupKeyboard() { - if (mMiniKeyboardPopup.isShowing()) { - mMiniKeyboardPopup.dismiss(); - mMiniKeyboardView = null; - mMiniKeyboardOriginX = 0; - mMiniKeyboardOriginY = 0; + private boolean dismissMiniKeyboard() { + if (mPopupWindow != null && mPopupWindow.isShowing()) { + mPopupWindow.dismiss(); + mPopupMiniKeyboardPanel = null; invalidateAllKeys(); + return true; } + return false; } public boolean handleBack() { - if (mMiniKeyboardPopup.isShowing()) { - dismissPopupKeyboard(); - return true; - } - return false; + return dismissMiniKeyboard(); } } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index 5820049bb..fe27ab412 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -26,6 +26,9 @@ import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.PorterDuff; @@ -33,41 +36,49 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import java.lang.ref.SoftReference; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Locale; // TODO: We should remove this class public class LatinKeyboard extends Keyboard { - public static final int OPACITY_FULLY_OPAQUE = 255; private static final int SPACE_LED_LENGTH_PERCENT = 80; + public static final int CODE_NEXT_LANGUAGE = -100; + public static final int CODE_PREV_LANGUAGE = -101; + private final Context mContext; + private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance(); /* Space key and its icons, drawables and colors. */ private final Key mSpaceKey; private final Drawable mSpaceIcon; private final Drawable mSpacePreviewIcon; - private final int[] mSpaceKeyIndexArray; + private final int mSpaceKeyIndex; private final Drawable mSpaceAutoCorrectionIndicator; private final Drawable mButtonArrowLeftIcon; private final Drawable mButtonArrowRightIcon; private final int mSpacebarTextColor; private final int mSpacebarTextShadowColor; - private final int mSpacebarVerticalCorrection; private float mSpacebarTextFadeFactor = 0.0f; - private int mSpaceDragStartX; - private int mSpaceDragLastDiff; - private boolean mCurrentlyInSpace; + private final int mSpacebarLanguageSwitchThreshold; + private int mSpacebarSlidingLanguageSwitchDiff; private SlidingLocaleDrawable mSlidingLocaleIcon; + private final HashMap<Integer, SoftReference<BitmapDrawable>> mSpaceDrawableCache = + new HashMap<Integer, SoftReference<BitmapDrawable>>(); /* Shortcut key and its icons if available */ private final Key mShortcutKey; private final Drawable mEnabledShortcutIcon; private final Drawable mDisabledShortcutIcon; - private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f; - // Minimum width of space key preview (proportional to keyboard width) - private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f; + // Minimum width of spacebar dragging to trigger the language switch (represented by the number + // of the most common key width of this keyboard). + private static final int SPACEBAR_DRAG_WIDTH = 3; + // Minimum width of space key preview (proportional to keyboard width). + private static final float SPACEBAR_POPUP_MIN_RATIO = 0.5f; // Height in space key the language name will be drawn. (proportional to space key height) public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; // If the full language name needs to be smaller than this value to be drawn on space key, @@ -77,8 +88,8 @@ public class LatinKeyboard extends Keyboard { private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small"; private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium"; - public LatinKeyboard(Context context, KeyboardId id) { - super(context, id.getXmlId(), id); + public LatinKeyboard(Context context, KeyboardId id, int width) { + super(context, id.getXmlId(), id, width); final Resources res = context.getResources(); mContext = context; @@ -92,7 +103,7 @@ public class LatinKeyboard extends Keyboard { case CODE_SPACE: spaceKeyIndex = index; break; - case CODE_VOICE: + case CODE_SHORTCUT: shortcutKeyIndex = index; break; } @@ -102,7 +113,7 @@ public class LatinKeyboard extends Keyboard { mSpaceKey = (spaceKeyIndex >= 0) ? keys.get(spaceKeyIndex) : null; mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null; mSpacePreviewIcon = (mSpaceKey != null) ? mSpaceKey.getPreviewIcon() : null; - mSpaceKeyIndexArray = new int[] { spaceKeyIndex }; + mSpaceKeyIndex = spaceKeyIndex; mShortcutKey = (shortcutKeyIndex >= 0) ? keys.get(shortcutKeyIndex) : null; mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null; @@ -120,8 +131,8 @@ public class LatinKeyboard extends Keyboard { mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led); mButtonArrowLeftIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_left); mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right); - mSpacebarVerticalCorrection = res.getDimensionPixelOffset( - R.dimen.spacebar_vertical_correction); + // The threshold is "key width" x 1.25 + mSpacebarLanguageSwitchThreshold = (getMostCommonKeyWidth() * 5) / 4; } public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) { @@ -137,6 +148,12 @@ public class LatinKeyboard extends Keyboard { return newColor; } + private static ColorFilter getSpacebarDrawableFilter(float fadeFactor) { + final ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.setScale(1, 1, 1, fadeFactor); + return new ColorMatrixColorFilter(colorMatrix); + } + public void updateShortcutKey(boolean available, LatinKeyboardView view) { if (mShortcutKey == null) return; @@ -157,19 +174,14 @@ public class LatinKeyboard extends Keyboard { private void updateSpacebarForLocale(boolean isAutoCorrection) { if (mSpaceKey == null) return; - final Resources res = mContext.getResources(); // If application locales are explicitly selected. - if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) { - mSpaceKey.setIcon(new BitmapDrawable(res, - drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); + if (mSubtypeSwitcher.needsToDisplayLanguage()) { + mSpaceKey.setIcon(getSpaceDrawable( + mSubtypeSwitcher.getInputLocale(), isAutoCorrection)); + } else if (isAutoCorrection) { + mSpaceKey.setIcon(getSpaceDrawable(null, true)); } else { - // sym_keyboard_space_led can be shared with Black and White symbol themes. - if (isAutoCorrection) { - mSpaceKey.setIcon(new BitmapDrawable(res, - drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); - } else { - mSpaceKey.setIcon(mSpaceIcon); - } + mSpaceKey.setIcon(mSpaceIcon); } } @@ -182,8 +194,7 @@ public class LatinKeyboard extends Keyboard { // Layout local language name and left and right arrow on spacebar. private static String layoutSpacebar(Paint paint, Locale locale, Drawable lArrow, - Drawable rArrow, int width, int height, float origTextSize, - boolean allowVariableTextSize) { + Drawable rArrow, int width, int height, float origTextSize) { final float arrowWidth = lArrow.getIntrinsicWidth(); final float arrowHeight = lArrow.getIntrinsicHeight(); final float maxTextWidth = width - (arrowWidth + arrowWidth); @@ -194,17 +205,23 @@ public class LatinKeyboard extends Keyboard { int textWidth = getTextWidth(paint, language, origTextSize, bounds); // Assuming text width and text size are proportional to each other. float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); + // allow variable text size + textWidth = getTextWidth(paint, language, textSize, bounds); + // If text size goes too small or text does not fit, use middle or short name + final boolean useMiddleName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) + || (textWidth > maxTextWidth); final boolean useShortName; - if (allowVariableTextSize) { - textWidth = getTextWidth(paint, language, textSize, bounds); - // If text size goes too small or text does not fit, use short name - useShortName = textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME - || textWidth > maxTextWidth; + if (useMiddleName) { + language = SubtypeSwitcher.getMiddleDisplayLanguage(locale); + textWidth = getTextWidth(paint, language, origTextSize, bounds); + textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); + useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) + || (textWidth > maxTextWidth); } else { - useShortName = textWidth > maxTextWidth; - textSize = origTextSize; + useShortName = false; } + if (useShortName) { language = SubtypeSwitcher.getShortDisplayLanguage(locale); textWidth = getTextWidth(paint, language, origTextSize, bounds); @@ -223,19 +240,31 @@ public class LatinKeyboard extends Keyboard { return language; } - private Bitmap drawSpacebar(int opacity, boolean isAutoCorrection) { + private BitmapDrawable getSpaceDrawable(Locale locale, boolean isAutoCorrection) { + final Integer hashCode = Arrays.hashCode( + new Object[] { locale, isAutoCorrection, mSpacebarTextFadeFactor }); + final SoftReference<BitmapDrawable> ref = mSpaceDrawableCache.get(hashCode); + BitmapDrawable drawable = (ref == null) ? null : ref.get(); + if (drawable == null) { + drawable = new BitmapDrawable(mContext.getResources(), drawSpacebar( + locale, isAutoCorrection, mSpacebarTextFadeFactor)); + mSpaceDrawableCache.put(hashCode, new SoftReference<BitmapDrawable>(drawable)); + } + return drawable; + } + + private Bitmap drawSpacebar(Locale inputLocale, boolean isAutoCorrection, + float textFadeFactor) { final int width = mSpaceKey.mWidth; final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight; final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(buffer); final Resources res = mContext.getResources(); - canvas.drawColor(res.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR); + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance(); // If application locales are explicitly selected. - if (subtypeSwitcher.needsToDisplayLanguage()) { + if (inputLocale != null) { final Paint paint = new Paint(); - paint.setAlpha(opacity); paint.setAntiAlias(true); paint.setTextAlign(Align.CENTER); @@ -252,11 +281,9 @@ public class LatinKeyboard extends Keyboard { defaultTextSize = 14; } - final boolean allowVariableTextSize = true; - final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(), + final String language = layoutSpacebar(paint, inputLocale, mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height, - getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize), - allowVariableTextSize); + getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize)); // Draw language text with shadow // In case there is no space icon, we will place the language text at the center of @@ -265,14 +292,19 @@ public class LatinKeyboard extends Keyboard { final float textHeight = -paint.ascent() + descent; final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE : height / 2 + textHeight / 2; - paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor)); + paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor)); canvas.drawText(language, width / 2, baseline - descent - 1, paint); - paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor)); + paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor)); canvas.drawText(language, width / 2, baseline - descent, paint); - // Put arrows that are already layed out on either side of the text - if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() - && subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { + // Put arrows that are already laid out on either side of the text + // Because language switch is disabled on phone and number layouts, hide arrows. + // TODO: Sort out how to enable language switch on these layouts. + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher() + && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1 + && !(isPhoneKeyboard() || isNumberKeyboard())) { + mButtonArrowLeftIcon.setColorFilter(getSpacebarDrawableFilter(textFadeFactor)); + mButtonArrowRightIcon.setColorFilter(getSpacebarDrawableFilter(textFadeFactor)); mButtonArrowLeftIcon.draw(canvas); mButtonArrowRightIcon.draw(canvas); } @@ -297,7 +329,14 @@ public class LatinKeyboard extends Keyboard { return buffer; } - private void updateLocaleDrag(int diff) { + public void setSpacebarSlidingLanguageSwitchDiff(int diff) { + mSpacebarSlidingLanguageSwitchDiff = diff; + } + + public void updateSpacebarPreviewIcon(int diff) { + if (mSpacebarSlidingLanguageSwitchDiff == diff) + return; + mSpacebarSlidingLanguageSwitchDiff = diff; if (mSlidingLocaleIcon == null) { final int width = Math.max(mSpaceKey.mWidth, (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO)); @@ -305,7 +344,6 @@ public class LatinKeyboard extends Keyboard { mSlidingLocaleIcon = new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height); mSlidingLocaleIcon.setBounds(0, 0, width, height); - mSpaceKey.setPreviewIcon(mSlidingLocaleIcon); } mSlidingLocaleIcon.setDiff(diff); if (Math.abs(diff) == Integer.MAX_VALUE) { @@ -316,69 +354,49 @@ public class LatinKeyboard extends Keyboard { mSpaceKey.getPreviewIcon().invalidateSelf(); } - public int getLanguageChangeDirection() { - if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1 - || Math.abs(mSpaceDragLastDiff) < mSpaceKey.mWidth * SPACEBAR_DRAG_THRESHOLD) { - return 0; // No change - } - return mSpaceDragLastDiff > 0 ? 1 : -1; - } - - public void keyReleased() { - mCurrentlyInSpace = false; - mSpaceDragLastDiff = 0; - if (mSpaceKey != null) { - updateLocaleDrag(Integer.MAX_VALUE); - } + public boolean shouldTriggerSpacebarSlidingLanguageSwitch(int diff) { + // On phone and number layouts, sliding language switch is disabled. + // TODO: Sort out how to enable language switch on these layouts. + if (isPhoneKeyboard() || isNumberKeyboard()) + return false; + return Math.abs(diff) > mSpacebarLanguageSwitchThreshold; } /** - * Does the magic of locking the touch gesture into the spacebar when - * switching input languages. + * Return true if spacebar needs showing preview even when "popup on keypress" is off. + * @param keyIndex index of the pressing key + * @return true if spacebar needs showing preview */ @Override - public boolean isInside(Key key, int pointX, int pointY) { - int x = pointX; - int y = pointY; - final int code = key.mCode; - if (code == CODE_SPACE) { - y += mSpacebarVerticalCorrection; - if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() - && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) { - if (mCurrentlyInSpace) { - int diff = x - mSpaceDragStartX; - if (Math.abs(diff - mSpaceDragLastDiff) > 0) { - updateLocaleDrag(diff); - } - mSpaceDragLastDiff = diff; - return true; - } else { - boolean isOnSpace = key.isOnKey(x, y); - if (isOnSpace) { - mCurrentlyInSpace = true; - mSpaceDragStartX = x; - updateLocaleDrag(0); - } - return isOnSpace; - } - } - } - - // Lock into the spacebar - if (mCurrentlyInSpace) return false; + public boolean needSpacebarPreview(int keyIndex) { + // This method is called when "popup on keypress" is off. + if (!mSubtypeSwitcher.useSpacebarLanguageSwitcher()) + return false; + // Dismiss key preview. + if (keyIndex == KeyDetector.NOT_A_KEY) + return true; + // Key is not a spacebar. + if (keyIndex != mSpaceKeyIndex) + return false; + // The language switcher will be displayed only when the dragging distance is greater + // than the threshold. + return shouldTriggerSpacebarSlidingLanguageSwitch(mSpacebarSlidingLanguageSwitchDiff); + } - return key.isOnKey(x, y); + public int getLanguageChangeDirection() { + if (mSpaceKey == null || mSubtypeSwitcher.getEnabledKeyboardLocaleCount() <= 1 + || Math.abs(mSpacebarSlidingLanguageSwitchDiff) + < getMostCommonKeyWidth() * SPACEBAR_DRAG_WIDTH) { + return 0; // No change + } + return mSpacebarSlidingLanguageSwitchDiff > 0 ? 1 : -1; } @Override public int[] getNearestKeys(int x, int y) { - if (mCurrentlyInSpace) { - return mSpaceKeyIndexArray; - } else { - // Avoid dead pixels at edges of the keyboard - return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)), - Math.max(0, Math.min(y, getHeight() - 1))); - } + // Avoid dead pixels at edges of the keyboard + return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)), + Math.max(0, Math.min(y, getHeight() - 1))); } private static int getTextSizeFromTheme(Theme theme, int style, int defValue) { diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 77e9caecc..583b997ee 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -16,9 +16,9 @@ package com.android.inputmethod.keyboard; +import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.Utils; -import com.android.inputmethod.voice.VoiceIMEConnector; import android.content.Context; import android.graphics.Canvas; @@ -55,24 +55,19 @@ public class LatinKeyboardView extends KeyboardView { } @Override - public void setPreviewEnabled(boolean previewEnabled) { + public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) { LatinKeyboard latinKeyboard = getLatinKeyboard(); if (latinKeyboard != null && (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard())) { // Phone and number keyboard never shows popup preview (except language switch). - super.setPreviewEnabled(false); + super.setKeyPreviewPopupEnabled(false, delay); } else { - super.setPreviewEnabled(previewEnabled); + super.setKeyPreviewPopupEnabled(previewEnabled, delay); } } @Override public void setKeyboard(Keyboard newKeyboard) { - final LatinKeyboard oldKeyboard = getLatinKeyboard(); - if (oldKeyboard != null) { - // Reset old keyboard state before switching to new keyboard. - oldKeyboard.keyReleased(); - } super.setKeyboard(newKeyboard); // One-seventh of the keyboard width seems like a reasonable threshold mJumpThresholdSquare = newKeyboard.getMinWidth() / 7; @@ -145,10 +140,6 @@ public class LatinKeyboardView extends KeyboardView { // If device has distinct multi touch panel, there is no need to check sudden jump. if (hasDistinctMultitouch()) return false; - // If accessibiliy is enabled, stop looking for sudden jumps because it interferes - // with touch exploration of the keyboard. - if (isAccessibilityEnabled()) - return false; final int action = me.getAction(); final int x = (int) me.getX(); final int y = (int) me.getY(); @@ -182,7 +173,8 @@ public class LatinKeyboardView extends KeyboardView { if (!mDroppingEvents) { mDroppingEvents = true; // Send an up event - MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(), + MotionEvent translated = MotionEvent.obtain( + me.getEventTime(), me.getEventTime(), MotionEvent.ACTION_UP, mLastX, mLastY, me.getMetaState()); super.onTouchEvent(translated); @@ -216,8 +208,7 @@ public class LatinKeyboardView extends KeyboardView { @Override public boolean onTouchEvent(MotionEvent me) { - LatinKeyboard keyboard = getLatinKeyboard(); - if (keyboard == null) return true; + if (getLatinKeyboard() == null) return true; // If there was a sudden jump, return without processing the actual motion event. if (handleSuddenJump(me)) { @@ -226,24 +217,6 @@ public class LatinKeyboardView extends KeyboardView { return true; } - // Reset any bounding box controls in the keyboard - if (me.getAction() == MotionEvent.ACTION_DOWN) { - keyboard.keyReleased(); - } - - if (me.getAction() == MotionEvent.ACTION_UP) { - int languageDirection = keyboard.getLanguageChangeDirection(); - if (languageDirection != 0) { - getOnKeyboardActionListener().onCodeInput( - languageDirection == 1 - ? Keyboard.CODE_NEXT_LANGUAGE : Keyboard.CODE_PREV_LANGUAGE, - null, mLastX, mLastY); - me.setAction(MotionEvent.ACTION_CANCEL); - keyboard.keyReleased(); - return super.onTouchEvent(me); - } - } - return super.onTouchEvent(me); } @@ -264,6 +237,6 @@ public class LatinKeyboardView extends KeyboardView { @Override protected void onAttachedToWindow() { // Token is available from here. - VoiceIMEConnector.getInstance().onAttachedToWindow(); + VoiceProxy.getInstance().onAttachedToWindow(); } } diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java index a45aaa4c6..2d6766f2d 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java @@ -18,11 +18,13 @@ package com.android.inputmethod.keyboard; import android.content.Context; +import java.util.List; + public class MiniKeyboard extends Keyboard { private int mDefaultKeyCoordX; - public MiniKeyboard(Context context, int xmlLayoutResId, KeyboardId id) { - super(context, xmlLayoutResId, id); + public MiniKeyboard(Context context, int xmlLayoutResId, Keyboard parentKeyboard) { + super(context, xmlLayoutResId, null, parentKeyboard.getMinWidth()); } public void setDefaultCoordX(int pos) { @@ -32,4 +34,19 @@ public class MiniKeyboard extends Keyboard { public int getDefaultCoordX() { return mDefaultKeyCoordX; } + + public boolean isOneRowKeyboard() { + final List<Key> keys = getKeys(); + if (keys.size() == 0) return false; + final int edgeFlags = keys.get(0).mEdgeFlags; + // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows, + // does not have both top and bottom edge flags on at the same time. On the other hand, + // the first key of mini keyboard that was created with popupCharacters must have both top + // and bottom edge flags on. + // When you want to use one row mini-keyboard from xml file, make sure that the row has + // both top and bottom edge flags set. + return (edgeFlags & Keyboard.EDGE_TOP) != 0 + && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0; + + } } diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java index 765750fbe..6e939123d 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java @@ -185,7 +185,8 @@ public class MiniKeyboardBuilder { Keyboard parentKeyboard) { final Context context = view.getContext(); mRes = context.getResources(); - final MiniKeyboard keyboard = new MiniKeyboard(context, layoutTemplateResId, null); + final MiniKeyboard keyboard = new MiniKeyboard( + context, layoutTemplateResId, parentKeyboard); mKeyboard = keyboard; mPopupCharacters = parentKey.mPopupCharacters; diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java index 1243f6f37..cc5c3bbfe 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java @@ -16,9 +16,9 @@ package com.android.inputmethod.keyboard; -public class MiniKeyboardKeyDetector extends KeyDetector { - private static final int MAX_NEARBY_KEYS = 1; +import java.util.List; +public class MiniKeyboardKeyDetector extends KeyDetector { private final int mSlideAllowanceSquare; private final int mSlideAllowanceSquareTop; @@ -31,20 +31,21 @@ public class MiniKeyboardKeyDetector extends KeyDetector { @Override protected int getMaxNearbyKeys() { - return MAX_NEARBY_KEYS; + // No nearby key will be returned. + return 1; } @Override public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) { - final Key[] keys = getKeys(); + final List<Key> keys = getKeys(); final int touchX = getTouchX(x); final int touchY = getTouchY(y); int nearestIndex = NOT_A_KEY; int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare; - final int keyCount = keys.length; + final int keyCount = keys.size(); for (int index = 0; index < keyCount; index++) { - final int dist = keys[index].squaredDistanceToEdge(touchX, touchY); + final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY); if (dist < nearestDist) { nearestIndex = index; nearestDist = dist; @@ -52,7 +53,7 @@ public class MiniKeyboardKeyDetector extends KeyDetector { } if (allCodes != null && nearestIndex != NOT_A_KEY) - allCodes[0] = keys[nearestIndex].mCode; + allCodes[0] = keys.get(nearestIndex).mCode; return nearestIndex; } } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 4b3fe8b8b..a489245aa 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -19,12 +19,14 @@ package com.android.inputmethod.keyboard; import com.android.inputmethod.keyboard.KeyboardView.UIHandler; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; import android.content.res.Resources; import android.util.Log; import android.view.MotionEvent; import java.util.Arrays; +import java.util.List; public class PointerTracker { private static final String TAG = PointerTracker.class.getSimpleName(); @@ -36,9 +38,9 @@ public class PointerTracker { public interface UIProxy { public void invalidateKey(Key key); - public void showPreview(int keyIndex, PointerTracker tracker); + public void showKeyPreview(int keyIndex, PointerTracker tracker); + public void dismissKeyPreview(PointerTracker tracker); public boolean hasDistinctMultitouch(); - public boolean isAccessibilityEnabled(); } public final int mPointerId; @@ -48,9 +50,7 @@ public class PointerTracker { private final int mLongPressKeyTimeout; private final int mLongPressShiftKeyTimeout; - // Miscellaneous constants - private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY; - + private final KeyboardView mKeyboardView; private final UIProxy mProxy; private final UIHandler mHandler; private final KeyDetector mKeyDetector; @@ -63,15 +63,12 @@ public class PointerTracker { private final int mTouchNoiseThresholdDistanceSquared; private Keyboard mKeyboard; - private Key[] mKeys; + private List<Key> mKeys; private int mKeyHysteresisDistanceSquared = -1; private int mKeyQuarterWidthSquared; private final PointerTrackerKeyState mKeyState; - // true if accessibility is enabled in the parent keyboard - private boolean mIsAccessibilityEnabled; - // true if keyboard layout has been changed. private boolean mKeyboardLayoutHasBeenChanged; @@ -87,8 +84,14 @@ public class PointerTracker { // true if sliding key is allowed. private boolean mIsAllowedSlidingKeyInput; - // pressed key - private int mPreviousKey = NOT_A_KEY; + // ignore modifier key if true + private boolean mIgnoreModifierKey; + + // TODO: Remove these hacking variables + // true if this pointer is in sliding language switch + private boolean mIsInSlidingLanguageSwitch; + private int mSpaceKeyIndex; + private final SubtypeSwitcher mSubtypeSwitcher; // Empty {@link KeyboardActionListener} private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener() { @@ -106,18 +109,19 @@ public class PointerTracker { public void onSwipeDown() {} }; - public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy, - Resources res) { + public PointerTracker(int id, KeyboardView keyboardView, UIHandler handler, + KeyDetector keyDetector, UIProxy proxy) { if (proxy == null || handler == null || keyDetector == null) throw new NullPointerException(); mPointerId = id; + mKeyboardView = keyboardView; mProxy = proxy; mHandler = handler; mKeyDetector = keyDetector; mKeyboardSwitcher = KeyboardSwitcher.getInstance(); mKeyState = new PointerTrackerKeyState(keyDetector); - mIsAccessibilityEnabled = proxy.isAccessibilityEnabled(); mHasDistinctMultitouch = proxy.hasDistinctMultitouch(); + final Resources res = mKeyboardView.getResources(); mConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled); mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start); mLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout); @@ -127,20 +131,21 @@ public class PointerTracker { R.dimen.config_touch_noise_threshold_distance); mTouchNoiseThresholdDistanceSquared = (int)( touchNoiseThresholdDistance * touchNoiseThresholdDistance); + mSubtypeSwitcher = SubtypeSwitcher.getInstance(); } public void setOnKeyboardActionListener(KeyboardActionListener listener) { mListener = listener; } - public void setAccessibilityEnabled(boolean accessibilityEnabled) { - mIsAccessibilityEnabled = accessibilityEnabled; - } - // Returns true if keyboard has been changed by this callback. private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key, boolean withSliding) { + final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode); if (DEBUG_LISTENER) - Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding); + Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding + + " ignoreModifier=" + ignoreModifierKey); + if (ignoreModifierKey) + return false; if (key.mEnabled) { mListener.onPress(key.mCode, withSliding); final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; @@ -153,9 +158,13 @@ public class PointerTracker { // Note that we need primaryCode argument because the keyboard may in shifted state and the // primaryCode is different from {@link Key#mCode}. private void callListenerOnCodeInput(Key key, int primaryCode, int[] keyCodes, int x, int y) { + final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode); if (DEBUG_LISTENER) Log.d(TAG, "onCodeInput: " + keyCodePrintable(primaryCode) - + " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y); + + " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y + + " ignoreModifier=" + ignoreModifierKey); + if (ignoreModifierKey) + return; if (key.mEnabled) mListener.onCodeInput(primaryCode, keyCodes, x, y); } @@ -170,8 +179,12 @@ public class PointerTracker { // Note that we need primaryCode argument because the keyboard may in shifted state and the // primaryCode is different from {@link Key#mCode}. private void callListenerOnRelease(Key key, int primaryCode, boolean withSliding) { + final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode); if (DEBUG_LISTENER) - Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding=" + withSliding); + Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding=" + + withSliding + " ignoreModifier=" + ignoreModifierKey); + if (ignoreModifierKey) + return; if (key.mEnabled) mListener.onRelease(primaryCode, withSliding); } @@ -182,11 +195,11 @@ public class PointerTracker { mListener.onCancelInput(); } - public void setKeyboard(Keyboard keyboard, Key[] keys, float keyHysteresisDistance) { - if (keyboard == null || keys == null || keyHysteresisDistance < 0) + public void setKeyboard(Keyboard keyboard, float keyHysteresisDistance) { + if (keyboard == null || keyHysteresisDistance < 0) throw new IllegalArgumentException(); mKeyboard = keyboard; - mKeys = keys; + mKeys = keyboard.getKeys(); mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); final int keyQuarterWidth = keyboard.getKeyWidth() / 4; mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth; @@ -199,11 +212,11 @@ public class PointerTracker { } private boolean isValidKeyIndex(int keyIndex) { - return keyIndex >= 0 && keyIndex < mKeys.length; + return keyIndex >= 0 && keyIndex < mKeys.size(); } public Key getKey(int keyIndex) { - return isValidKeyIndex(keyIndex) ? mKeys[keyIndex] : null; + return isValidKeyIndex(keyIndex) ? mKeys.get(keyIndex) : null; } private static boolean isModifierCode(int primaryCode) { @@ -229,34 +242,33 @@ public class PointerTracker { return key != null && key.mCode == Keyboard.CODE_SHIFT; } + public int getKeyIndexOn(int x, int y) { + return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null); + } + public boolean isSpaceKey(int keyIndex) { Key key = getKey(keyIndex); return key != null && key.mCode == Keyboard.CODE_SPACE; } - public void releaseKey() { - updateKeyGraphics(NOT_A_KEY); + public void setReleasedKeyGraphics() { + setReleasedKeyGraphics(mKeyState.getKeyIndex()); } - private void updateKeyGraphics(int keyIndex) { - int oldKeyIndex = mPreviousKey; - mPreviousKey = keyIndex; - if (keyIndex != oldKeyIndex) { - if (isValidKeyIndex(oldKeyIndex)) { - // if new key index is not a key, old key was just released inside of the key. - final boolean inside = (keyIndex == NOT_A_KEY); - mKeys[oldKeyIndex].onReleased(inside); - mProxy.invalidateKey(mKeys[oldKeyIndex]); - } - if (isValidKeyIndex(keyIndex)) { - mKeys[keyIndex].onPressed(); - mProxy.invalidateKey(mKeys[keyIndex]); - } + private void setReleasedKeyGraphics(int keyIndex) { + final Key key = getKey(keyIndex); + if (key != null) { + key.onReleased(); + mProxy.invalidateKey(key); } } - public void setAlreadyProcessed() { - mKeyAlreadyProcessed = true; + private void setPressedKeyGraphics(int keyIndex) { + final Key key = getKey(keyIndex); + if (key != null && key.mEnabled) { + key.onPressed(); + mProxy.invalidateKey(key); + } } private void checkAssertion(PointerTrackerQueue queue) { @@ -302,7 +314,7 @@ public class PointerTracker { if (DEBUG_MODE) Log.w(TAG, "onDownEvent: ignore potential noise: time=" + deltaT + " distance=" + distanceSquared); - setAlreadyProcessed(); + mKeyAlreadyProcessed = true; return; } } @@ -321,32 +333,33 @@ public class PointerTracker { private void onDownEventInternal(int x, int y, long eventTime) { int keyIndex = mKeyState.onDownKey(x, y, eventTime); // Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding - // from modifier key, 3) this pointer is on mini-keyboard, or 4) accessibility is enabled. + // from modifier key, or 3) this pointer is on mini-keyboard. mIsAllowedSlidingKeyInput = mConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex) - || mKeyDetector instanceof MiniKeyboardKeyDetector - || mIsAccessibilityEnabled; + || mKeyDetector instanceof MiniKeyboardKeyDetector; mKeyboardLayoutHasBeenChanged = false; mKeyAlreadyProcessed = false; mIsRepeatableKey = false; mIsInSlidingKeyInput = false; + mIsInSlidingLanguageSwitch = false; + mIgnoreModifierKey = false; if (isValidKeyIndex(keyIndex)) { // This onPress call may have changed keyboard layout. Those cases are detected at // {@link #setKeyboard}. In those cases, we should update keyIndex according to the new // keyboard layout. - if (callListenerOnPressAndCheckKeyboardLayoutChange(mKeys[keyIndex], false)) + if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), false)) keyIndex = mKeyState.onDownKey(x, y, eventTime); - } - if (isValidKeyIndex(keyIndex)) { - // Accessibility disables key repeat because users may need to pause on a key to hear - // its spoken description. - if (mKeys[keyIndex].mRepeatable && !mIsAccessibilityEnabled) { - repeatKey(keyIndex); - mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this); - mIsRepeatableKey = true; - } + + startRepeatKey(keyIndex); startLongPressTimer(keyIndex); + showKeyPreview(keyIndex); + setPressedKeyGraphics(keyIndex); } - showKeyPreviewAndUpdateKeyGraphics(keyIndex); + } + + private void startSlidingKeyInput(Key key) { + if (!mIsInSlidingKeyInput) + mIgnoreModifierKey = isModifierCode(key.mCode); + mIsInSlidingKeyInput = true; } public void onMoveEvent(int x, int y, long eventTime, PointerTrackerQueue queue) { @@ -357,10 +370,17 @@ public class PointerTracker { return; final PointerTrackerKeyState keyState = mKeyState; + // TODO: Remove this hacking code + if (mIsInSlidingLanguageSwitch) { + ((LatinKeyboard)mKeyboard).updateSpacebarPreviewIcon(x - keyState.getKeyX()); + showKeyPreview(mSpaceKeyIndex); + return; + } final int lastX = keyState.getLastX(); final int lastY = keyState.getLastY(); + final int oldKeyIndex = keyState.getKeyIndex(); + final Key oldKey = getKey(oldKeyIndex); int keyIndex = keyState.onMoveKey(x, y); - final Key oldKey = getKey(keyState.getKeyIndex()); if (isValidKeyIndex(keyIndex)) { if (oldKey == null) { // The pointer has been slid in to the new key, but the finger was not on any keys. @@ -372,13 +392,17 @@ public class PointerTracker { keyIndex = keyState.onMoveKey(x, y); keyState.onMoveToNewKey(keyIndex, x, y); startLongPressTimer(keyIndex); - } else if (!isMinorMoveBounce(x, y, keyIndex)) { + showKeyPreview(keyIndex); + setPressedKeyGraphics(keyIndex); + } else if (isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) { // The pointer has been slid in to the new key from the previous key, we must call // onRelease() first to notify that the previous key has been released, then call // onPress() to notify that the new key is being pressed. - mIsInSlidingKeyInput = true; + setReleasedKeyGraphics(oldKeyIndex); callListenerOnRelease(oldKey, oldKey.mCode, true); - mHandler.cancelLongPressTimers(); + startSlidingKeyInput(oldKey); + mHandler.cancelKeyTimers(); + startRepeatKey(keyIndex); if (mIsAllowedSlidingKeyInput) { // This onPress call may have changed keyboard layout. Those cases are detected // at {@link #setKeyboard}. In those cases, we should update keyIndex according @@ -387,6 +411,8 @@ public class PointerTracker { keyIndex = keyState.onMoveKey(x, y); keyState.onMoveToNewKey(keyIndex, x, y); startLongPressTimer(keyIndex); + setPressedKeyGraphics(keyIndex); + showKeyPreview(keyIndex); } else { // HACK: On some devices, quick successive touches may be translated to sudden // move by touch panel firmware. This hack detects the case and translates the @@ -398,32 +424,50 @@ public class PointerTracker { if (DEBUG_MODE) Log.w(TAG, String.format("onMoveEvent: sudden move is translated to " + "up[%d,%d]/down[%d,%d] events", lastX, lastY, x, y)); - onUpEventInternal(lastX, lastY, eventTime); + onUpEventInternal(lastX, lastY, eventTime, true); onDownEventInternal(x, y, eventTime); } else { - setAlreadyProcessed(); - showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY); + mKeyAlreadyProcessed = true; + dismissKeyPreview(); + setReleasedKeyGraphics(oldKeyIndex); + } + } + } + // TODO: Remove this hack code + else if (isSpaceKey(keyIndex) && !mIsInSlidingLanguageSwitch + && mKeyboard instanceof LatinKeyboard) { + final LatinKeyboard keyboard = ((LatinKeyboard)mKeyboard); + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher() + && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { + final int diff = x - keyState.getKeyX(); + if (keyboard.shouldTriggerSpacebarSlidingLanguageSwitch(diff)) { + // Detect start sliding language switch. + mIsInSlidingLanguageSwitch = true; + mSpaceKeyIndex = keyIndex; + keyboard.updateSpacebarPreviewIcon(diff); + // Display spacebar slide language switcher. + showKeyPreview(keyIndex); + if (queue != null) + queue.releaseAllPointersExcept(this, eventTime, true); } - return; } } } else { - if (oldKey != null && !isMinorMoveBounce(x, y, keyIndex)) { + if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) { // The pointer has been slid out from the previous key, we must call onRelease() to // notify that the previous key has been released. - mIsInSlidingKeyInput = true; + setReleasedKeyGraphics(oldKeyIndex); callListenerOnRelease(oldKey, oldKey.mCode, true); + startSlidingKeyInput(oldKey); mHandler.cancelLongPressTimers(); if (mIsAllowedSlidingKeyInput) { - keyState.onMoveToNewKey(keyIndex, x ,y); + keyState.onMoveToNewKey(keyIndex, x, y); } else { - setAlreadyProcessed(); - showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY); - return; + mKeyAlreadyProcessed = true; + dismissKeyPreview(); } } } - showKeyPreviewAndUpdateKeyGraphics(mKeyState.getKeyIndex()); } public void onUpEvent(int x, int y, long eventTime, PointerTrackerQueue queue) { @@ -435,42 +479,69 @@ public class PointerTracker { if (isModifier()) { // Before processing an up event of modifier key, all pointers already being // tracked should be released. - queue.releaseAllPointersExcept(this, eventTime); + queue.releaseAllPointersExcept(this, eventTime, true); } else { queue.releaseAllPointersOlderThan(this, eventTime); } queue.remove(this); } - onUpEventInternal(x, y, eventTime); + onUpEventInternal(x, y, eventTime, true); } - public void onUpEventForRelease(int x, int y, long eventTime) { - onUpEventInternal(x, y, eventTime); + // Let this pointer tracker know that one of newer-than-this pointer trackers got an up event. + // This pointer tracker needs to keep the key top graphics "pressed", but needs to get a + // "virtual" up event. + public void onPhantomUpEvent(int x, int y, long eventTime, boolean updateReleasedKeyGraphics) { + if (DEBUG_EVENT) + printTouchEvent("onPhntEvent:", x, y, eventTime); + onUpEventInternal(x, y, eventTime, updateReleasedKeyGraphics); + mKeyAlreadyProcessed = true; } - private void onUpEventInternal(int pointX, int pointY, long eventTime) { - int x = pointX; - int y = pointY; + private void onUpEventInternal(int x, int y, long eventTime, + boolean updateReleasedKeyGraphics) { mHandler.cancelKeyTimers(); - mHandler.cancelPopupPreview(); - showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY); + mHandler.cancelShowKeyPreview(this); mIsInSlidingKeyInput = false; + final PointerTrackerKeyState keyState = mKeyState; + final int keyX, keyY; + if (isMajorEnoughMoveToBeOnNewKey(x, y, keyState.onMoveKey(x, y))) { + keyX = x; + keyY = y; + } else { + // Use previous fixed key coordinates. + keyX = keyState.getKeyX(); + keyY = keyState.getKeyY(); + } + final int keyIndex = keyState.onUpKey(keyX, keyY, eventTime); + dismissKeyPreview(); + if (updateReleasedKeyGraphics) + setReleasedKeyGraphics(keyIndex); if (mKeyAlreadyProcessed) return; - final PointerTrackerKeyState keyState = mKeyState; - int keyIndex = keyState.onUpKey(x, y, eventTime); - if (isMinorMoveBounce(x, y, keyIndex)) { - // Use previous fixed key index and coordinates. - keyIndex = keyState.getKeyIndex(); - x = keyState.getKeyX(); - y = keyState.getKeyY(); + // TODO: Remove this hacking code + if (mIsInSlidingLanguageSwitch) { + setReleasedKeyGraphics(mSpaceKeyIndex); + final int languageDir = ((LatinKeyboard)mKeyboard).getLanguageChangeDirection(); + if (languageDir != 0) { + final int code = (languageDir == 1) + ? LatinKeyboard.CODE_NEXT_LANGUAGE : LatinKeyboard.CODE_PREV_LANGUAGE; + // This will change keyboard layout. + mListener.onCodeInput(code, new int[] {code}, keyX, keyY); + } + mIsInSlidingLanguageSwitch = false; + ((LatinKeyboard)mKeyboard).setSpacebarSlidingLanguageSwitchDiff(0); + return; } if (!mIsRepeatableKey) { - detectAndSendKey(keyIndex, x, y); + detectAndSendKey(keyIndex, keyX, keyY); } + } - if (isValidKeyIndex(keyIndex)) - mProxy.invalidateKey(mKeys[keyIndex]); + public void onLongPressed(PointerTrackerQueue queue) { + mKeyAlreadyProcessed = true; + if (queue != null) + queue.remove(this); } public void onCancelEvent(int x, int y, long eventTime, PointerTrackerQueue queue) { @@ -478,22 +549,34 @@ public class PointerTracker { if (DEBUG_EVENT) printTouchEvent("onCancelEvt:", x, y, eventTime); - if (queue != null) + if (queue != null) { + queue.releaseAllPointersExcept(this, eventTime, true); queue.remove(this); + } onCancelEventInternal(); } private void onCancelEventInternal() { mHandler.cancelKeyTimers(); - mHandler.cancelPopupPreview(); - showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY); + mHandler.cancelShowKeyPreview(this); + dismissKeyPreview(); + setReleasedKeyGraphics(mKeyState.getKeyIndex()); mIsInSlidingKeyInput = false; - int keyIndex = mKeyState.getKeyIndex(); - if (isValidKeyIndex(keyIndex)) - mProxy.invalidateKey(mKeys[keyIndex]); } - public void repeatKey(int keyIndex) { + private void startRepeatKey(int keyIndex) { + final Key key = getKey(keyIndex); + if (key != null && key.mRepeatable) { + dismissKeyPreview(); + onRepeatKey(keyIndex); + mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this); + mIsRepeatableKey = true; + } else { + mIsRepeatableKey = false; + } + } + + public void onRepeatKey(int keyIndex) { Key key = getKey(keyIndex); if (key != null) { detectAndSendKey(keyIndex, key.mX, key.mY); @@ -512,39 +595,46 @@ public class PointerTracker { return mKeyState.getDownTime(); } - private boolean isMinorMoveBounce(int x, int y, int newKey) { + private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, int newKey) { if (mKeys == null || mKeyHysteresisDistanceSquared < 0) throw new IllegalStateException("keyboard and/or hysteresis not set"); int curKey = mKeyState.getKeyIndex(); if (newKey == curKey) { - return true; + return false; } else if (isValidKeyIndex(curKey)) { - return mKeys[curKey].squaredDistanceToEdge(x, y) < mKeyHysteresisDistanceSquared; + return mKeys.get(curKey).squaredDistanceToEdge(x, y) >= mKeyHysteresisDistanceSquared; } else { - return false; + return true; } } - private void showKeyPreviewAndUpdateKeyGraphics(int keyIndex) { - updateKeyGraphics(keyIndex); - // The modifier key, such as shift key, should not be shown as preview when multi-touch is - // supported. On the other hand, if multi-touch is not supported, the modifier key should - // be shown as preview. If accessibility is turned on, the modifier key should be shown as - // preview. - if (mHasDistinctMultitouch && isModifier() && !mIsAccessibilityEnabled) { - mProxy.showPreview(NOT_A_KEY, this); - } else { - mProxy.showPreview(keyIndex, this); - } + // The modifier key, such as shift key, should not show its key preview. + private boolean isKeyPreviewNotRequired(int keyIndex) { + final Key key = getKey(keyIndex); + if (!key.mEnabled) + return true; + // Such as spacebar sliding language switch. + if (mKeyboard.needSpacebarPreview(keyIndex)) + return false; + final int code = key.mCode; + return isModifierCode(code) || code == Keyboard.CODE_DELETE + || code == Keyboard.CODE_ENTER || code == Keyboard.CODE_SPACE; } - private void startLongPressTimer(int keyIndex) { - // Accessibility disables long press because users are likely to need to pause on a key - // for an unspecified duration in order to hear the key's spoken description. - if (mIsAccessibilityEnabled) { + private void showKeyPreview(int keyIndex) { + if (isKeyPreviewNotRequired(keyIndex)) return; - } + mProxy.showKeyPreview(keyIndex, this); + } + + private void dismissKeyPreview() { + mProxy.dismissKeyPreview(this); + } + + private void startLongPressTimer(int keyIndex) { Key key = getKey(keyIndex); + if (!key.mEnabled) + return; if (key.mCode == Keyboard.CODE_SHIFT) { mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this); } else if (key.mManualTemporaryUpperCaseCode != Keyboard.CODE_DUMMY @@ -552,7 +642,7 @@ public class PointerTracker { // We need not start long press timer on the key which has manual temporary upper case // code defined and the keyboard is in manual temporary upper case mode. return; - } else if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) { + } else if (mKeyboardSwitcher.isInMomentarySwitchState()) { // We use longer timeout for sliding finger input started from the symbols mode key. mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this); } else { diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java index 64ba80a04..eecbb26f3 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java @@ -92,6 +92,7 @@ package com.android.inputmethod.keyboard; public int onUpKey(int x, int y, long eventTime) { mUpTime = eventTime; + mKeyIndex = KeyDetector.NOT_A_KEY; return onMoveKeyInternal(x, y); } } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java index 01d9b5d2c..9e287c67d 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java @@ -29,29 +29,28 @@ public class PointerTrackerQueue { if (mQueue.lastIndexOf(tracker) < 0) { return; } - LinkedList<PointerTracker> queue = mQueue; + final LinkedList<PointerTracker> queue = mQueue; int oldestPos = 0; for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) { if (t.isModifier()) { oldestPos++; } else { - t.onUpEventForRelease(t.getLastX(), t.getLastY(), eventTime); - t.setAlreadyProcessed(); + t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, true); queue.remove(oldestPos); } } } public void releaseAllPointers(long eventTime) { - releaseAllPointersExcept(null, eventTime); + releaseAllPointersExcept(null, eventTime, true); } - public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { + public void releaseAllPointersExcept(PointerTracker tracker, long eventTime, + boolean updateReleasedKeyGraphics) { for (PointerTracker t : mQueue) { if (t == tracker) continue; - t.onUpEventForRelease(t.getLastX(), t.getLastY(), eventTime); - t.setAlreadyProcessed(); + t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, updateReleasedKeyGraphics); } mQueue.clear(); if (tracker != null) diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java new file mode 100644 index 000000000..561dcbcef --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java @@ -0,0 +1,125 @@ +/* + * 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.keyboard; + +import com.android.inputmethod.latin.R; + +import android.content.Context; +import android.content.res.Resources; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.widget.PopupWindow; + +/** + * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting + * key presses and touch movements. + */ +public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel { + private final int[] mCoordinates = new int[2]; + private final boolean mConfigShowMiniKeyboardAtTouchedPoint; + + private int mOriginX; + private int mOriginY; + private int mTrackerId; + private long mDownTime; + + public PopupMiniKeyboardView(Context context, AttributeSet attrs) { + this(context, attrs, R.attr.keyboardViewStyle); + } + + public PopupMiniKeyboardView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + final Resources res = context.getResources(); + mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean( + R.bool.config_show_mini_keyboard_at_touched_point); + // Override default ProximityKeyDetector. + mKeyDetector = new MiniKeyboardKeyDetector(res.getDimension( + R.dimen.mini_keyboard_slide_allowance)); + // Remove gesture detector on mini-keyboard + mGestureDetector = null; + setKeyPreviewPopupEnabled(false, 0); + } + + @Override + public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) { + // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a + // delay of 0. The delay does not matter actually since the popup is not shown anyway. + super.setKeyPreviewPopupEnabled(false, 0); + } + + @Override + public void showPanel(KeyboardView parentKeyboardView, Key parentKey, + PointerTracker tracker, int keyPreviewY, PopupWindow window) { + final View container = (View)getParent(); + final MiniKeyboard miniKeyboard = (MiniKeyboard)getKeyboard(); + final Keyboard parentKeyboard = parentKeyboardView.getKeyboard(); + + parentKeyboardView.getLocationInWindow(mCoordinates); + final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX() + : parentKey.mX + parentKey.mWidth / 2; + final int pointY = parentKey.mY; + final int miniKeyboardX = pointX - miniKeyboard.getDefaultCoordX() + - container.getPaddingLeft() + + parentKeyboardView.getPaddingLeft() + mCoordinates[0]; + final int miniKeyboardY = pointY - parentKeyboard.getVerticalGap() + - (container.getMeasuredHeight() - container.getPaddingBottom()) + + parentKeyboardView.getPaddingTop() + mCoordinates[1]; + final int x = miniKeyboardX; + final int y = parentKeyboardView.isKeyPreviewPopupEnabled() && + miniKeyboard.isOneRowKeyboard() ? keyPreviewY : miniKeyboardY; + + if (miniKeyboard.setShifted(parentKeyboard.isShiftedOrShiftLocked())) { + invalidateAllKeys(); + } + window.setContentView(container); + window.setWidth(container.getMeasuredWidth()); + window.setHeight(container.getMeasuredHeight()); + window.showAtLocation(parentKeyboardView, Gravity.NO_GRAVITY, x, y); + + mOriginX = x + container.getPaddingLeft() - mCoordinates[0]; + mOriginY = y + container.getPaddingTop() - mCoordinates[1]; + mTrackerId = tracker.mPointerId; + mDownTime = SystemClock.uptimeMillis(); + + // Inject down event on the key to mini keyboard. + final MotionEvent downEvent = translateMotionEvent(MotionEvent.ACTION_DOWN, pointX, + pointY + parentKey.mHeight / 2, mDownTime); + onTouchEvent(downEvent); + downEvent.recycle(); + } + + private MotionEvent translateMotionEvent(int action, float x, float y, long eventTime) { + return MotionEvent.obtain(mDownTime, eventTime, action, x - mOriginX, y - mOriginY, 0); + } + + @Override + public boolean onTouchEvent(MotionEvent me) { + final int index = me.getActionIndex(); + final int id = me.getPointerId(index); + if (id == mTrackerId) { + final MotionEvent translated = translateMotionEvent(me.getAction(), me.getX(index), + me.getY(index), me.getEventTime()); + super.onTouchEvent(translated); + translated.recycle(); + } + return true; + } +} diff --git a/java/src/com/android/inputmethod/keyboard/PopupPanel.java b/java/src/com/android/inputmethod/keyboard/PopupPanel.java new file mode 100644 index 000000000..6f2b16148 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/PopupPanel.java @@ -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.keyboard; + +import android.view.MotionEvent; +import android.widget.PopupWindow; + +public interface PopupPanel { + /** + * Show popup panel. + * @param parentKeyboardView the parent KeyboardView that has the parent key. + * @param parentKey the parent key that is the source of this popup panel + * @param tracker the pointer tracker that pressesd the parent key + * @param keyPreviewY the Y-coordinate of key preview + * @param window PopupWindow to be used to show this popup panel + */ + public void showPanel(KeyboardView parentKeyboardView, Key parentKey, + PointerTracker tracker, int keyPreviewY, PopupWindow window); + + /** + * Check if the pointer is in siding key input mode. + * @return true if the pointer is sliding key input mode. + */ + public boolean isInSlidingKeyInput(); + + /** + * The motion event handler. + * @param me the MotionEvent to be processed. + * @return true if the motion event is processed and should be consumed. + */ + public boolean onTouchEvent(MotionEvent me); +} diff --git a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java deleted file mode 100644 index e2ff8c48e..000000000 --- a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2010 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.keyboard; - -import android.util.Log; - -import java.util.Arrays; - -public class ProximityKeyDetector extends KeyDetector { - private static final String TAG = ProximityKeyDetector.class.getSimpleName(); - private static final boolean DEBUG = false; - - private static final int MAX_NEARBY_KEYS = 12; - - // working area - private final int[] mDistances = new int[MAX_NEARBY_KEYS]; - private final int[] mIndices = new int[MAX_NEARBY_KEYS]; - - @Override - protected int getMaxNearbyKeys() { - return MAX_NEARBY_KEYS; - } - - private void initializeNearbyKeys() { - Arrays.fill(mDistances, Integer.MAX_VALUE); - Arrays.fill(mIndices, NOT_A_KEY); - } - - /** - * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance. - * - * @param keyIndex index of the key. - * @param distance distance between the key's edge and user touched point. - * @param isOnKey true if the point is on the key. - * @return order of the key in the nearby buffer, 0 if it is the nearest key. - */ - private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) { - final int[] distances = mDistances; - final int[] indices = mIndices; - for (int insertPos = 0; insertPos < distances.length; insertPos++) { - final int comparingDistance = distances[insertPos]; - if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) { - final int nextPos = insertPos + 1; - if (nextPos < distances.length) { - System.arraycopy(distances, insertPos, distances, nextPos, - distances.length - nextPos); - System.arraycopy(indices, insertPos, indices, nextPos, - indices.length - nextPos); - } - distances[insertPos] = distance; - indices[insertPos] = keyIndex; - return insertPos; - } - } - return distances.length; - } - - private void getNearbyKeyCodes(final int[] allCodes) { - final Key[] keys = getKeys(); - final int[] indices = mIndices; - - // allCodes[0] should always have the key code even if it is a non-letter key. - if (indices[0] == NOT_A_KEY) { - allCodes[0] = NOT_A_CODE; - return; - } - - int numCodes = 0; - for (int j = 0; j < indices.length && numCodes < allCodes.length; j++) { - final int index = indices[j]; - if (index == NOT_A_KEY) - break; - final int code = keys[index].mCode; - // filter out a non-letter key from nearby keys - if (code < Keyboard.CODE_SPACE) - continue; - allCodes[numCodes++] = code; - } - } - - @Override - public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) { - final Key[] keys = getKeys(); - final int touchX = getTouchX(x); - final int touchY = getTouchY(y); - - initializeNearbyKeys(); - int primaryIndex = NOT_A_KEY; - for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) { - final Key key = keys[index]; - final boolean isInside = key.isInside(touchX, touchY); - final int distance = key.squaredDistanceToEdge(touchX, touchY); - if (isInside || (mProximityCorrectOn && distance < mProximityThresholdSquare)) { - final int insertedPosition = sortNearbyKeys(index, distance, isInside); - if (insertedPosition == 0 && isInside) - primaryIndex = index; - } - } - - if (allCodes != null && allCodes.length > 0) { - getNearbyKeyCodes(allCodes); - if (DEBUG) { - Log.d(TAG, "x=" + x + " y=" + y - + " primary=" - + (primaryIndex == NOT_A_KEY ? "none" : keys[primaryIndex].mCode) - + " codes=" + Arrays.toString(allCodes)); - } - } - - return primaryIndex; - } -} diff --git a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java index ad8b0d623..5cf31cb14 100644 --- a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java +++ b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; @@ -37,7 +38,7 @@ import android.view.ViewConfiguration; * movement on the spacebar. */ public class SlidingLocaleDrawable extends Drawable { - + private static final int SLIDE_SPEED_MULTIPLIER_RATIO = 150; private final Context mContext; private final Resources mRes; private final int mWidth; @@ -63,9 +64,8 @@ public class SlidingLocaleDrawable extends Drawable { mHeight = height; final TextPaint textPaint = new TextPaint(); textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18)); - textPaint.setColor(R.color.latinkeyboard_transparent); + textPaint.setColor(Color.TRANSPARENT); textPaint.setTextAlign(Align.CENTER); - textPaint.setAlpha(LatinKeyboard.OPACITY_FULLY_OPAQUE); textPaint.setAntiAlias(true); mTextPaint = textPaint; mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2; @@ -90,7 +90,7 @@ public class SlidingLocaleDrawable extends Drawable { mCurrentLanguage = null; return; } - mDiff = diff; + mDiff = Math.max(diff, diff * SLIDE_SPEED_MULTIPLIER_RATIO / 100); if (mDiff > mWidth) mDiff = mWidth; if (mDiff < -mWidth) mDiff = -mWidth; if (Math.abs(mDiff) > mThreshold) mHitThreshold = true; diff --git a/java/src/com/android/inputmethod/latin/AccessibilityUtils.java b/java/src/com/android/inputmethod/latin/AccessibilityUtils.java deleted file mode 100644 index cd3f9e0ad..000000000 --- a/java/src/com/android/inputmethod/latin/AccessibilityUtils.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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.SharedPreferences; -import android.content.res.TypedArray; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; - -import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.KeyboardSwitcher; - -import java.util.HashMap; -import java.util.Map; - -/** - * Utility functions for accessibility support. - */ -public class AccessibilityUtils { - /** Shared singleton instance. */ - private static final AccessibilityUtils sInstance = new AccessibilityUtils(); - private /* final */ LatinIME mService; - private /* final */ AccessibilityManager mAccessibilityManager; - private /* final */ Map<Integer, CharSequence> mDescriptions; - - /** - * Returns a shared instance of AccessibilityUtils. - * - * @return A shared instance of AccessibilityUtils. - */ - public static AccessibilityUtils getInstance() { - return sInstance; - } - - /** - * Initializes (or re-initializes) the shared instance of AccessibilityUtils - * with the specified parent service and preferences. - * - * @param service The parent input method service. - * @param prefs The parent preferences. - */ - public static void init(LatinIME service, SharedPreferences prefs) { - sInstance.initialize(service, prefs); - } - - private AccessibilityUtils() { - // This class is not publicly instantiable. - } - - /** - * Initializes (or re-initializes) with the specified parent service and - * preferences. - * - * @param service The parent input method service. - * @param prefs The parent preferences. - */ - private void initialize(LatinIME service, SharedPreferences prefs) { - mService = service; - mAccessibilityManager = (AccessibilityManager) service.getSystemService( - Context.ACCESSIBILITY_SERVICE); - mDescriptions = null; - } - - /** - * Returns true if accessibility is enabled. - * - * @return {@code true} if accessibility is enabled. - */ - public boolean isAccessibilityEnabled() { - return mAccessibilityManager.isEnabled(); - } - - /** - * Speaks a key's action after it has been released. Does not speak letter - * keys since typed keys are already spoken aloud by TalkBack. - * <p> - * No-op if accessibility is not enabled. - * </p> - * - * @param primaryCode The primary code of the released key. - * @param switcher The input method's {@link KeyboardSwitcher}. - */ - public void onRelease(int primaryCode, KeyboardSwitcher switcher) { - if (!isAccessibilityEnabled()) { - return; - } - - int resId = -1; - - switch (primaryCode) { - case Keyboard.CODE_SHIFT: { - if (switcher.isShiftedOrShiftLocked()) { - resId = R.string.description_shift_on; - } else { - resId = R.string.description_shift_off; - } - break; - } - - case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: { - if (switcher.isAlphabetMode()) { - resId = R.string.description_symbols_off; - } else { - resId = R.string.description_symbols_on; - } - break; - } - } - - if (resId >= 0) { - speakDescription(mService.getResources().getText(resId)); - } - } - - /** - * Speaks a key's description for accessibility. If a key has an explicit - * description defined in keycodes.xml, that will be used. Otherwise, if the - * key is a Unicode character, then its character will be used. - * <p> - * No-op if accessibility is not enabled. - * </p> - * - * @param primaryCode The primary code of the pressed key. - * @param switcher The input method's {@link KeyboardSwitcher}. - */ - public void onPress(int primaryCode, KeyboardSwitcher switcher) { - if (!isAccessibilityEnabled()) { - return; - } - - // TODO Use the current keyboard state to read "Switch to symbols" - // instead of just "Symbols" (and similar for shift key). - CharSequence description = describeKey(primaryCode); - if (description == null && Character.isDefined((char) primaryCode)) { - description = Character.toString((char) primaryCode); - } - - if (description != null) { - speakDescription(description); - } - } - - /** - * Returns a text description for a given key code. If the key does not have - * an explicit description, returns <code>null</code>. - * - * @param keyCode An integer key code. - * @return A {@link CharSequence} describing the key or <code>null</code> if - * no description is available. - */ - private CharSequence describeKey(int keyCode) { - // If not loaded yet, load key descriptions from XML file. - if (mDescriptions == null) { - mDescriptions = loadDescriptions(); - } - - return mDescriptions.get(keyCode); - } - - /** - * Loads key descriptions from resources. - */ - private Map<Integer, CharSequence> loadDescriptions() { - final Map<Integer, CharSequence> descriptions = new HashMap<Integer, CharSequence>(); - final TypedArray array = mService.getResources().obtainTypedArray(R.array.key_descriptions); - - // Key descriptions are stored as a key code followed by a string. - for (int i = 0; i < array.length() - 1; i += 2) { - int code = array.getInteger(i, 0); - CharSequence desc = array.getText(i + 1); - - descriptions.put(code, desc); - } - - array.recycle(); - - return descriptions; - } - - /** - * Sends a character sequence to be read aloud. - * - * @param description The {@link CharSequence} to be read aloud. - */ - private void speakDescription(CharSequence description) { - // TODO We need to add an AccessibilityEvent type for IMEs. - final AccessibilityEvent event = AccessibilityEvent.obtain( - AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); - event.setPackageName(mService.getPackageName()); - event.setClassName(getClass().getName()); - event.setAddedCount(description.length()); - event.getText().add(description); - - mAccessibilityManager.sendAccessibilityEvent(event); - } -} diff --git a/java/src/com/android/inputmethod/latin/AssetFileAddress.java b/java/src/com/android/inputmethod/latin/AssetFileAddress.java new file mode 100644 index 000000000..074ecacc5 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/AssetFileAddress.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin; + +import java.io.File; + +/** + * Immutable class to hold the address of an asset. + * As opposed to a normal file, an asset is usually represented as a contiguous byte array in + * the package file. Open it correctly thus requires the name of the package it is in, but + * also the offset in the file and the length of this data. This class encapsulates these three. + */ +class AssetFileAddress { + public final String mFilename; + public final long mOffset; + public final long mLength; + + public AssetFileAddress(final String filename, final long offset, final long length) { + mFilename = filename; + mOffset = offset; + mLength = length; + } + + public static AssetFileAddress makeFromFileName(final String filename) { + if (null == filename) return null; + File f = new File(filename); + if (null == f || !f.isFile()) return null; + return new AssetFileAddress(filename, 0l, f.length()); + } + + public static AssetFileAddress makeFromFileNameAndOffset(final String filename, + final long offset, final long length) { + if (null == filename) return null; + File f = new File(filename); + if (null == f || !f.isFile()) return null; + return new AssetFileAddress(filename, offset, length); + } +} diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java index 092f7ad63..d3119792c 100644 --- a/java/src/com/android/inputmethod/latin/AutoCorrection.java +++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java @@ -48,7 +48,7 @@ public class AutoCorrection { } public void updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries, - WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] priorities, + WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores, CharSequence typedWord, double autoCorrectionThreshold, int correctionMode, CharSequence quickFixedWord, CharSequence whitelistedWord) { if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) { @@ -62,7 +62,7 @@ public class AutoCorrection { mHasAutoCorrection = true; mAutoCorrectionWord = quickFixedWord; } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, correctionMode, - priorities, typedWord, autoCorrectionThreshold)) { + sortedScores, typedWord, autoCorrectionThreshold)) { mHasAutoCorrection = true; mAutoCorrectionWord = suggestions.get(0); } @@ -114,13 +114,13 @@ public class AutoCorrection { } private boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer, - ArrayList<CharSequence> suggestions, int correctionMode, int[] priorities, + ArrayList<CharSequence> suggestions, int correctionMode, int[] sortedScores, CharSequence typedWord, double autoCorrectionThreshold) { if (wordComposer.size() > 1 && (correctionMode == Suggest.CORRECTION_FULL || correctionMode == Suggest.CORRECTION_FULL_BIGRAM) - && typedWord != null && suggestions.size() > 0 && priorities.length > 0) { + && typedWord != null && suggestions.size() > 0 && sortedScores.length > 0) { final CharSequence autoCorrectionCandidate = suggestions.get(0); - final int autoCorrectionCandidateScore = priorities[0]; + final int autoCorrectionCandidateScore = sortedScores[0]; // TODO: when the normalized score of the first suggestion is nearly equals to // the normalized score of the second suggestion, behave less aggressive. mNormalizedScore = Utils.calcNormalizedScore( diff --git a/java/src/com/android/inputmethod/latin/AutoDictionary.java b/java/src/com/android/inputmethod/latin/AutoDictionary.java index 54c6f309c..c2646160d 100644 --- a/java/src/com/android/inputmethod/latin/AutoDictionary.java +++ b/java/src/com/android/inputmethod/latin/AutoDictionary.java @@ -27,7 +27,6 @@ import android.provider.BaseColumns; import android.util.Log; import java.util.HashMap; -import java.util.Map; import java.util.Map.Entry; import java.util.Set; diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 08ddd25fa..d95fb9638 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -21,10 +21,7 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.ProximityInfo; import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.util.Log; -import java.io.File; import java.util.Arrays; /** @@ -32,8 +29,11 @@ import java.util.Arrays; */ public class BinaryDictionary extends Dictionary { + public static final String DICTIONARY_PACK_AUTHORITY = + "com.android.inputmethod.latin.dictionarypack"; + /** - * There is difference between what java and native code can handle. + * There is a difference between what java and native code can handle. * This value should only be used in BinaryDictionary.java * It is necessary to keep it at this value because some languages e.g. German have * really long words. @@ -41,101 +41,59 @@ public class BinaryDictionary extends Dictionary { public static final int MAX_WORD_LENGTH = 48; public static final int MAX_WORDS = 18; + @SuppressWarnings("unused") private static final String TAG = "BinaryDictionary"; private static final int MAX_PROXIMITY_CHARS_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE; private static final int MAX_BIGRAMS = 60; private static final int TYPED_LETTER_MULTIPLIER = 2; - private static final BinaryDictionary sInstance = new BinaryDictionary(); private int mDicTypeId; private int mNativeDict; - private long mDictLength; private final int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_PROXIMITY_CHARS_SIZE]; private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; - private final int[] mFrequencies = new int[MAX_WORDS]; - private final int[] mFrequencies_bigrams = new int[MAX_BIGRAMS]; + private final int[] mScores = new int[MAX_WORDS]; + private final int[] mBigramScores = new int[MAX_BIGRAMS]; private final KeyboardSwitcher mKeyboardSwitcher = KeyboardSwitcher.getInstance(); - private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance(); - - private static class Flags { - private static class FlagEntry { - public final String mName; - public final int mValue; - public FlagEntry(String name, int value) { - mName = name; - mValue = value; - } - } - public static final FlagEntry[] ALL_FLAGS = { - // Here should reside all flags that trigger some special processing - // These *must* match the definition in UnigramDictionary enum in - // unigram_dictionary.h so please update both at the same time. - new FlagEntry("requiresGermanUmlautProcessing", 0x1) - }; - } - private int mFlags = 0; - private BinaryDictionary() { - } + public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING = + new Flag(R.bool.config_require_umlaut_processing, 0x1); - /** - * Initialize a dictionary from a raw resource file - * @param context application context for reading resources - * @param resId the resource containing the raw binary dictionary - * @return initialized instance of BinaryDictionary - */ - public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) { - synchronized (sInstance) { - sInstance.closeInternal(); - try { - final AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId); - if (afd == null) { - Log.e(TAG, "Found the resource but it is compressed. resId=" + resId); - return null; - } - final String sourceDir = context.getApplicationInfo().sourceDir; - final File packagePath = new File(sourceDir); - // TODO: Come up with a way to handle a directory. - if (!packagePath.isFile()) { - Log.e(TAG, "sourceDir is not a file: " + sourceDir); - return null; - } - sInstance.loadDictionary(sourceDir, afd.getStartOffset(), afd.getLength()); - sInstance.mDicTypeId = dicTypeId; - } catch (android.content.res.Resources.NotFoundException e) { - Log.e(TAG, "Could not find the resource. resId=" + resId); - return null; - } - } - sInstance.initFlags(); - return sInstance; - } + // Can create a new flag from extravalue : + // public static final Flag FLAG_MYFLAG = + // new Flag("my_flag", 0x02); - /* package for test */ static BinaryDictionary initDictionary(File dictionary, long startOffset, - long length, int dicTypeId) { - synchronized (sInstance) { - sInstance.closeInternal(); - if (dictionary.isFile()) { - sInstance.loadDictionary(dictionary.getAbsolutePath(), startOffset, length); - sInstance.mDicTypeId = dicTypeId; - } else { - Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath()); - return null; - } - } - return sInstance; - } + private static final Flag[] ALL_FLAGS = { + // Here should reside all flags that trigger some special processing + // These *must* match the definition in UnigramDictionary enum in + // unigram_dictionary.h so please update both at the same time. + FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING, + }; - private void initFlags() { - int flags = 0; - for (Flags.FlagEntry entry : Flags.ALL_FLAGS) { - if (mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(entry.mName)) - flags |= entry.mValue; - } - mFlags = flags; + private int mFlags = 0; + + /** + * Constructor for the binary dictionary. This is supposed to be called from the + * dictionary factory. + * All implementations should pass null into flagArray, except for testing purposes. + * @param context the context to access the environment from. + * @param filename the name of the file to read through native code. + * @param offset the offset of the dictionary data within the file. + * @param length the length of the binary data. + * @param flagArray the flags to limit the dictionary to, or null for default. + */ + public BinaryDictionary(final Context context, + final String filename, final long offset, final long length, Flag[] flagArray) { + // Note: at the moment a binary dictionary is always of the "main" type. + // Initializing this here will help transitioning out of the scheme where + // the Suggest class knows everything about every single dictionary. + mDicTypeId = Suggest.DIC_MAIN; + // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter + mFlags = Flag.initFlags(null == flagArray ? ALL_FLAGS : flagArray, context, + SubtypeSwitcher.getInstance()); + loadDictionary(filename, offset, length); } static { @@ -149,16 +107,15 @@ public class BinaryDictionary extends Dictionary { private native boolean isValidWordNative(int nativeData, char[] word, int wordLength); private native int getSuggestionsNative(int dict, int proximityInfo, int[] xCoordinates, int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars, - int[] frequencies); + int[] scores); private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength, - int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies, + int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores, int maxWordLength, int maxBigrams, int maxAlternatives); private final void loadDictionary(String path, long startOffset, long length) { mNativeDict = openNative(path, startOffset, length, - TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER, + TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER, MAX_WORD_LENGTH, MAX_WORDS, MAX_PROXIMITY_CHARS_SIZE); - mDictLength = length; } @Override @@ -168,27 +125,32 @@ public class BinaryDictionary extends Dictionary { char[] chars = previousWord.toString().toCharArray(); Arrays.fill(mOutputChars_bigrams, (char) 0); - Arrays.fill(mFrequencies_bigrams, 0); + Arrays.fill(mBigramScores, 0); int codesSize = codes.size(); + if (codesSize <= 0) { + // Do not return bigrams from BinaryDictionary when nothing was typed. + // Only use user-history bigrams (or whatever other bigram dictionaries decide). + return; + } Arrays.fill(mInputCodes, -1); int[] alternatives = codes.getCodesAt(0); System.arraycopy(alternatives, 0, mInputCodes, 0, Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE)); int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize, - mOutputChars_bigrams, mFrequencies_bigrams, MAX_WORD_LENGTH, MAX_BIGRAMS, + mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS, MAX_PROXIMITY_CHARS_SIZE); for (int j = 0; j < count; ++j) { - if (mFrequencies_bigrams[j] < 1) break; + if (mBigramScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; int len = 0; while (len < MAX_WORD_LENGTH && mOutputChars_bigrams[start + len] != 0) { ++len; } if (len > 0) { - callback.addWord(mOutputChars_bigrams, start, len, mFrequencies_bigrams[j], + callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j], mDicTypeId, DataType.BIGRAM); } } @@ -197,17 +159,17 @@ public class BinaryDictionary extends Dictionary { @Override public void getWords(final WordComposer codes, final WordCallback callback) { final int count = getSuggestions(codes, mKeyboardSwitcher.getLatinKeyboard(), - mOutputChars, mFrequencies); + mOutputChars, mScores); for (int j = 0; j < count; ++j) { - if (mFrequencies[j] < 1) break; + if (mScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; int len = 0; while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) { ++len; } if (len > 0) { - callback.addWord(mOutputChars, start, len, mFrequencies[j], mDicTypeId, + callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId, DataType.UNIGRAM); } } @@ -218,7 +180,7 @@ public class BinaryDictionary extends Dictionary { } /* package for test */ int getSuggestions(final WordComposer codes, final Keyboard keyboard, - char[] outputChars, int[] frequencies) { + char[] outputChars, int[] scores) { if (!isValidDictionary()) return -1; final int codesSize = codes.size(); @@ -232,12 +194,12 @@ public class BinaryDictionary extends Dictionary { Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE)); } Arrays.fill(outputChars, (char) 0); - Arrays.fill(frequencies, 0); + Arrays.fill(scores, 0); return getSuggestionsNative( mNativeDict, keyboard.getProximityInfo(), codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, - mFlags, outputChars, frequencies); + mFlags, outputChars, scores); } @Override @@ -247,10 +209,6 @@ public class BinaryDictionary extends Dictionary { return isValidWordNative(mNativeDict, chars, chars.length); } - public long getSize() { - return mDictLength; // This value is initialized in loadDictionary() - } - @Override public synchronized void close() { closeInternal(); @@ -260,7 +218,6 @@ public class BinaryDictionary extends Dictionary { if (mNativeDict != 0) { closeNative(mNativeDict); mNativeDict = 0; - mDictLength = 0; } } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java new file mode 100644 index 000000000..76a230f82 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -0,0 +1,151 @@ +/* + * 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.ContentResolver; +import android.content.Context; +import android.content.res.AssetFileDescriptor; +import android.net.Uri; +import android.text.TextUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +/** + * Group class for static methods to help with creation and getting of the binary dictionary + * file from the dictionary provider + */ +public class BinaryDictionaryFileDumper { + /** + * The size of the temporary buffer to copy files. + */ + static final int FILE_READ_BUFFER_SIZE = 1024; + + // Prevents this class to be accidentally instantiated. + private BinaryDictionaryFileDumper() { + } + + /** + * Generates a file name that matches the locale passed as an argument. + * The file name is basically the result of the .toString() method, except we replace + * any @File.separator with an underscore to avoid generating a file name that may not + * be created. + * @param locale the locale for which to get the file name + * @param context the context to use for getting the directory + * @return the name of the file to be created + */ + private static String getCacheFileNameForLocale(Locale locale, Context context) { + // The following assumes two things : + // 1. That File.separator is not the same character as "_" + // I don't think any android system will ever use "_" as a path separator + // 2. That no two locales differ by only a File.separator versus a "_" + // Since "_" can't be part of locale components this should be safe. + // Examples: + // en -> en + // en_US_POSIX -> en_US_POSIX + // en__foo/bar -> en__foo_bar + final String[] separator = { File.separator }; + final String[] empty = { "_" }; + final CharSequence basename = TextUtils.replace(locale.toString(), separator, empty); + return context.getFilesDir() + File.separator + basename; + } + + /** + * Return for a given locale the provider URI to query to get the dictionary. + */ + public static Uri getProviderUri(Locale locale) { + return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + .authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath( + locale.toString()).build(); + } + + /** + * Queries a content provider for dictionary data for some locale and returns the file addresses + * + * This will query a content provider for dictionary data for a given locale, and return + * the addresses of a file set the members of which are suitable to be mmap'ed. It will copy + * them to local storage if needed. + * It should also check the dictionary versions to avoid unnecessary copies but this is + * still in TODO state. + * This will make the data from the content provider the cached dictionary for this locale, + * overwriting any previous cached data. + * @returns the addresses of the files, or null if no data could be obtained. + * @throw FileNotFoundException if the provider returns non-existent data. + * @throw IOException if the provider-returned data could not be read. + */ + public static List<AssetFileAddress> getDictSetFromContentProvider(Locale locale, + Context context) throws FileNotFoundException, IOException { + // TODO: check whether the dictionary is the same or not and if it is, return the cached + // file. + // TODO: This should be able to read a number of files from the dictionary pack, copy + // them all and return them. + final ContentResolver resolver = context.getContentResolver(); + final Uri dictionaryPackUri = getProviderUri(locale); + final AssetFileDescriptor afd = resolver.openAssetFileDescriptor(dictionaryPackUri, "r"); + if (null == afd) return null; + final String fileName = + copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context)); + return Arrays.asList(AssetFileAddress.makeFromFileName(fileName)); + } + + /** + * Accepts a file as dictionary data for some locale and returns the name of a file. + * + * This will make the data in the input file the cached dictionary for this locale, overwriting + * any previous cached data. + */ + public static String getDictionaryFileFromFile(String fileName, Locale locale, + Context context) throws FileNotFoundException, IOException { + return copyFileTo(new FileInputStream(fileName), getCacheFileNameForLocale(locale, + context)); + } + + /** + * Accepts a resource number as dictionary data for some locale and returns the name of a file. + * + * This will make the resource the cached dictionary for this locale, overwriting any previous + * cached data. + */ + public static String getDictionaryFileFromResource(int resource, Locale locale, + Context context) throws FileNotFoundException, IOException { + return copyFileTo(context.getResources().openRawResource(resource), + getCacheFileNameForLocale(locale, context)); + } + + /** + * Copies the data in an input stream to a target file, creating the file if necessary and + * overwriting it if it already exists. + * @param input the stream to be copied. + * @param outputFileName the name of a file to copy the data to. It is created if necessary. + */ + private static String copyFileTo(final InputStream input, final String outputFileName) + throws FileNotFoundException, IOException { + final byte[] buffer = new byte[FILE_READ_BUFFER_SIZE]; + final FileOutputStream output = new FileOutputStream(outputFileName); + for (int readBytes = input.read(buffer); readBytes >= 0; readBytes = input.read(buffer)) + output.write(buffer, 0, readBytes); + input.close(); + return outputFileName; + } +} diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java new file mode 100644 index 000000000..7ce92920d --- /dev/null +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -0,0 +1,97 @@ +/* + * 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.AssetFileDescriptor; +import android.util.Log; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +/** + * Helper class to get the address of a mmap'able dictionary file. + */ +class BinaryDictionaryGetter { + + /** + * Used for Log actions from this class + */ + private static final String TAG = BinaryDictionaryGetter.class.getSimpleName(); + + // Prevents this from being instantiated + private BinaryDictionaryGetter() {} + + /** + * Returns a file address from a resource, or null if it cannot be opened. + */ + private static AssetFileAddress loadFallbackResource(Context context, int fallbackResId) { + final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId); + if (afd == null) { + Log.e(TAG, "Found the resource but cannot read it. Is it compressed? resId=" + + fallbackResId); + return null; + } + return AssetFileAddress.makeFromFileNameAndOffset( + context.getApplicationInfo().sourceDir, afd.getStartOffset(), afd.getLength()); + } + + /** + * Returns a list of file addresses for a given locale, trying relevant methods in order. + * + * Tries to get binary dictionaries from various sources, in order: + * - Uses a private method of getting a private dictionaries, as implemented by the + * PrivateBinaryDictionaryGetter class. + * If that fails: + * - Uses a content provider to get a public dictionary set, as per the protocol described + * in BinaryDictionaryFileDumper. + * If that fails: + * - Gets a file name from the fallback resource passed as an argument. + * If that fails: + * - Returns null. + * @return The address of a valid file, or null. + */ + public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context, + int fallbackResId) { + // Try first to query a private package signed the same way for private files. + final List<AssetFileAddress> privateFiles = + PrivateBinaryDictionaryGetter.getDictionaryFiles(locale, context); + if (null != privateFiles) { + return privateFiles; + } else { + try { + // If that was no-go, try to find a publicly exported dictionary. + List<AssetFileAddress> listFromContentProvider = + BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context); + if (null != listFromContentProvider) { + return listFromContentProvider; + } + // If the list is null, fall through and return the fallback + } catch (FileNotFoundException e) { + Log.e(TAG, "Unable to create dictionary file from provider for locale " + + locale.toString() + ": falling back to internal dictionary"); + } catch (IOException e) { + Log.e(TAG, "Unable to read source data for locale " + + locale.toString() + ": falling back to internal dictionary"); + } + return Arrays.asList(loadFallbackResource(context, fallbackResId)); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java index 5719b9012..abdf30e6b 100644 --- a/java/src/com/android/inputmethod/latin/CandidateView.java +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -133,7 +133,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo ViewGroup.LayoutParams.WRAP_CONTENT); mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setBackgroundDrawable(null); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); mConfigCandidateHighlightFontColorEnabled = res.getBoolean(R.bool.config_candidate_highlight_font_color_enabled); mColorNormal = res.getColor(R.color.candidate_normal); @@ -151,7 +150,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo tv.setOnLongClickListener(this); ImageView divider = (ImageView)v.findViewById(R.id.candidate_divider); // Do not display divider of first candidate. - divider.setVisibility(i == 0 ? GONE : VISIBLE); + divider.setVisibility(i == 0 ? INVISIBLE : VISIBLE); mWords.add(v); } @@ -180,7 +179,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo private void updateSuggestions() { final SuggestedWords suggestions = mSuggestions; clear(); - final int count = suggestions.size(); + final int count = Math.min(mWords.size(), suggestions.size()); for (int i = 0; i < count; i++) { CharSequence word = suggestions.getWord(i); if (word == null) continue; diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java index 048f72dc5..b057cf4e3 100644 --- a/java/src/com/android/inputmethod/latin/ContactsDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java @@ -26,6 +26,8 @@ import android.provider.ContactsContract.Contacts; import android.text.TextUtils; import android.util.Log; +import com.android.inputmethod.keyboard.Keyboard; + public class ContactsDictionary extends ExpandableDictionary { private static final String[] PROJECTION = { @@ -95,6 +97,14 @@ public class ContactsDictionary extends ExpandableDictionary { mLastLoadedContacts = SystemClock.uptimeMillis(); } + @Override + public void getBigrams(final WordComposer codes, final CharSequence previousWord, + final WordCallback callback) { + // Do not return bigrams from Contacts when nothing was typed. + if (codes.size() <= 0) return; + super.getBigrams(codes, previousWord, callback); + } + private void addWords(Cursor cursor) { clearDictionary(); @@ -115,8 +125,9 @@ public class ContactsDictionary extends ExpandableDictionary { for (j = i + 1; j < len; j++) { char c = name.charAt(j); - if (!(c == '-' || c == '\'' || - Character.isLetter(c))) { + if (!(c == Keyboard.CODE_DASH + || c == Keyboard.CODE_SINGLE_QUOTE + || Character.isLetter(c))) { break; } } diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java index 2f1e7c2b8..fd62d61c3 100644 --- a/java/src/com/android/inputmethod/latin/DebugSettings.java +++ b/java/src/com/android/inputmethod/latin/DebugSettings.java @@ -33,6 +33,7 @@ public class DebugSettings extends PreferenceActivity private boolean mServiceNeedsRestart = false; private CheckBoxPreference mDebugMode; + private CheckBoxPreference mUseSpacebarLanguageSwitch; @Override protected void onCreate(Bundle icicle) { @@ -60,6 +61,13 @@ public class DebugSettings extends PreferenceActivity updateDebugMode(); mServiceNeedsRestart = true; } + } else if (key.equals(SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCH_KEY)) { + if (mUseSpacebarLanguageSwitch != null) { + mUseSpacebarLanguageSwitch.setChecked( + prefs.getBoolean(SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCH_KEY, + getResources().getBoolean( + R.bool.config_use_spacebar_language_switcher))); + } } } diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index 56f0cc503..c7737b9a2 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -29,7 +29,7 @@ public abstract class Dictionary { /** * The weight to give to a word if it's length is the same as the number of typed characters. */ - protected static final int FULL_WORD_FREQ_MULTIPLIER = 2; + protected static final int FULL_WORD_SCORE_MULTIPLIER = 2; public static enum DataType { UNIGRAM, BIGRAM @@ -42,17 +42,17 @@ public abstract class Dictionary { public interface WordCallback { /** * Adds a word to a list of suggestions. The word is expected to be ordered based on - * the provided frequency. + * the provided score. * @param word the character array containing the word * @param wordOffset starting offset of the word in the character array * @param wordLength length of valid characters in the character array - * @param frequency the frequency of occurrence. This is normalized between 1 and 255, but + * @param score the score of occurrence. This is normalized between 1 and 255, but * can exceed those limits * @param dicTypeId of the dictionary where word was from * @param dataType tells type of this data * @return true if the word was added, false if no more words are required */ - boolean addWord(char[] word, int wordOffset, int wordLength, int frequency, int dicTypeId, + boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId, DataType dataType); } @@ -61,7 +61,7 @@ public abstract class Dictionary { * words are added through the callback object. * @param composer the key sequence to match * @param callback the callback object to send matched words to as possible candidates - * @see WordCallback#addWord(char[], int, int) + * @see WordCallback#addWord(char[], int, int, int, int, DataType) */ abstract public void getWords(final WordComposer composer, final WordCallback callback); diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java new file mode 100644 index 000000000..3fcb6ed55 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -0,0 +1,71 @@ +/* + * 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 java.util.Collection; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Class for a collection of dictionaries that behave like one dictionary. + */ +public class DictionaryCollection extends Dictionary { + + protected final List<Dictionary> mDictionaries; + + public DictionaryCollection() { + mDictionaries = new CopyOnWriteArrayList<Dictionary>(); + } + + public DictionaryCollection(Dictionary... dictionaries) { + mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); + } + + public DictionaryCollection(Collection<Dictionary> dictionaries) { + mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); + } + + @Override + public void getWords(final WordComposer composer, final WordCallback callback) { + for (final Dictionary dict : mDictionaries) + dict.getWords(composer, callback); + } + + @Override + public void getBigrams(final WordComposer composer, final CharSequence previousWord, + final WordCallback callback) { + for (final Dictionary dict : mDictionaries) + dict.getBigrams(composer, previousWord, callback); + } + + @Override + public boolean isValidWord(CharSequence word) { + for (final Dictionary dict : mDictionaries) + if (dict.isValidWord(word)) return true; + return false; + } + + @Override + public void close() { + for (final Dictionary dict : mDictionaries) + dict.close(); + } + + public void addDictionary(Dictionary newDict) { + mDictionaries.add(newDict); + } +} diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java new file mode 100644 index 000000000..bba331868 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -0,0 +1,177 @@ +/* + * 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.AssetFileDescriptor; +import android.content.res.Resources; +import android.util.Log; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; + +/** + * Factory for dictionary instances. + */ +public class DictionaryFactory { + + private static String TAG = DictionaryFactory.class.getSimpleName(); + + /** + * Initializes a dictionary from a dictionary pack. + * + * This searches for a content provider providing a dictionary pack for the specified + * locale. If none is found, it falls back to using the resource passed as fallBackResId + * as a dictionary. + * @param context application context for reading resources + * @param locale the locale for which to create the dictionary + * @param fallbackResId the id of the resource to use as a fallback if no pack is found + * @return an initialized instance of Dictionary + */ + public static Dictionary createDictionaryFromManager(Context context, Locale locale, + int fallbackResId) { + if (null == locale) { + Log.e(TAG, "No locale defined for dictionary"); + return new DictionaryCollection(createBinaryDictionary(context, fallbackResId)); + } + + final List<Dictionary> dictList = new LinkedList<Dictionary>(); + for (final AssetFileAddress f : BinaryDictionaryGetter.getDictionaryFiles(locale, + context, fallbackResId)) { + dictList.add(new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, null)); + } + + if (null == dictList) return null; + return new DictionaryCollection(dictList); + } + + /** + * Initializes a dictionary from a raw resource file + * @param context application context for reading resources + * @param resId the resource containing the raw binary dictionary + * @return an initialized instance of BinaryDictionary + */ + protected static BinaryDictionary createBinaryDictionary(Context context, int resId) { + AssetFileDescriptor afd = null; + try { + afd = context.getResources().openRawResourceFd(resId); + if (afd == null) { + Log.e(TAG, "Found the resource but it is compressed. resId=" + resId); + return null; + } + if (!isFullDictionary(afd)) return null; + final String sourceDir = context.getApplicationInfo().sourceDir; + final File packagePath = new File(sourceDir); + // TODO: Come up with a way to handle a directory. + if (!packagePath.isFile()) { + Log.e(TAG, "sourceDir is not a file: " + sourceDir); + return null; + } + return new BinaryDictionary(context, + sourceDir, afd.getStartOffset(), afd.getLength(), null); + } catch (android.content.res.Resources.NotFoundException e) { + Log.e(TAG, "Could not find the resource. resId=" + resId); + return null; + } finally { + if (null != afd) { + try { + afd.close(); + } catch (java.io.IOException e) { + /* IOException on close ? What am I supposed to do ? */ + } + } + } + } + + /** + * Create a dictionary from passed data. This is intended for unit tests only. + * @param context the test context to create this data from. + * @param dictionary the file to read + * @param startOffset the offset in the file where the data starts + * @param length the length of the data + * @param flagArray the flags to use with this data for testing + * @return the created dictionary, or null. + */ + public static Dictionary createDictionaryForTest(Context context, File dictionary, + long startOffset, long length, Flag[] flagArray) { + if (dictionary.isFile()) { + return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length, + flagArray); + } else { + Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath()); + return null; + } + } + + /** + * Find out whether a dictionary is available for this locale. + * @param context the context on which to check resources. + * @param locale the locale to check for. + * @return whether a (non-placeholder) dictionary is available or not. + */ + public static boolean isDictionaryAvailable(Context context, Locale locale) { + final Resources res = context.getResources(); + final Locale saveLocale = Utils.setSystemLocale(res, locale); + + final int resourceId = Utils.getMainDictionaryResourceId(res); + final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); + final boolean hasDictionary = isFullDictionary(afd); + try { + if (null != afd) afd.close(); + } catch (java.io.IOException e) { + /* Um, what can we do here exactly? */ + } + + Utils.setSystemLocale(res, saveLocale); + return hasDictionary; + } + + // TODO: Do not use the size of the dictionary as an unique dictionary ID. + public static Long getDictionaryId(Context context, Locale locale) { + final Resources res = context.getResources(); + final Locale saveLocale = Utils.setSystemLocale(res, locale); + + final int resourceId = Utils.getMainDictionaryResourceId(res); + final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); + final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH) + ? afd.getLength() + : null; + try { + if (null != afd) afd.close(); + } catch (java.io.IOException e) { + } + + Utils.setSystemLocale(res, saveLocale); + return size; + } + + // TODO: Find the Right Way to find out whether the resource is a placeholder or not. + // Suggestion : strip the locale, open the placeholder file and store its offset. + // Upon opening the file, if it's the same offset, then it's the placeholder. + private static final long PLACEHOLDER_LENGTH = 34; + /** + * Finds out whether the data pointed out by an AssetFileDescriptor is a full + * dictionary (as opposed to null, or to a place holder). + * @param afd the file descriptor to test, or null + * @return true if the dictionary is a real full dictionary, false if it's null or a placeholder + */ + protected static boolean isFullDictionary(final AssetFileDescriptor afd) { + return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH); + } +} diff --git a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java new file mode 100644 index 000000000..9d30af84b --- /dev/null +++ b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java @@ -0,0 +1,89 @@ +/* + * 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.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; +import android.net.Uri; + +/** + * Takes action to reload the necessary data when a dictionary pack was added/removed. + */ +public class DictionaryPackInstallBroadcastReceiver extends BroadcastReceiver { + + final LatinIME mService; + /** + * The action of the intent for publishing that new dictionary data is available. + */ + /* package */ static final String NEW_DICTIONARY_INTENT_ACTION = + "com.android.inputmethod.latin.dictionarypack.newdict"; + + public DictionaryPackInstallBroadcastReceiver(final LatinIME service) { + mService = service; + } + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + final PackageManager manager = context.getPackageManager(); + + // We need to reread the dictionary if a new dictionary package is installed. + if (action.equals(Intent.ACTION_PACKAGE_ADDED)) { + final Uri packageUri = intent.getData(); + if (null == packageUri) return; // No package name : we can't do anything + final String packageName = packageUri.getSchemeSpecificPart(); + if (null == packageName) return; + final PackageInfo packageInfo; + try { + packageInfo = manager.getPackageInfo(packageName, PackageManager.GET_PROVIDERS); + } catch (android.content.pm.PackageManager.NameNotFoundException e) { + return; // No package info : we can't do anything + } + final ProviderInfo[] providers = packageInfo.providers; + if (null == providers) return; // No providers : it is not a dictionary. + + // Search for some dictionary pack in the just-installed package. If found, reread. + for (ProviderInfo info : providers) { + if (BinaryDictionary.DICTIONARY_PACK_AUTHORITY.equals(info.authority)) { + mService.resetSuggestMainDict(); + return; + } + } + // If we come here none of the authorities matched the one we searched for. + // We can exit safely. + return; + } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED) + && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + // When the dictionary package is removed, we need to reread dictionary (to use the + // next-priority one, or stop using a dictionary at all if this was the only one, + // since this is the user request). + // If we are replacing the package, we will receive ADDED right away so no need to + // remove the dictionary at the moment, since we will do it when we receive the + // ADDED broadcast. + + // TODO: Only reload dictionary on REMOVED when the removed package is the one we + // read dictionary from? + mService.resetSuggestMainDict(); + } else if (action.equals(NEW_DICTIONARY_INTENT_ACTION)) { + mService.resetSuggestMainDict(); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java index 90c250dcb..e56aa695d 100644 --- a/java/src/com/android/inputmethod/latin/EditingUtils.java +++ b/java/src/com/android/inputmethod/latin/EditingUtils.java @@ -16,13 +16,13 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.compat.InputConnectionCompatUtils; + import android.text.TextUtils; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.regex.Pattern; /** @@ -34,11 +34,6 @@ public class EditingUtils { */ private static final int LOOKBACK_CHARACTER_NUM = 15; - // Cache Method pointers - private static boolean sMethodsInitialized; - private static Method sMethodGetSelectedText; - private static Method sMethodSetComposingRegion; - private EditingUtils() { // Unintentional empty constructor for singleton. } @@ -78,7 +73,7 @@ public class EditingUtils { /** * @param connection connection to the current text field. - * @param sep characters which may separate words + * @param separators characters which may separate words * @return the word that surrounds the cursor, including up to one trailing * separator. For example, if the field contains "he|llo world", where | * represents the cursor, then "hello " will be returned. @@ -166,23 +161,62 @@ public class EditingUtils { private static final Pattern spaceRegex = Pattern.compile("\\s+"); + public static CharSequence getPreviousWord(InputConnection connection, String sentenceSeperators) { //TODO: Should fix this. This could be slow! CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0); - if (prev == null) { - return null; - } + return getPreviousWord(prev, sentenceSeperators); + } + + // Get the word before the whitespace preceding the non-whitespace preceding the cursor. + // Also, it won't return words that end in a separator. + // Example : + // "abc def|" -> abc + // "abc def |" -> abc + // "abc def. |" -> abc + // "abc def . |" -> def + // "abc|" -> null + // "abc |" -> null + // "abc. def|" -> null + public static CharSequence getPreviousWord(CharSequence prev, String sentenceSeperators) { + if (prev == null) return null; String[] w = spaceRegex.split(prev); - if (w.length >= 2 && w[w.length-2].length() > 0) { - char lastChar = w[w.length-2].charAt(w[w.length-2].length() -1); - if (sentenceSeperators.contains(String.valueOf(lastChar))) { - return null; - } - return w[w.length-2]; - } else { - return null; - } + + // If we can't find two words, or we found an empty word, return null. + if (w.length < 2 || w[w.length - 2].length() <= 0) return null; + + // If ends in a separator, return null + char lastChar = w[w.length - 2].charAt(w[w.length - 2].length() - 1); + if (sentenceSeperators.contains(String.valueOf(lastChar))) return null; + + return w[w.length - 2]; + } + + public static CharSequence getThisWord(InputConnection connection, String sentenceSeperators) { + final CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0); + return getThisWord(prev, sentenceSeperators); + } + + // Get the word immediately before the cursor, even if there is whitespace between it and + // the cursor - but not if there is punctuation. + // Example : + // "abc def|" -> def + // "abc def |" -> def + // "abc def. |" -> null + // "abc def . |" -> null + public static CharSequence getThisWord(CharSequence prev, String sentenceSeperators) { + if (prev == null) return null; + String[] w = spaceRegex.split(prev); + + // No word : return null + if (w.length < 1 || w[w.length - 1].length() <= 0) return null; + + // If ends in a separator, return null + char lastChar = w[w.length - 1].charAt(w[w.length - 1].length() - 1); + if (sentenceSeperators.contains(String.valueOf(lastChar))) return null; + + return w[w.length - 1]; } public static class SelectedWord { @@ -241,7 +275,8 @@ public class EditingUtils { } // Extract the selection alone - CharSequence touching = getSelectedText(ic, selStart, selEnd); + CharSequence touching = InputConnectionCompatUtils.getSelectedText( + ic, selStart, selEnd); if (TextUtils.isEmpty(touching)) return null; // Is any part of the selection a separator? If so, return null. final int length = touching.length(); @@ -255,74 +290,4 @@ public class EditingUtils { } return null; } - - /** - * Cache method pointers for performance - */ - private static void initializeMethodsForReflection() { - try { - // These will either both exist or not, so no need for separate try/catch blocks. - // If other methods are added later, use separate try/catch blocks. - sMethodGetSelectedText = InputConnection.class.getMethod("getSelectedText", int.class); - sMethodSetComposingRegion = InputConnection.class.getMethod("setComposingRegion", - int.class, int.class); - } catch (NoSuchMethodException exc) { - // Ignore - } - sMethodsInitialized = true; - } - - /** - * Returns the selected text between the selStart and selEnd positions. - */ - private static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) { - // Use reflection, for backward compatibility - CharSequence result = null; - if (!sMethodsInitialized) { - initializeMethodsForReflection(); - } - if (sMethodGetSelectedText != null) { - try { - result = (CharSequence) sMethodGetSelectedText.invoke(ic, 0); - return result; - } catch (InvocationTargetException exc) { - // Ignore - } catch (IllegalArgumentException e) { - // Ignore - } catch (IllegalAccessException e) { - // Ignore - } - } - // Reflection didn't work, try it the poor way, by moving the cursor to the start, - // getting the text after the cursor and moving the text back to selected mode. - // TODO: Verify that this works properly in conjunction with - // LatinIME#onUpdateSelection - ic.setSelection(selStart, selEnd); - result = ic.getTextAfterCursor(selEnd - selStart, 0); - ic.setSelection(selStart, selEnd); - return result; - } - - /** - * Tries to set the text into composition mode if there is support for it in the framework. - */ - public static void underlineWord(InputConnection ic, SelectedWord word) { - // Use reflection, for backward compatibility - // If method not found, there's nothing we can do. It still works but just wont underline - // the word. - if (!sMethodsInitialized) { - initializeMethodsForReflection(); - } - if (sMethodSetComposingRegion != null) { - try { - sMethodSetComposingRegion.invoke(ic, word.mStart, word.mEnd); - } catch (InvocationTargetException exc) { - // Ignore - } catch (IllegalArgumentException e) { - // Ignore - } catch (IllegalAccessException e) { - // Ignore - } - } - } } diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java index 0318175f6..97a4a1816 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java @@ -19,6 +19,8 @@ package com.android.inputmethod.latin; import android.content.Context; import android.os.AsyncTask; +import com.android.inputmethod.keyboard.Keyboard; + import java.util.LinkedList; /** @@ -32,14 +34,14 @@ public class ExpandableDictionary extends Dictionary { */ protected static final int MAX_WORD_LENGTH = 32; + // Bigram frequency is a fixed point number with 1 meaning 1.2 and 255 meaning 1.8. + protected static final int BIGRAM_MAX_FREQUENCY = 255; + private Context mContext; private char[] mWordBuilder = new char[MAX_WORD_LENGTH]; private int mDicTypeId; private int mMaxDepth; private int mInputLength; - private StringBuilder sb = new StringBuilder(MAX_WORD_LENGTH); - - private static final char QUOTE = '\''; private boolean mRequiresReload; @@ -98,6 +100,7 @@ public class ExpandableDictionary extends Dictionary { public int addFrequency(int add) { mFrequency += add; + if (mFrequency > BIGRAM_MAX_FREQUENCY) mFrequency = BIGRAM_MAX_FREQUENCY; return mFrequency; } } @@ -226,6 +229,7 @@ public class ExpandableDictionary extends Dictionary { * Returns the word's frequency or -1 if not found */ protected int getWordFrequency(CharSequence word) { + // Case-sensitive search Node node = searchNode(mRoots, word, 0, word.length()); return (node == null) ? -1 : node.mFrequency; } @@ -301,7 +305,8 @@ public class ExpandableDictionary extends Dictionary { getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex, skipPos, callback); } - } else if ((c == QUOTE && currentChars[0] != QUOTE) || depth == skipPos) { + } else if ((c == Keyboard.CODE_SINGLE_QUOTE + && currentChars[0] != Keyboard.CODE_SINGLE_QUOTE) || depth == skipPos) { // Skip the ' and continue deeper word[depth] = c; if (children != null) { @@ -327,7 +332,7 @@ public class ExpandableDictionary extends Dictionary { final int finalFreq; if (skipPos < 0) { finalFreq = freq * snr * addedAttenuation - * FULL_WORD_FREQ_MULTIPLIER; + * FULL_WORD_SCORE_MULTIPLIER; } else { finalFreq = computeSkippedWordFinalFreq(freq, snr * addedAttenuation, mInputLength); @@ -362,12 +367,16 @@ public class ExpandableDictionary extends Dictionary { /** * Adds bigrams to the in-memory trie structure that is being used to retrieve any word - * @param frequency frequency for this bigrams - * @param addFrequency if true, it adds to current frequency + * @param frequency frequency for this bigram + * @param addFrequency if true, it adds to current frequency, else it overwrites the old value * @return returns the final frequency */ private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) { - Node firstWord = searchWord(mRoots, word1, 0, null); + // We don't want results to be different according to case of the looked up left hand side + // word. We do want however to return the correct case for the right hand side. + // So we want to squash the case of the left hand side, and preserve that of the right + // hand side word. + Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigram = firstWord.mNGrams; if (bigram == null || bigram.size() == 0) { @@ -433,8 +442,12 @@ public class ExpandableDictionary extends Dictionary { } } - private void runReverseLookUp(final CharSequence previousWord, final WordCallback callback) { - Node prevWord = searchNode(mRoots, previousWord, 0, previousWord.length()); + private void runBigramReverseLookUp(final CharSequence previousWord, + final WordCallback callback) { + // Search for the lowercase version of the word only, because that's where bigrams + // store their sons. + Node prevWord = searchNode(mRoots, previousWord.toString().toLowerCase(), 0, + previousWord.length()); if (prevWord != null && prevWord.mNGrams != null) { reverseLookUp(prevWord.mNGrams, callback); } @@ -444,7 +457,7 @@ public class ExpandableDictionary extends Dictionary { public void getBigrams(final WordComposer codes, final CharSequence previousWord, final WordCallback callback) { if (!reloadDictionaryIfRequired()) { - runReverseLookUp(previousWord, callback); + runBigramReverseLookUp(previousWord, callback); } } @@ -462,6 +475,9 @@ public class ExpandableDictionary extends Dictionary { } } + // Local to reverseLookUp, but do not allocate each time. + private final char[] mLookedUpString = new char[MAX_WORD_LENGTH]; + /** * reverseLookUp retrieves the full word given a list of terminal nodes and adds those words * through callback. @@ -474,30 +490,33 @@ public class ExpandableDictionary extends Dictionary { for (NextWord nextWord : terminalNodes) { node = nextWord.mWord; freq = nextWord.getFrequency(); - // TODO Not the best way to limit suggestion threshold - if (freq >= UserBigramDictionary.SUGGEST_THRESHOLD) { - sb.setLength(0); - do { - sb.insert(0, node.mCode); - node = node.mParent; - } while(node != null); - - // TODO better way to feed char array? - callback.addWord(sb.toString().toCharArray(), 0, sb.length(), freq, mDicTypeId, - DataType.BIGRAM); - } + int index = MAX_WORD_LENGTH; + do { + --index; + mLookedUpString[index] = node.mCode; + node = node.mParent; + } while (node != null); + + callback.addWord(mLookedUpString, index, MAX_WORD_LENGTH - index, freq, mDicTypeId, + DataType.BIGRAM); } } /** - * Search for the terminal node of the word + * Recursively search for the terminal node of the word. + * + * One iteration takes the full word to search for and the current index of the recursion. + * + * @param children the node of the trie to search under. + * @param word the word to search for. Only read [offset..length] so there may be trailing chars + * @param offset the index in {@code word} this recursion should operate on. + * @param length the length of the input word. * @return Returns the terminal node of the word if the word exists */ private Node searchNode(final NodeArray children, final CharSequence word, final int offset, final int length) { - // TODO Consider combining with addWordRec final int count = children.mLength; - char currentChar = word.charAt(offset); + final char currentChar = word.charAt(offset); for (int j = 0; j < count; j++) { final Node node = children.mData[j]; if (node.mCode == currentChar) { diff --git a/java/src/com/android/inputmethod/latin/Flag.java b/java/src/com/android/inputmethod/latin/Flag.java new file mode 100644 index 000000000..3cb8f7e17 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/Flag.java @@ -0,0 +1,64 @@ +/* + * 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; + +public class Flag { + public final String mName; + public final int mResource; + public final int mMask; + public final int mSource; + + static private final int SOURCE_CONFIG = 1; + static private final int SOURCE_EXTRAVALUE = 2; + + public Flag(int resourceId, int mask) { + mName = null; + mResource = resourceId; + mSource = SOURCE_CONFIG; + mMask = mask; + } + + public Flag(String name, int mask) { + mName = name; + mResource = 0; + mSource = SOURCE_EXTRAVALUE; + mMask = mask; + } + + // If context/switcher are null, set all related flags in flagArray to on. + public static int initFlags(Flag[] flagArray, Context context, SubtypeSwitcher switcher) { + int flags = 0; + final Resources res = null == context ? null : context.getResources(); + for (Flag entry : flagArray) { + switch (entry.mSource) { + case Flag.SOURCE_CONFIG: + if (res == null || res.getBoolean(entry.mResource)) + flags |= entry.mMask; + break; + case Flag.SOURCE_EXTRAVALUE: + if (switcher == null || + switcher.currentSubtypeContainsExtraValueKey(entry.mName)) + flags |= entry.mMask; + break; + } + } + return flags; + } +} diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java deleted file mode 100644 index b58a57e42..000000000 --- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2008-2009 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.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceGroup; -import android.preference.PreferenceManager; -import android.text.TextUtils; - -import java.text.Collator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; - -public class InputLanguageSelection extends PreferenceActivity { - - private SharedPreferences mPrefs; - private String mSelectedLanguages; - private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>(); - private static final String[] BLACKLIST_LANGUAGES = { - "ko", "ja", "zh", "el", "zz" - }; - - private static class Loc implements Comparable<Object> { - private static Collator sCollator = Collator.getInstance(); - - private String mLabel; - public final Locale mLocale; - - public Loc(String label, Locale locale) { - this.mLabel = label; - this.mLocale = locale; - } - - public void setLabel(String label) { - this.mLabel = label; - } - - @Override - public String toString() { - return this.mLabel; - } - - @Override - public int compareTo(Object o) { - return sCollator.compare(this.mLabel, ((Loc) o).mLabel); - } - } - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - addPreferencesFromResource(R.xml.language_prefs); - // Get the settings preferences - mPrefs = PreferenceManager.getDefaultSharedPreferences(this); - mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, ""); - String[] languageList = mSelectedLanguages.split(","); - mAvailableLanguages = getUniqueLocales(); - PreferenceGroup parent = getPreferenceScreen(); - for (int i = 0; i < mAvailableLanguages.size(); i++) { - CheckBoxPreference pref = new CheckBoxPreference(this); - Locale locale = mAvailableLanguages.get(i).mLocale; - pref.setTitle(SubtypeSwitcher.getFullDisplayName(locale, true)); - boolean checked = isLocaleIn(locale, languageList); - pref.setChecked(checked); - if (hasDictionary(locale)) { - pref.setSummary(R.string.has_dictionary); - } - parent.addPreference(pref); - } - } - - private boolean isLocaleIn(Locale locale, String[] list) { - String lang = get5Code(locale); - for (int i = 0; i < list.length; i++) { - if (lang.equalsIgnoreCase(list[i])) return true; - } - return false; - } - - private boolean hasDictionary(Locale locale) { - final Resources res = getResources(); - final Configuration conf = res.getConfiguration(); - final Locale saveLocale = conf.locale; - boolean haveDictionary = false; - conf.locale = locale; - res.updateConfiguration(conf, res.getDisplayMetrics()); - - int mainDicResId = Utils.getMainDictionaryResourceId(res); - BinaryDictionary bd = BinaryDictionary.initDictionary(this, mainDicResId, Suggest.DIC_MAIN); - - // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of - // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. - if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) { - haveDictionary = true; - } - bd.close(); - conf.locale = saveLocale; - res.updateConfiguration(conf, res.getDisplayMetrics()); - return haveDictionary; - } - - private String get5Code(Locale locale) { - String country = locale.getCountry(); - return locale.getLanguage() - + (TextUtils.isEmpty(country) ? "" : "_" + country); - } - - @Override - protected void onResume() { - super.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - // Save the selected languages - String checkedLanguages = ""; - PreferenceGroup parent = getPreferenceScreen(); - int count = parent.getPreferenceCount(); - for (int i = 0; i < count; i++) { - CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); - if (pref.isChecked()) { - Locale locale = mAvailableLanguages.get(i).mLocale; - checkedLanguages += get5Code(locale) + ","; - } - } - if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null - Editor editor = mPrefs.edit(); - editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages); - SharedPreferencesCompat.apply(editor); - } - - public ArrayList<Loc> getUniqueLocales() { - String[] locales = getAssets().getLocales(); - Arrays.sort(locales); - ArrayList<Loc> uniqueLocales = new ArrayList<Loc>(); - - final int origSize = locales.length; - Loc[] preprocess = new Loc[origSize]; - int finalSize = 0; - for (int i = 0 ; i < origSize; i++ ) { - String s = locales[i]; - int len = s.length(); - if (len == 5) { - String language = s.substring(0, 2); - String country = s.substring(3, 5); - Locale l = new Locale(language, country); - - // Exclude languages that are not relevant to LatinIME - if (arrayContains(BLACKLIST_LANGUAGES, language)) continue; - - if (finalSize == 0) { - preprocess[finalSize++] = - new Loc(SubtypeSwitcher.getFullDisplayName(l, true), l); - } else { - // check previous entry: - // same lang and a country -> upgrade to full name and - // insert ours with full name - // diff lang -> insert ours with lang-only name - if (preprocess[finalSize-1].mLocale.getLanguage().equals( - language)) { - preprocess[finalSize-1].setLabel(SubtypeSwitcher.getFullDisplayName( - preprocess[finalSize-1].mLocale, false)); - preprocess[finalSize++] = - new Loc(SubtypeSwitcher.getFullDisplayName(l, false), l); - } else { - String displayName; - if (s.equals("zz_ZZ")) { - // ignore this locale - } else { - displayName = SubtypeSwitcher.getFullDisplayName(l, true); - preprocess[finalSize++] = new Loc(displayName, l); - } - } - } - } - } - for (int i = 0; i < finalSize ; i++) { - uniqueLocales.add(preprocess[i]); - } - return uniqueLocales; - } - - private boolean arrayContains(String[] array, String value) { - for (int i = 0; i < array.length; i++) { - if (array[i].equalsIgnoreCase(value)) return true; - } - return false; - } -} diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 6e76cadf2..6cb928321 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -16,15 +16,6 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.KeyboardActionListener; -import com.android.inputmethod.keyboard.KeyboardSwitcher; -import com.android.inputmethod.keyboard.KeyboardView; -import com.android.inputmethod.keyboard.LatinKeyboard; -import com.android.inputmethod.keyboard.LatinKeyboardView; -import com.android.inputmethod.latin.Utils.RingCharBuffer; -import com.android.inputmethod.voice.VoiceIMEConnector; - import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -42,7 +33,6 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.SystemClock; -import android.os.Vibrator; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.text.InputType; @@ -51,37 +41,42 @@ import android.util.DisplayMetrics; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; -import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; -import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; -import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; -import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.InputMethodSubtype; -import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; -import android.widget.LinearLayout; + +import com.android.inputmethod.compat.CompatUtils; +import com.android.inputmethod.compat.EditorInfoCompatUtils; +import com.android.inputmethod.compat.InputConnectionCompatUtils; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; +import com.android.inputmethod.compat.InputTypeCompatUtils; +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; +import com.android.inputmethod.deprecated.VoiceProxy; +import com.android.inputmethod.deprecated.recorrection.Recorrection; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardActionListener; +import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.keyboard.KeyboardView; +import com.android.inputmethod.keyboard.LatinKeyboard; +import com.android.inputmethod.keyboard.LatinKeyboardView; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Locale; /** * Input method implementation for Qwerty'ish keyboard. */ -public class LatinIME extends InputMethodService implements KeyboardActionListener { +public class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener { private static final String TAG = LatinIME.class.getSimpleName(); private static final boolean PERF_DEBUG = false; private static final boolean TRACE = false; @@ -94,6 +89,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen * * @deprecated Use {@link LatinIME#IME_OPTION_NO_MICROPHONE} with package name prefixed. */ + @SuppressWarnings("dep-ann") public static final String IME_OPTION_NO_MICROPHONE_COMPAT = "nm"; /** @@ -109,9 +105,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen */ public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey"; - private static final int DELAY_UPDATE_SUGGESTIONS = 180; - private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300; - private static final int DELAY_UPDATE_SHIFT_STATE = 300; private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; // How many continuous deletes at which to start deleting at a higher speed. @@ -119,6 +112,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Key events coming any faster than this are long-presses. private static final int QUICK_PRESS = 200; + /** + * The name of the scheme used by the Package Manager to warn of a new package installation, + * replacement or removal. + */ + private static final String SCHEME_PACKAGE = "package"; + private int mSuggestionVisibility; private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE = R.string.prefs_suggestion_visibility_show_value; @@ -133,55 +132,45 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen SUGGESTION_VISIBILILTY_HIDE_VALUE }; + private Settings.Values mSettingsValues; + private View mCandidateViewContainer; + private int mCandidateStripHeight; private CandidateView mCandidateView; private Suggest mSuggest; private CompletionInfo[] mApplicationSpecifiedCompletions; private AlertDialog mOptionsDialog; - private InputMethodManager mImm; + private InputMethodManagerCompatWrapper mImm; private Resources mResources; private SharedPreferences mPrefs; private String mInputMethodId; private KeyboardSwitcher mKeyboardSwitcher; private SubtypeSwitcher mSubtypeSwitcher; - private VoiceIMEConnector mVoiceConnector; + private VoiceProxy mVoiceProxy; + private Recorrection mRecorrection; private UserDictionary mUserDictionary; private UserBigramDictionary mUserBigramDictionary; private ContactsDictionary mContactsDictionary; private AutoDictionary mAutoDictionary; + // TODO: Create an inner class to group options and pseudo-options to improve readability. // These variables are initialized according to the {@link EditorInfo#inputType}. - private boolean mAutoSpace; + private boolean mShouldInsertMagicSpace; private boolean mInputTypeNoAutoCorrect; private boolean mIsSettingsSuggestionStripOn; private boolean mApplicationSpecifiedCompletionOn; - private AccessibilityUtils mAccessibilityUtils; - private final StringBuilder mComposing = new StringBuilder(); private WordComposer mWord = new WordComposer(); private CharSequence mBestWord; - private boolean mHasValidSuggestions; + private boolean mHasUncommittedTypedChars; private boolean mHasDictionary; - private boolean mJustAddedAutoSpace; - private boolean mAutoCorrectEnabled; - private boolean mRecorrectionEnabled; - private boolean mBigramSuggestionEnabled; - private boolean mAutoCorrectOn; - private boolean mVibrateOn; - private boolean mSoundOn; - private boolean mPopupOn; - private boolean mAutoCap; - private boolean mQuickFixes; - private boolean mConfigEnableShowSubtypeSettings; - private boolean mConfigSwipeDownDismissKeyboardEnabled; - private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; - private int mConfigDurationOfFadeoutLanguageOnSpacebar; - private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar; - private long mConfigDoubleSpacesTurnIntoPeriodTimeout; + // Magic space: a space that should disappear on space/apostrophe insertion, move after the + // punctuation on punctuation insertion, and become a real space on alpha char insertion. + private boolean mJustAddedMagicSpace; // This indicates whether the last char is a magic space. private int mCorrectionMode; private int mCommittedLength; @@ -189,7 +178,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Keep track of the last selection range to decide if we need to show word alternatives private int mLastSelectionStart; private int mLastSelectionEnd; - private SuggestedWords mSuggestPuncList; // Indicates whether the suggestion strip is to be on in landscape private boolean mJustAccepted; @@ -199,66 +187,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private AudioManager mAudioManager; // Align sound effect volume on music volume private static final float FX_VOLUME = -1.0f; - private boolean mSilentMode; + private boolean mSilentModeOn; // System-wide current configuration - /* package */ String mWordSeparators; - private String mSentenceSeparators; - private String mSuggestPuncs; - // TODO: Move this flag to VoiceIMEConnector + // TODO: Move this flag to VoiceProxy private boolean mConfigurationChanging; + // Object for reacting to adding/removing a dictionary pack. + private BroadcastReceiver mDictionaryPackInstallReceiver = + new DictionaryPackInstallBroadcastReceiver(this); + // Keeps track of most recently inserted text (multi-character key) for reverting private CharSequence mEnteredText; - private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>(); - - public abstract static class WordAlternatives { - protected CharSequence mChosenWord; - - public WordAlternatives() { - // Nothing - } - - public WordAlternatives(CharSequence chosenWord) { - mChosenWord = chosenWord; - } - - @Override - public int hashCode() { - return mChosenWord.hashCode(); - } - - public abstract CharSequence getOriginalWord(); - - public CharSequence getChosenWord() { - return mChosenWord; - } - - public abstract SuggestedWords.Builder getAlternatives(); - } - - public class TypedWordAlternatives extends WordAlternatives { - private WordComposer word; - - public TypedWordAlternatives() { - // Nothing - } - - public TypedWordAlternatives(CharSequence chosenWord, WordComposer wordComposer) { - super(chosenWord); - word = wordComposer; - } - - @Override - public CharSequence getOriginalWord() { - return word.getTypedWord(); - } - - @Override - public SuggestedWords.Builder getAlternatives() { - return getTypedSuggestions(word); - } - } public final UIHandler mHandler = new UIHandler(); @@ -270,44 +210,54 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4; private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; private static final int MSG_SPACE_TYPED = 6; + private static final int MSG_SET_BIGRAM_PREDICTIONS = 7; @Override public void handleMessage(Message msg) { final KeyboardSwitcher switcher = mKeyboardSwitcher; - final LatinKeyboardView inputView = switcher.getInputView(); + final LatinKeyboardView inputView = switcher.getKeyboardView(); switch (msg.what) { case MSG_UPDATE_SUGGESTIONS: updateSuggestions(); break; case MSG_UPDATE_OLD_SUGGESTIONS: - setOldSuggestions(); + mRecorrection.setRecorrectionSuggestions(mVoiceProxy, mCandidateView, mSuggest, + mKeyboardSwitcher, mWord, mHasUncommittedTypedChars, mLastSelectionStart, + mLastSelectionEnd, mSettingsValues.mWordSeparators); break; case MSG_UPDATE_SHIFT_STATE: switcher.updateShiftState(); break; + case MSG_SET_BIGRAM_PREDICTIONS: + updateBigramPredictions(); + break; case MSG_VOICE_RESULTS: - mVoiceConnector.handleVoiceResults(preferCapitalization() + mVoiceProxy.handleVoiceResults(preferCapitalization() || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); break; case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: - if (inputView != null) + if (inputView != null) { inputView.setSpacebarTextFadeFactor( - (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2, + (1.0f + mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar) / 2, (LatinKeyboard)msg.obj); + } sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), - mConfigDurationOfFadeoutLanguageOnSpacebar); + mSettingsValues.mDurationOfFadeoutLanguageOnSpacebar); break; case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: - if (inputView != null) + if (inputView != null) { inputView.setSpacebarTextFadeFactor( - mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); + mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, + (LatinKeyboard)msg.obj); + } break; } } public void postUpdateSuggestions() { removeMessages(MSG_UPDATE_SUGGESTIONS); - sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), DELAY_UPDATE_SUGGESTIONS); + sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), + mSettingsValues.mDelayUpdateSuggestions); } public void cancelUpdateSuggestions() { @@ -321,7 +271,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void postUpdateOldSuggestions() { removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), - DELAY_UPDATE_OLD_SUGGESTIONS); + mSettingsValues.mDelayUpdateOldSuggestions); } public void cancelUpdateOldSuggestions() { @@ -330,13 +280,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void postUpdateShiftKeyState() { removeMessages(MSG_UPDATE_SHIFT_STATE); - sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), DELAY_UPDATE_SHIFT_STATE); + sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), + mSettingsValues.mDelayUpdateShiftState); } public void cancelUpdateShiftState() { removeMessages(MSG_UPDATE_SHIFT_STATE); } + public void postUpdateBigramPredictions() { + removeMessages(MSG_SET_BIGRAM_PREDICTIONS); + sendMessageDelayed(obtainMessage(MSG_SET_BIGRAM_PREDICTIONS), + mSettingsValues.mDelayUpdateSuggestions); + } + + public void cancelUpdateBigramPredictions() { + removeMessages(MSG_SET_BIGRAM_PREDICTIONS); + } + public void updateVoiceResults() { sendMessage(obtainMessage(MSG_VOICE_RESULTS)); } @@ -344,17 +305,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void startDisplayLanguageOnSpacebar(boolean localeChanged) { removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); - final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); + final LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) { final LatinKeyboard keyboard = mKeyboardSwitcher.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) { + final boolean needsToDisplayLanguage = localeChanged + || mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar < 0; + // The language is never displayed when the delay is zero. + if (mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar != 0) { + inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f + : mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); + } + // The fadeout animation will start when the delay is positive. + if (localeChanged && mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar > 0) { sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), - mConfigDelayBeforeFadeoutLanguageOnSpacebar); + mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar); } } } @@ -362,7 +327,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void startDoubleSpacesTimer() { removeMessages(MSG_SPACE_TYPED); sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED), - mConfigDoubleSpacesTurnIntoPeriodTimeout); + mSettingsValues.mDoubleSpacesTurnIntoPeriodTimeout); } public void cancelDoubleSpacesTimer() { @@ -379,43 +344,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); mPrefs = prefs; LatinImeLogger.init(this, prefs); + LanguageSwitcherProxy.init(this, prefs); SubtypeSwitcher.init(this, prefs); KeyboardSwitcher.init(this, prefs); - AccessibilityUtils.init(this, prefs); + Recorrection.init(this, prefs); super.onCreate(); - mImm = ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)); + mImm = InputMethodManagerCompatWrapper.getInstance(this); mInputMethodId = Utils.getInputMethodId(mImm, getPackageName()); mSubtypeSwitcher = SubtypeSwitcher.getInstance(); mKeyboardSwitcher = KeyboardSwitcher.getInstance(); - mAccessibilityUtils = AccessibilityUtils.getInstance(); + mRecorrection = Recorrection.getInstance(); + + loadSettings(); final Resources res = getResources(); mResources = res; - // 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.config_default_recorrection_enabled)); - } else { - mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled); - } - - mConfigEnableShowSubtypeSettings = res.getBoolean( - R.bool.config_enable_show_subtype_settings); - mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( - 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; - mConfigDoubleSpacesTurnIntoPeriodTimeout = res.getInteger( - R.integer.config_double_spaces_turn_into_period_timeout); - Utils.GCUtils.getInstance().reset(); boolean tryGC = true; for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { @@ -428,49 +374,73 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } mOrientation = res.getConfiguration().orientation; - initSuggestPuncList(); - // register to receive ringer mode change and network state change. + // Register to receive ringer mode change and network state change. + // Also receive installation and removal of a dictionary pack. final IntentFilter filter = new IntentFilter(); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(mReceiver, filter); - mVoiceConnector = VoiceIMEConnector.init(this, prefs, mHandler); + mVoiceProxy = VoiceProxy.init(this, prefs, mHandler); + + final IntentFilter packageFilter = new IntentFilter(); + packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + packageFilter.addDataScheme(SCHEME_PACKAGE); + registerReceiver(mDictionaryPackInstallReceiver, packageFilter); + + final IntentFilter newDictFilter = new IntentFilter(); + newDictFilter.addAction( + DictionaryPackInstallBroadcastReceiver.NEW_DICTIONARY_INTENT_ACTION); + registerReceiver(mDictionaryPackInstallReceiver, newDictFilter); + } + + // Has to be package-visible for unit tests + /* package */ void loadSettings() { + if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); + if (null == mSubtypeSwitcher) mSubtypeSwitcher = SubtypeSwitcher.getInstance(); + mSettingsValues = new Settings.Values(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr()); } private void initSuggest() { - String locale = mSubtypeSwitcher.getInputLocaleStr(); + final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); + final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr); - Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(new Locale(locale)); + final Resources res = mResources; + final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale); if (mSuggest != null) { mSuggest.close(); } - final SharedPreferences prefs = mPrefs; - mQuickFixes = isQuickFixesEnabled(prefs); - final Resources res = mResources; int mainDicResId = Utils.getMainDictionaryResourceId(res); - mSuggest = new Suggest(this, mainDicResId); - loadAndSetAutoCorrectionThreshold(prefs); + mSuggest = new Suggest(this, mainDicResId, keyboardLocale); + if (mSettingsValues.mAutoCorrectEnabled) { + mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); + } updateAutoTextEnabled(); - mUserDictionary = new UserDictionary(this, locale); + mUserDictionary = new UserDictionary(this, localeStr); mSuggest.setUserDictionary(mUserDictionary); mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS); mSuggest.setContactsDictionary(mContactsDictionary); - mAutoDictionary = new AutoDictionary(this, this, locale, Suggest.DIC_AUTO); + mAutoDictionary = new AutoDictionary(this, this, localeStr, Suggest.DIC_AUTO); mSuggest.setAutoDictionary(mAutoDictionary); - mUserBigramDictionary = new UserBigramDictionary(this, this, locale, Suggest.DIC_USER); + mUserBigramDictionary = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER); mSuggest.setUserBigramDictionary(mUserBigramDictionary); updateCorrectionMode(); - mWordSeparators = res.getString(R.string.word_separators); - mSentenceSeparators = res.getString(R.string.sentence_separators); - mSubtypeSwitcher.changeSystemLocale(savedLocale); + Utils.setSystemLocale(res, savedLocale); + } + + /* package private */ void resetSuggestMainDict() { + final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); + final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr); + int mainDicResId = Utils.getMainDictionaryResourceId(mResources); + mSuggest.resetMainDict(this, mainDicResId, keyboardLocale); } @Override @@ -480,7 +450,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mSuggest = null; } unregisterReceiver(mReceiver); - mVoiceConnector.destroy(); + unregisterReceiver(mDictionaryPackInstallReceiver); + mVoiceProxy.destroy(); LatinImeLogger.commit(); LatinImeLogger.onDestroy(); super.onDestroy(); @@ -501,38 +472,34 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mConfigurationChanging = true; super.onConfigurationChanged(conf); - mVoiceConnector.onConfigurationChanged(conf); + mVoiceProxy.onConfigurationChanged(conf); mConfigurationChanging = false; + + // This will work only when the subtype is not supported. + LanguageSwitcherProxy.onConfigurationChanged(conf); } @Override public View onCreateInputView() { - return mKeyboardSwitcher.onCreateInputView(); + final View inputView = mKeyboardSwitcher.onCreateInputView(); + mCandidateViewContainer = inputView.findViewById(R.id.candidates_container); + mCandidateView = (CandidateView) inputView.findViewById(R.id.candidates); + mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height); + return inputView; } @Override - public View onCreateCandidatesView() { - LayoutInflater inflater = getLayoutInflater(); - LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); - mCandidateViewContainer = container; - if (container.getPaddingRight() != 0) { - HorizontalScrollView scrollView = - (HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view); - scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); - container.setGravity(Gravity.CENTER_HORIZONTAL); - } - mCandidateView = (CandidateView) container.findViewById(R.id.candidates); - mCandidateView.setService(this); - setCandidatesViewShown(true); - return container; + public void setCandidatesView(View view) { + // To ensure that CandidatesView will never be set. + return; } @Override public void onStartInputView(EditorInfo attribute, boolean restarting) { final KeyboardSwitcher switcher = mKeyboardSwitcher; - LatinKeyboardView inputView = switcher.getInputView(); + LatinKeyboardView inputView = switcher.getKeyboardView(); - if(DEBUG) { + if (DEBUG) { Log.d(TAG, "onStartInputView: " + inputView); } // In landscape mode, this method gets called without the input view being created. @@ -547,20 +514,31 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to // know now whether this is a password text field, because we need to know now whether we // want to enable the voice button. - final VoiceIMEConnector voiceIme = mVoiceConnector; - voiceIme.resetVoiceStates(Utils.isPasswordInputType(attribute.inputType) - || Utils.isVisiblePasswordInputType(attribute.inputType)); + final VoiceProxy voiceIme = mVoiceProxy; + voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(attribute.inputType) + || InputTypeCompatUtils.isVisiblePasswordInputType(attribute.inputType)); initializeInputAttributes(attribute); inputView.closing(); mEnteredText = null; mComposing.setLength(0); - mHasValidSuggestions = false; + mHasUncommittedTypedChars = false; mDeleteCount = 0; - mJustAddedAutoSpace = false; + mJustAddedMagicSpace = false; + + loadSettings(); + updateCorrectionMode(); + updateAutoTextEnabled(); + updateSuggestionVisibility(mPrefs, mResources); + + if (mSuggest != null && mSettingsValues.mAutoCorrectEnabled) { + mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); + } + mVoiceProxy.loadSettings(attribute, mPrefs); + // This will work only when the subtype is not supported. + LanguageSwitcherProxy.loadSettings(); - loadSettings(attribute); if (mSubtypeSwitcher.isKeyboardMode()) { switcher.loadKeyboard(attribute, mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(), @@ -568,20 +546,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen switcher.updateShiftState(); } - setCandidatesViewShownInternal(isCandidateStripVisible(), - false /* needsInputViewShown */ ); + setSuggestionStripShownInternal(isCandidateStripVisible(), /* needsInputViewShown */ false); // Delay updating suggestions because keyboard input view may not be shown at this point. mHandler.postUpdateSuggestions(); updateCorrectionMode(); - final boolean accessibilityEnabled = mAccessibilityUtils.isAccessibilityEnabled(); - - inputView.setPreviewEnabled(mPopupOn); + inputView.setKeyPreviewPopupEnabled(mSettingsValues.mKeyPreviewPopupOn, + mSettingsValues.mKeyPreviewPopupDismissDelay); inputView.setProximityCorrectionEnabled(true); - inputView.setAccessibilityEnabled(accessibilityEnabled); // If we just entered a text field, maybe it has some old text that requires correction - checkRecorrectionOnStart(); + mRecorrection.checkRecorrectionOnStart(); inputView.setForeground(true); voiceIme.onStartInputView(inputView.getWindowToken()); @@ -594,7 +569,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; final int inputType = attribute.inputType; final int variation = inputType & InputType.TYPE_MASK_VARIATION; - mAutoSpace = false; + mShouldInsertMagicSpace = false; mInputTypeNoAutoCorrect = false; mIsSettingsSuggestionStripOn = false; mApplicationSpecifiedCompletionOn = false; @@ -603,17 +578,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) { mIsSettingsSuggestionStripOn = true; // Make sure that passwords are not displayed in candidate view - if (Utils.isPasswordInputType(inputType) - || Utils.isVisiblePasswordInputType(inputType)) { + if (InputTypeCompatUtils.isPasswordInputType(inputType) + || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)) { mIsSettingsSuggestionStripOn = false; } - if (Utils.isEmailVariation(variation) + if (InputTypeCompatUtils.isEmailVariation(variation) || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) { - mAutoSpace = false; + mShouldInsertMagicSpace = false; } else { - mAutoSpace = true; + mShouldInsertMagicSpace = true; } - if (Utils.isEmailVariation(variation)) { + if (InputTypeCompatUtils.isEmailVariation(variation)) { mIsSettingsSuggestionStripOn = false; } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { mIsSettingsSuggestionStripOn = false; @@ -644,32 +619,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - private void checkRecorrectionOnStart() { - if (!mRecorrectionEnabled) return; - - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - // There could be a pending composing span. Clean it up first. - ic.finishComposingText(); - - if (isShowingSuggestionsStrip() && isSuggestionsRequested()) { - // First get the cursor position. This is required by setOldSuggestions(), so that - // it can pass the correct range to setComposingRegion(). At this point, we don't - // have valid values for mLastSelectionStart/End because onUpdateSelection() has - // not been called yet. - ExtractedTextRequest etr = new ExtractedTextRequest(); - etr.token = 0; // anything is fine here - ExtractedText et = ic.getExtractedText(etr, 0); - if (et == null) return; - - mLastSelectionStart = et.startOffset + et.selectionStart; - mLastSelectionEnd = et.startOffset + et.selectionEnd; - - // Then look for possible corrections in a delayed fashion - if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) { - mHandler.postUpdateOldSuggestions(); - } - } + @Override + public void onWindowHidden() { + super.onWindowHidden(); + KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); + if (inputView != null) inputView.closing(); } @Override @@ -679,9 +633,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen LatinImeLogger.commit(); mKeyboardSwitcher.onAutoCorrectionStateChanged(false); - mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging); + mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging); - KeyboardView inputView = mKeyboardSwitcher.getInputView(); + KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.closing(); if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); @@ -690,7 +644,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onFinishInputView(boolean finishingInput) { super.onFinishInputView(finishingInput); - KeyboardView inputView = mKeyboardSwitcher.getInputView(); + KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.setForeground(false); // Remove pending messages related to update suggestions mHandler.cancelUpdateSuggestions(); @@ -700,7 +654,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onUpdateExtractedText(int token, ExtractedText text) { super.onUpdateExtractedText(token, text); - mVoiceConnector.showPunctuationHintIfNecessary(); + mVoiceProxy.showPunctuationHintIfNecessary(); } @Override @@ -721,36 +675,41 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen + ", ce=" + candidatesEnd); } - mVoiceConnector.setCursorAndSelection(newSelEnd, newSelStart); + mVoiceProxy.setCursorAndSelection(newSelEnd, newSelStart); // If the current selection in the text view changes, we should // clear whatever candidate text we have. final boolean selectionChanged = (newSelStart != candidatesEnd || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart; final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1; - if (((mComposing.length() > 0 && mHasValidSuggestions) - || mVoiceConnector.isVoiceInputHighlighted()) + if (((mComposing.length() > 0 && mHasUncommittedTypedChars) + || mVoiceProxy.isVoiceInputHighlighted()) && (selectionChanged || candidatesCleared)) { if (candidatesCleared) { // If the composing span has been cleared, save the typed word in the history for // recorrection before we reset the candidate strip. Then, we'll be able to show // suggestions for recorrection right away. - saveWordInHistory(mComposing); + mRecorrection.saveRecorrectionSuggestion(mWord, mComposing); } mComposing.setLength(0); - mHasValidSuggestions = false; - mHandler.postUpdateSuggestions(); + mHasUncommittedTypedChars = false; + if (isCursorTouchingWord()) { + mHandler.cancelUpdateBigramPredictions(); + mHandler.postUpdateSuggestions(); + } else { + setPunctuationSuggestions(); + } TextEntryState.reset(); InputConnection ic = getCurrentInputConnection(); if (ic != null) { ic.finishComposingText(); } - mVoiceConnector.setVoiceInputHighlighted(false); - } else if (!mHasValidSuggestions && !mJustAccepted) { + mVoiceProxy.setVoiceInputHighlighted(false); + } else if (!mHasUncommittedTypedChars && !mJustAccepted) { if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) { if (TextEntryState.isAcceptedDefault()) TextEntryState.reset(); - mJustAddedAutoSpace = false; // The user moved the cursor. + mJustAddedMagicSpace = false; // The user moved the cursor. } } mJustAccepted = false; @@ -760,28 +719,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mLastSelectionStart = newSelStart; mLastSelectionEnd = newSelEnd; - if (mRecorrectionEnabled && isShowingSuggestionsStrip()) { - // Don't look for corrections if the keyboard is not visible - if (mKeyboardSwitcher.isInputViewShown()) { - // Check if we should go in or out of correction mode. - if (isSuggestionsRequested() - && (candidatesStart == candidatesEnd || newSelStart != oldSelStart - || TextEntryState.isRecorrecting()) - && (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) { - if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) { - mHandler.postUpdateOldSuggestions(); - } else { - abortRecorrection(false); - // Show the punctuation suggestions list if the current one is not - // and if not showing "Touch again to save". - if (mCandidateView != null && !isShowingPunctuationList() - && !mCandidateView.isShowingAddToDictionaryHint()) { - setPunctuationSuggestions(); - } - } - } - } - } + mRecorrection.updateRecorrectionSelection(mKeyboardSwitcher, + mCandidateView, candidatesStart, candidatesEnd, newSelStart, + newSelEnd, oldSelStart, mLastSelectionStart, + mLastSelectionEnd, mHasUncommittedTypedChars); + } + + public void setLastSelection(int start, int end) { + mLastSelectionStart = start; + mLastSelectionEnd = end; } /** @@ -794,7 +740,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen */ @Override public void onExtractedTextClicked() { - if (mRecorrectionEnabled && isSuggestionsRequested()) return; + if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return; super.onExtractedTextClicked(); } @@ -810,7 +756,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen */ @Override public void onExtractedCursorMovement(int dx, int dy) { - if (mRecorrectionEnabled && isSuggestionsRequested()) return; + if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return; super.onExtractedCursorMovement(dx, dy); } @@ -825,8 +771,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mOptionsDialog.dismiss(); mOptionsDialog = null; } - mVoiceConnector.hideVoiceWindow(mConfigurationChanging); - mWordHistory.clear(); + mVoiceProxy.hideVoiceWindow(mConfigurationChanging); + mRecorrection.clearWordsInHistory(); super.hideWindow(); } @@ -854,57 +800,58 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // When in fullscreen mode, show completions generated by the application setSuggestions(builder.build()); mBestWord = null; - setCandidatesViewShown(true); + setSuggestionStripShown(true); } } - private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { - // TODO: Remove this if we support candidates with hard keyboard + private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) { + // TODO: Modify this if we support candidates with hard keyboard if (onEvaluateInputViewShown()) { - super.setCandidatesViewShown(shown - && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true)); + final boolean shouldShowCandidates = shown + && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); + if (isExtractViewShown()) { + // No need to have extra space to show the key preview. + mCandidateViewContainer.setMinimumHeight(0); + mCandidateViewContainer.setVisibility( + shouldShowCandidates ? View.VISIBLE : View.GONE); + } else { + // We must control the visibility of the suggestion strip in order to avoid clipped + // key previews, even when we don't show the suggestion strip. + mCandidateViewContainer.setVisibility( + shouldShowCandidates ? View.VISIBLE : View.INVISIBLE); + } } } - @Override - public void setCandidatesViewShown(boolean shown) { - setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ ); + private void setSuggestionStripShown(boolean shown) { + setSuggestionStripShownInternal(shown, /* needsInputViewShown */true); } @Override public void onComputeInsets(InputMethodService.Insets outInsets) { super.onComputeInsets(outInsets); - if (!isFullscreenMode()) { - outInsets.contentTopInsets = outInsets.visibleTopInsets; - } - KeyboardView inputView = mKeyboardSwitcher.getInputView(); + final KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); + if (inputView == null) + return; + final int containerHeight = mCandidateViewContainer.getHeight(); + int touchY = containerHeight; // Need to set touchable region only if input view is being shown - if (inputView != null && mKeyboardSwitcher.isInputViewShown()) { - final int x = 0; - int y = 0; - final int width = inputView.getWidth(); - int height = inputView.getHeight() + EXTENDED_TOUCHABLE_REGION_HEIGHT; - if (mCandidateViewContainer != null) { - ViewParent candidateParent = mCandidateViewContainer.getParent(); - if (candidateParent instanceof FrameLayout) { - FrameLayout fl = (FrameLayout) candidateParent; - if (fl != null) { - // Check frame layout's visibility - if (fl.getVisibility() == View.INVISIBLE) { - y = fl.getHeight(); - height += y; - } else if (fl.getVisibility() == View.VISIBLE) { - height += fl.getHeight(); - } - } - } + if (mKeyboardSwitcher.isInputViewShown()) { + if (mCandidateViewContainer.getVisibility() == View.VISIBLE) { + touchY -= mCandidateStripHeight; } + final int touchWidth = inputView.getWidth(); + final int touchHeight = inputView.getHeight() + containerHeight + // Extend touchable region below the keyboard. + + EXTENDED_TOUCHABLE_REGION_HEIGHT; if (DEBUG) { - Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height); + Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth + + " height=" + touchHeight); } - outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; - outInsets.touchableRegion.set(x, y, width, height); + setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight); } + outInsets.contentTopInsets = touchY; + outInsets.visibleTopInsets = touchY; } @Override @@ -925,8 +872,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: - if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) { - if (mKeyboardSwitcher.getInputView().handleBack()) { + if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getKeyboardView() != null) { + if (mKeyboardSwitcher.getKeyboardView().handleBack()) { return true; } } @@ -960,8 +907,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void commitTyped(InputConnection inputConnection) { - if (mHasValidSuggestions) { - mHasValidSuggestions = false; + if (mHasUncommittedTypedChars) { + mHasUncommittedTypedChars = false; if (mComposing.length() > 0) { if (inputConnection != null) { inputConnection.commitText(mComposing, 1); @@ -977,45 +924,29 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public boolean getCurrentAutoCapsState() { InputConnection ic = getCurrentInputConnection(); EditorInfo ei = getCurrentInputEditorInfo(); - if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) { + if (mSettingsValues.mAutoCap && ic != null && ei != null + && ei.inputType != InputType.TYPE_NULL) { return ic.getCursorCapsMode(ei.inputType) != 0; } return false; } - private void swapPunctuationAndSpace() { + private void swapSwapperAndSpace() { final InputConnection ic = getCurrentInputConnection(); if (ic == null) return; CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); + // It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called. if (lastTwo != null && lastTwo.length() == 2 - && lastTwo.charAt(0) == Keyboard.CODE_SPACE - && isSentenceSeparator(lastTwo.charAt(1))) { + && lastTwo.charAt(0) == Keyboard.CODE_SPACE) { ic.beginBatchEdit(); ic.deleteSurroundingText(2, 0); ic.commitText(lastTwo.charAt(1) + " ", 1); ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); - mJustAddedAutoSpace = true; } } - private void reswapPeriodAndSpace() { - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - CharSequence lastThree = ic.getTextBeforeCursor(3, 0); - if (lastThree != null && lastThree.length() == 3 - && lastThree.charAt(0) == Keyboard.CODE_PERIOD - && lastThree.charAt(1) == Keyboard.CODE_SPACE - && lastThree.charAt(2) == Keyboard.CODE_PERIOD) { - ic.beginBatchEdit(); - ic.deleteSurroundingText(3, 0); - ic.commitText(" ..", 1); - ic.endBatchEdit(); - mKeyboardSwitcher.updateShiftState(); - } - } - - private void doubleSpace() { + private void maybeDoubleSpace() { if (mCorrectionMode == Suggest.CORRECTION_NONE) return; final InputConnection ic = getCurrentInputConnection(); if (ic == null) return; @@ -1031,7 +962,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen ic.commitText(". ", 1); ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); - mJustAddedAutoSpace = true; } else { mHandler.startDoubleSpacesTimer(); } @@ -1079,14 +1009,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private void onSettingsKeyPressed() { - if (!isShowingOptionDialog()) { - if (!mConfigEnableShowSubtypeSettings) { - showSubtypeSelectorAndSettings(); - } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { - showOptionsMenu(); - } else { - launchSettings(); - } + if (isShowingOptionDialog()) + return; + if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) { + showSubtypeSelectorAndSettings(); + } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { + showOptionsMenu(); + } else { + launchSettings(); } } @@ -1113,7 +1043,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } mLastKeyTime = when; KeyboardSwitcher switcher = mKeyboardSwitcher; - final boolean accessibilityEnabled = switcher.isAccessibilityEnabled(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); switch (primaryCode) { case Keyboard.CODE_DELETE: @@ -1123,12 +1052,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; case Keyboard.CODE_SHIFT: // Shift key is handled in onPress() when device has distinct multi-touch panel. - if (!distinctMultiTouch || accessibilityEnabled) + if (!distinctMultiTouch) switcher.toggleShift(); break; case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: // Symbol key is handled in onPress() when device has distinct multi-touch panel. - if (!distinctMultiTouch || accessibilityEnabled) + if (!distinctMultiTouch) switcher.changeKeyboardMode(); break; case Keyboard.CODE_CANCEL: @@ -1142,29 +1071,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen case Keyboard.CODE_SETTINGS_LONGPRESS: onSettingsKeyLongPressed(); break; - case Keyboard.CODE_NEXT_LANGUAGE: - toggleLanguage(false, true); + case LatinKeyboard.CODE_NEXT_LANGUAGE: + toggleLanguage(true); break; - case Keyboard.CODE_PREV_LANGUAGE: - toggleLanguage(false, false); + case LatinKeyboard.CODE_PREV_LANGUAGE: + toggleLanguage(false); break; case Keyboard.CODE_CAPSLOCK: switcher.toggleCapsLock(); break; - case Keyboard.CODE_VOICE: + case Keyboard.CODE_SHORTCUT: mSubtypeSwitcher.switchToShortcutIME(); break; case Keyboard.CODE_TAB: handleTab(); break; default: - if (primaryCode != Keyboard.CODE_ENTER) { - mJustAddedAutoSpace = false; - } - RingCharBuffer.getInstance().push((char)primaryCode, x, y); - LatinImeLogger.logOnInputChar(); - if (isWordSeparator(primaryCode)) { - handleSeparator(primaryCode); + if (mSettingsValues.isWordSeparator(primaryCode)) { + handleSeparator(primaryCode, x, y); } else { handleCharacter(primaryCode, keyCodes, x, y); } @@ -1176,10 +1100,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onTextInput(CharSequence text) { - mVoiceConnector.commitVoiceInput(); + mVoiceProxy.commitVoiceInput(); InputConnection ic = getCurrentInputConnection(); if (ic == null) return; - abortRecorrection(false); + mRecorrection.abortRecorrection(false); ic.beginBatchEdit(); commitTyped(ic); maybeRemovePreviousPeriod(text); @@ -1187,7 +1111,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); - mJustAddedAutoSpace = false; + mJustAddedMagicSpace = false; mEnteredText = text; } @@ -1198,25 +1122,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private void handleBackspace() { - if (mVoiceConnector.logAndRevertVoiceInput()) return; + if (mVoiceProxy.logAndRevertVoiceInput()) return; final InputConnection ic = getCurrentInputConnection(); if (ic == null) return; ic.beginBatchEdit(); - mVoiceConnector.handleBackspace(); + mVoiceProxy.handleBackspace(); boolean deleteChar = false; - if (mHasValidSuggestions) { + if (mHasUncommittedTypedChars) { final int length = mComposing.length(); if (length > 0) { mComposing.delete(length - 1, length); mWord.deleteLast(); ic.setComposingText(mComposing, 1); if (mComposing.length() == 0) { - mHasValidSuggestions = false; + mHasUncommittedTypedChars = false; + } + if (1 == length) { + // 1 == length means we are about to erase the last character of the word, + // so we can show bigrams. + mHandler.postUpdateBigramPredictions(); + } else { + // length > 1, so we still have letters to deduce a suggestion from. + mHandler.postUpdateSuggestions(); } - mHandler.postUpdateSuggestions(); } else { ic.deleteSurroundingText(1, 0); } @@ -1256,9 +1187,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void handleTab() { final int imeOptions = getCurrentInputEditorInfo().imeOptions; - final int navigationFlags = - EditorInfo.IME_FLAG_NAVIGATE_NEXT | EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS; - if ((imeOptions & navigationFlags) == 0) { + if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) + && !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) { sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); return; } @@ -1269,37 +1199,33 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // True if keyboard is in either chording shift or manual temporary upper case mode. final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase(); - if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0 + if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) && !isManualTemporaryUpperCase) { + EditorInfoCompatUtils.performEditorActionNext(ic); ic.performEditorAction(EditorInfo.IME_ACTION_NEXT); - } else if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0 + } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions) && isManualTemporaryUpperCase) { - ic.performEditorAction(EditorInfo.IME_ACTION_PREVIOUS); - } - } - - private void abortRecorrection(boolean force) { - if (force || TextEntryState.isRecorrecting()) { - TextEntryState.onAbortRecorrection(); - setCandidatesViewShown(isCandidateStripVisible()); - getCurrentInputConnection().finishComposingText(); - clearSuggestions(); + EditorInfoCompatUtils.performEditorActionPrevious(ic); } } private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) { - mVoiceConnector.handleCharacter(); + mVoiceProxy.handleCharacter(); + + if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceStripper(primaryCode)) { + removeTrailingSpace(); + } - if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) { - abortRecorrection(false); + if (mLastSelectionStart == mLastSelectionEnd) { + mRecorrection.abortRecorrection(false); } int code = primaryCode; if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) { - if (!mHasValidSuggestions) { - mHasValidSuggestions = true; + if (!mHasUncommittedTypedChars) { + mHasUncommittedTypedChars = true; mComposing.setLength(0); - saveWordInHistory(mBestWord); + mRecorrection.saveRecorrectionSuggestion(mWord, mBestWord); mWord.reset(); clearSuggestions(); } @@ -1323,7 +1249,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } } - if (mHasValidSuggestions) { + if (mHasUncommittedTypedChars) { if (mComposing.length() == 0 && switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked()) { mWord.setFirstCharCapitalized(true); @@ -1342,16 +1268,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else { sendKeyChar((char)code); } + if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceSwapper(primaryCode)) { + swapSwapperAndSpace(); + } else { + mJustAddedMagicSpace = false; + } + switcher.updateShiftState(); if (LatinIME.PERF_DEBUG) measureCps(); - TextEntryState.typedCharacter((char) code, isWordSeparator(code)); + TextEntryState.typedCharacter((char) code, mSettingsValues.isWordSeparator(code), x, y); } - private void handleSeparator(int primaryCode) { - mVoiceConnector.handleSeparator(); + private void handleSeparator(int primaryCode, int x, int y) { + mVoiceProxy.handleSeparator(); // Should dismiss the "Touch again to save" message when handling separator if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { + mHandler.cancelUpdateBigramPredictions(); mHandler.postUpdateSuggestions(); } @@ -1360,54 +1293,61 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final InputConnection ic = getCurrentInputConnection(); if (ic != null) { ic.beginBatchEdit(); - abortRecorrection(false); + mRecorrection.abortRecorrection(false); } - if (mHasValidSuggestions) { + if (mHasUncommittedTypedChars) { // In certain languages where single quote is a separator, it's better // not to auto correct, but accept the typed word. For instance, // in Italian dov' should not be expanded to dove' because the elision // requires the last vowel to be removed. - if (mAutoCorrectOn && primaryCode != '\'') { - pickedDefault = pickDefaultSuggestion(); - // Picked the suggestion by the space key. We consider this - // as "added an auto space". - if (primaryCode == Keyboard.CODE_SPACE) { - mJustAddedAutoSpace = true; - } + final boolean shouldAutoCorrect = + (mSettingsValues.mAutoCorrectEnabled || mSettingsValues.mQuickFixes) + && !mInputTypeNoAutoCorrect && mHasDictionary; + if (shouldAutoCorrect && primaryCode != Keyboard.CODE_SINGLE_QUOTE) { + pickedDefault = pickDefaultSuggestion(primaryCode); } else { commitTyped(ic); } } - if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) { - removeTrailingSpace(); - mJustAddedAutoSpace = false; - } - sendKeyChar((char)primaryCode); - // Handle the case of ". ." -> " .." with auto-space if necessary - // before changing the TextEntryState. - if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) { - reswapPeriodAndSpace(); + if (mJustAddedMagicSpace) { + if (mSettingsValues.isMagicSpaceSwapper(primaryCode)) { + sendKeyChar((char)primaryCode); + swapSwapperAndSpace(); + } else { + if (mSettingsValues.isMagicSpaceStripper(primaryCode)) removeTrailingSpace(); + sendKeyChar((char)primaryCode); + mJustAddedMagicSpace = false; + } + } else { + sendKeyChar((char)primaryCode); } - TextEntryState.typedCharacter((char) primaryCode, true); - if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) { - swapPunctuationAndSpace(); - } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { - doubleSpace(); + if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { + maybeDoubleSpace(); } + + TextEntryState.typedCharacter((char) primaryCode, true, x, y); + if (pickedDefault) { CharSequence typedWord = mWord.getTypedWord(); TextEntryState.backToAcceptedDefault(typedWord); if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) { - if (ic != null) { - CorrectionInfo correctionInfo = new CorrectionInfo( - mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); - ic.commitCorrection(correctionInfo); - } + InputConnectionCompatUtils.commitCorrection( + ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); if (mCandidateView != null) mCandidateView.onAutoCorrectionInverted(mBestWord); } + } + if (Keyboard.CODE_SPACE == primaryCode) { + if (!isCursorTouchingWord()) { + mHandler.cancelUpdateSuggestions(); + mHandler.cancelUpdateOldSuggestions(); + mHandler.postUpdateBigramPredictions(); + } + } else { + // Set punctuation right away. onUpdateSelection will fire but tests whether it is + // already displayed or not, so it's okay. setPunctuationSuggestions(); } mKeyboardSwitcher.updateShiftState(); @@ -1418,45 +1358,29 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void handleClose() { commitTyped(getCurrentInputConnection()); - mVoiceConnector.handleClose(); + mVoiceProxy.handleClose(); requestHideSelf(0); - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); + LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.closing(); } - private void saveWordInHistory(CharSequence result) { - if (mWord.size() <= 1) { - return; - } - // Skip if result is null. It happens in some edge case. - if (TextUtils.isEmpty(result)) { - return; - } - - // Make a copy of the CharSequence, since it is/could be a mutable CharSequence - final String resultCopy = result.toString(); - TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy, - new WordComposer(mWord)); - mWordHistory.add(entry); - } - - private boolean isSuggestionsRequested() { + public boolean isSuggestionsRequested() { return mIsSettingsSuggestionStripOn && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); } - private boolean isShowingPunctuationList() { - return mSuggestPuncList == mCandidateView.getSuggestions(); + public boolean isShowingPunctuationList() { + return mSettingsValues.mSuggestPuncList == mCandidateView.getSuggestions(); } - private boolean isShowingSuggestionsStrip() { + public boolean isShowingSuggestionsStrip() { return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE && mOrientation == Configuration.ORIENTATION_PORTRAIT); } - private boolean isCandidateStripVisible() { + public boolean isCandidateStripVisible() { if (mCandidateView == null) return false; if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting()) @@ -1472,7 +1396,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (DEBUG) { Log.d(TAG, "Switch to keyboard view."); } - View v = mKeyboardSwitcher.getInputView(); + View v = mKeyboardSwitcher.getKeyboardView(); if (v != null) { // Confirms that the keyboard view doesn't have parent view. ViewParent p = v.getParent(); @@ -1481,7 +1405,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } setInputView(v); } - setCandidatesViewShown(isCandidateStripVisible()); + setSuggestionStripShown(isCandidateStripVisible()); updateInputViewShown(); mHandler.postUpdateSuggestions(); } @@ -1491,9 +1415,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void setSuggestions(SuggestedWords words) { - if (mVoiceConnector.getAndResetIsShowingHint()) { - setCandidatesView(mCandidateViewContainer); - } +// if (mVoiceProxy.getAndResetIsShowingHint()) { +// setCandidatesView(mCandidateViewContainer); +// } if (mCandidateView != null) { mCandidateView.setSuggestions(words); @@ -1507,33 +1431,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void updateSuggestions() { // Check if we have a suggestion engine attached. if ((mSuggest == null || !isSuggestionsRequested()) - && !mVoiceConnector.isVoiceInputHighlighted()) { + && !mVoiceProxy.isVoiceInputHighlighted()) { return; } - if (!mHasValidSuggestions) { + if (!mHasUncommittedTypedChars) { setPunctuationSuggestions(); return; } showSuggestions(mWord); } - private SuggestedWords.Builder getTypedSuggestions(WordComposer word) { - return mSuggest.getSuggestedWordBuilder(mKeyboardSwitcher.getInputView(), word, null); - } - - private void showCorrections(WordAlternatives alternatives) { - SuggestedWords.Builder builder = alternatives.getAlternatives(); - builder.setTypedWordValid(false).setHasMinimalSuggestion(false); - showSuggestions(builder.build(), alternatives.getOriginalWord()); - } - private void showSuggestions(WordComposer word) { // TODO: May need a better way of retrieving previous word CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), - mWordSeparators); + mSettingsValues.mWordSeparators); SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( - mKeyboardSwitcher.getInputView(), word, prevWord); + mKeyboardSwitcher.getKeyboardView(), word, prevWord); boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection(); final CharSequence typedWord = word.getTypedWord(); @@ -1554,19 +1468,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // in most cases, suggestion count is 1 when typed word's length is 1, but we do always // need to clear the previous state when the user starts typing a word (i.e. typed word's // length == 1). - if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid - || mCandidateView.isShowingAddToDictionaryHint()) { - builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable); - } else { - final SuggestedWords previousSuggestions = mCandidateView.getSuggestions(); - if (previousSuggestions == mSuggestPuncList) - return; - builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); + if (typedWord != null) { + if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid + || mCandidateView.isShowingAddToDictionaryHint()) { + builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion( + correctionAvailable); + } else { + final SuggestedWords previousSuggestions = mCandidateView.getSuggestions(); + if (previousSuggestions == mSettingsValues.mSuggestPuncList) + return; + builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); + } } showSuggestions(builder.build(), typedWord); } - private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) { + public void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) { setSuggestions(suggestedWords); if (suggestedWords.size() > 0) { if (Utils.shouldBlockedBySafetyNetForAutoCorrection(suggestedWords, mSuggest)) { @@ -1579,30 +1496,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else { mBestWord = null; } - setCandidatesViewShown(isCandidateStripVisible()); + setSuggestionStripShown(isCandidateStripVisible()); } - private boolean pickDefaultSuggestion() { + private boolean pickDefaultSuggestion(int separatorCode) { // Complete any pending candidate query first if (mHandler.hasPendingUpdateSuggestions()) { mHandler.cancelUpdateSuggestions(); updateSuggestions(); } if (mBestWord != null && mBestWord.length() > 0) { - TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord); + TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord, separatorCode); mJustAccepted = true; pickSuggestion(mBestWord); // Add the word to the auto dictionary if it's not a known word addToAutoAndUserBigramDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); return true; - } return false; } public void pickSuggestionManually(int index, CharSequence suggestion) { SuggestedWords suggestions = mCandidateView.getSuggestions(); - mVoiceConnector.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators); + mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, + mSettingsValues.mWordSeparators); final boolean recorrecting = TextEntryState.isRecorrecting(); InputConnection ic = getCurrentInputConnection(); @@ -1627,21 +1544,36 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // If this is a punctuation, apply it through the normal key press - if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0)) - || isSuggestedPunctuation(suggestion.charAt(0)))) { + if (suggestion.length() == 1 && (mSettingsValues.isWordSeparator(suggestion.charAt(0)) + || mSettingsValues.isSuggestedPunctuation(suggestion.charAt(0)))) { // Word separators are suggested before the user inputs something. // So, LatinImeLogger logs "" as a user's input. LatinImeLogger.logOnManualSuggestion( "", suggestion.toString(), index, suggestions.mWords); + // Find out whether the previous character is a space. If it is, as a special case + // for punctuation entered through the suggestion strip, it should be considered + // a magic space even if it was a normal space. This is meant to help in case the user + // pressed space on purpose of displaying the suggestion strip punctuation. final char primaryCode = suggestion.charAt(0); + final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : ""; + final int toLeft = (ic == null || TextUtils.isEmpty(beforeText)) + ? 0 : beforeText.charAt(0); + final boolean oldMagicSpace = mJustAddedMagicSpace; + if (Keyboard.CODE_SPACE == toLeft) mJustAddedMagicSpace = true; onCodeInput(primaryCode, new int[] { primaryCode }, KeyboardActionListener.NOT_A_TOUCH_COORDINATE, KeyboardActionListener.NOT_A_TOUCH_COORDINATE); + mJustAddedMagicSpace = oldMagicSpace; if (ic != null) { ic.endBatchEdit(); } return; } + if (!mHasUncommittedTypedChars) { + // If we are not composing a word, then it was a suggestion inferred from + // context - no user input. We should reset the word composer. + mWord.reset(); + } mJustAccepted = true; pickSuggestion(suggestion); // Add the word to the auto dictionary if it's not a known word @@ -1654,9 +1586,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen index, suggestions.mWords); TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); // Follow it with a space - if (mAutoSpace && !recorrecting) { - sendSpace(); - mJustAddedAutoSpace = true; + if (mShouldInsertMagicSpace && !recorrecting) { + sendMagicSpace(); } // We should show the hint if the user pressed the first entry AND either: @@ -1678,9 +1609,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Fool the state watcher so that a subsequent backspace will not do a revert, unless // we just did a correction, in which case we need to stay in // TextEntryState.State.PICKED_SUGGESTION state. - TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true); - setPunctuationSuggestions(); - } else if (!showingAddToDictionaryHint) { + TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true, + WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); + } + if (!showingAddToDictionaryHint) { // If we're not showing the "Touch again to save", then show corrections again. // In case the cursor position doesn't change, make sure we show the suggestions again. clearSuggestions(); @@ -1706,98 +1638,41 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; InputConnection ic = getCurrentInputConnection(); if (ic != null) { - mVoiceConnector.rememberReplacedWord(suggestion, mWordSeparators); + mVoiceProxy.rememberReplacedWord(suggestion, mSettingsValues.mWordSeparators); ic.commitText(suggestion, 1); } - saveWordInHistory(suggestion); - mHasValidSuggestions = false; + mRecorrection.saveRecorrectionSuggestion(mWord, suggestion); + mHasUncommittedTypedChars = false; mCommittedLength = suggestion.length(); } - /** - * Tries to apply any typed alternatives for the word if we have any cached alternatives, - * otherwise tries to find new corrections and completions for the word. - * @param touching The word that the cursor is touching, with position information - * @return true if an alternative was found, false otherwise. - */ - private boolean applyTypedAlternatives(EditingUtils.SelectedWord touching) { - // If we didn't find a match, search for result in typed word history - WordComposer foundWord = null; - WordAlternatives alternatives = null; - // Search old suggestions to suggest re-corrected suggestions. - for (WordAlternatives entry : mWordHistory) { - if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) { - if (entry instanceof TypedWordAlternatives) { - foundWord = ((TypedWordAlternatives) entry).word; - } - alternatives = entry; - break; - } - } - // If we didn't find a match, at least suggest corrections as re-corrected suggestions. - if (foundWord == null - && (AutoCorrection.isValidWord( - mSuggest.getUnigramDictionaries(), touching.mWord, true))) { - foundWord = new WordComposer(); - for (int i = 0; i < touching.mWord.length(); i++) { - foundWord.add(touching.mWord.charAt(i), new int[] { - touching.mWord.charAt(i) - }, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); - } - foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0))); - } - // Found a match, show suggestions - if (foundWord != null || alternatives != null) { - if (alternatives == null) { - alternatives = new TypedWordAlternatives(touching.mWord, foundWord); - } - showCorrections(alternatives); - if (foundWord != null) { - mWord = new WordComposer(foundWord); - } else { - mWord.reset(); - } - return true; - } - return false; - } + private static final WordComposer sEmptyWordComposer = new WordComposer(); + private void updateBigramPredictions() { + if (mSuggest == null || !isSuggestionsRequested()) + return; - private void setOldSuggestions() { - mVoiceConnector.setShowingVoiceSuggestions(false); - if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) { + if (!mSettingsValues.mBigramPredictionEnabled) { + setPunctuationSuggestions(); return; } - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - if (!mHasValidSuggestions) { - // Extract the selected or touching text - EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic, - mLastSelectionStart, mLastSelectionEnd, mWordSeparators); - - if (touching != null && touching.mWord.length() > 1) { - ic.beginBatchEdit(); - if (!mVoiceConnector.applyVoiceAlternatives(touching) - && !applyTypedAlternatives(touching)) { - abortRecorrection(true); - } else { - TextEntryState.selectedForRecorrection(); - EditingUtils.underlineWord(ic, touching); - } + final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(), + mSettingsValues.mWordSeparators); + SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( + mKeyboardSwitcher.getKeyboardView(), sEmptyWordComposer, prevWord); - ic.endBatchEdit(); - } else { - abortRecorrection(true); - setPunctuationSuggestions(); // Show the punctuation suggestions list - } + if (builder.size() > 0) { + // Explicitly supply an empty typed word (the no-second-arg version of + // showSuggestions will retrieve the word near the cursor, we don't want that here) + showSuggestions(builder.build(), ""); } else { - abortRecorrection(true); + if (!isShowingPunctuationList()) setPunctuationSuggestions(); } } - private void setPunctuationSuggestions() { - setSuggestions(mSuggestPuncList); - setCandidatesViewShown(isCandidateStripVisible()); + public void setPunctuationSuggestions() { + setSuggestions(mSettingsValues.mSuggestPuncList); + setSuggestionStripShown(isCandidateStripVisible()); } private void addToAutoAndUserBigramDictionaries(CharSequence suggestion, int frequencyDelta) { @@ -1835,27 +1710,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } if (mUserBigramDictionary != null) { + // We don't want to register as bigrams words separated by a separator. + // For example "I will, and you too" : we don't want the pair ("will" "and") to be + // a bigram. CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), - mSentenceSeparators); + mSettingsValues.mWordSeparators); if (!TextUtils.isEmpty(prevWord)) { mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); } } } - private boolean isCursorTouchingWord() { + public boolean isCursorTouchingWord() { InputConnection ic = getCurrentInputConnection(); if (ic == null) return false; CharSequence toLeft = ic.getTextBeforeCursor(1, 0); CharSequence toRight = ic.getTextAfterCursor(1, 0); if (!TextUtils.isEmpty(toLeft) - && !isWordSeparator(toLeft.charAt(0)) - && !isSuggestedPunctuation(toLeft.charAt(0))) { + && !mSettingsValues.isWordSeparator(toLeft.charAt(0)) + && !mSettingsValues.isSuggestedPunctuation(toLeft.charAt(0))) { return true; } if (!TextUtils.isEmpty(toRight) - && !isWordSeparator(toRight.charAt(0)) - && !isSuggestedPunctuation(toRight.charAt(0))) { + && !mSettingsValues.isWordSeparator(toRight.charAt(0)) + && !mSettingsValues.isSuggestedPunctuation(toRight.charAt(0))) { return true; } return false; @@ -1868,53 +1746,49 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void revertLastWord(boolean deleteChar) { final int length = mComposing.length(); - if (!mHasValidSuggestions && length > 0) { + if (!mHasUncommittedTypedChars && length > 0) { final InputConnection ic = getCurrentInputConnection(); final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); if (deleteChar) ic.deleteSurroundingText(1, 0); int toDelete = mCommittedLength; final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); - if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) { + if (!TextUtils.isEmpty(toTheLeft) + && mSettingsValues.isWordSeparator(toTheLeft.charAt(0))) { toDelete--; } ic.deleteSurroundingText(toDelete, 0); // Re-insert punctuation only when the deleted character was word separator and the // composing text wasn't equal to the auto-corrected text. if (deleteChar - && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0)) + && !TextUtils.isEmpty(punctuation) + && mSettingsValues.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); + TextEntryState.typedCharacter(punctuation.charAt(0), true, + WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); // Clear composing text mComposing.setLength(0); } else { - mHasValidSuggestions = true; + mHasUncommittedTypedChars = true; ic.setComposingText(mComposing, 1); TextEntryState.backspace(); } + mHandler.cancelUpdateBigramPredictions(); mHandler.postUpdateSuggestions(); } else { sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); } } - protected String getWordSeparators() { - return mWordSeparators; - } - public boolean isWordSeparator(int code) { - String separators = getWordSeparators(); - return separators.contains(String.valueOf((char)code)); + return mSettingsValues.isWordSeparator(code); } - private boolean isSentenceSeparator(int code) { - return mSentenceSeparators.contains(String.valueOf((char)code)); - } - - private void sendSpace() { + private void sendMagicSpace() { sendKeyChar((char)Keyboard.CODE_SPACE); + mJustAddedMagicSpace = true; mKeyboardSwitcher.updateShiftState(); } @@ -1922,28 +1796,31 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return mWord.isFirstCharCapitalized(); } - // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID + // Notify that language or mode have been changed and toggleLanguage will update KeyboardID // according to new language or mode. public void onRefreshKeyboard() { - toggleLanguage(true, true); - } - - // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. - private void toggleLanguage(boolean reset, boolean next) { - if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { - mSubtypeSwitcher.toggleLanguage(reset, next); - } // Reload keyboard because the current language has been changed. mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), - mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceConnector.isVoiceButtonEnabled(), - mVoiceConnector.isVoiceButtonOnPrimary()); + mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(), + mVoiceProxy.isVoiceButtonOnPrimary()); initSuggest(); + loadSettings(); mKeyboardSwitcher.updateShiftState(); } + // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. + private void toggleLanguage(boolean next) { + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { + mSubtypeSwitcher.toggleLanguage(next); + } + // The following is necessary because on API levels < 10, we don't get notified when + // subtype changes. + onRefreshKeyboard(); + } + @Override public void onSwipeDown() { - if (mConfigSwipeDownDismissKeyboardEnabled) + if (mSettingsValues.mSwipeDownDismissKeyboardEnabled) handleClose(); } @@ -1962,21 +1839,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else { switcher.onOtherKeyPressed(); } - mAccessibilityUtils.onPress(primaryCode, switcher); } @Override public void onRelease(int primaryCode, boolean withSliding) { KeyboardSwitcher switcher = mKeyboardSwitcher; // Reset any drag flags in the keyboard - switcher.keyReleased(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { switcher.onReleaseShift(withSliding); } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { switcher.onReleaseSymbol(); } - mAccessibilityUtils.onRelease(primaryCode, switcher); } @@ -1999,7 +1873,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); } if (mAudioManager != null) { - mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); + mSilentModeOn = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); } } @@ -2007,11 +1881,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // if mAudioManager is null, we don't have the ringer state yet // mAudioManager will be set by updateRingerMode if (mAudioManager == null) { - if (mKeyboardSwitcher.getInputView() != null) { + if (mKeyboardSwitcher.getKeyboardView() != null) { updateRingerMode(); } } - if (mSoundOn && !mSilentMode) { + if (isSoundOn()) { // FIXME: Volume and enable should come from UI settings // FIXME: These should be triggered after auto-repeat logic int sound = AudioManager.FX_KEYPRESS_STANDARD; @@ -2031,10 +1905,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void vibrate() { - if (!mVibrateOn) { + if (!mSettingsValues.mVibrateOn) { return; } - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); + LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) { inputView.performHapticFeedback( HapticFeedbackConstants.KEYBOARD_TAP, @@ -2051,19 +1925,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return mWord; } - public boolean getPopupOn() { - return mPopupOn; + boolean isSoundOn() { + return mSettingsValues.mSoundOn && !mSilentModeOn; } private void updateCorrectionMode() { // TODO: cleanup messy flags mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false; - mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes) - && !mInputTypeNoAutoCorrect && mHasDictionary; - mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) + final boolean shouldAutoCorrect = (mSettingsValues.mAutoCorrectEnabled + || mSettingsValues.mQuickFixes) && !mInputTypeNoAutoCorrect && mHasDictionary; + mCorrectionMode = (shouldAutoCorrect && mSettingsValues.mAutoCorrectEnabled) ? Suggest.CORRECTION_FULL - : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); - mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) + : (shouldAutoCorrect ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); + mCorrectionMode = (mSettingsValues.mBigramSuggestionEnabled && shouldAutoCorrect + && mSettingsValues.mAutoCorrectEnabled) ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; if (mSuggest != null) { mSuggest.setCorrectionMode(mCorrectionMode); @@ -2072,12 +1947,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void updateAutoTextEnabled() { if (mSuggest == null) return; - mSuggest.setQuickFixesEnabled(mQuickFixes + mSuggest.setQuickFixesEnabled(mSettingsValues.mQuickFixes && SubtypeSwitcher.getInstance().isSystemLanguageSameAsInputLanguage()); } - private void updateSuggestionVisibility(SharedPreferences prefs) { - final Resources res = mResources; + private void updateSuggestionVisibility(final SharedPreferences prefs, final Resources res) { final String suggestionVisiblityStr = prefs.getString( Settings.PREF_SHOW_SUGGESTIONS_SETTING, res.getString(R.string.prefs_suggestion_visibility_default_value)); @@ -2105,121 +1979,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen startActivity(intent); } - private void loadSettings(EditorInfo attribute) { - // Get the settings preferences - final SharedPreferences prefs = mPrefs; - Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - mVibrateOn = vibrator != null && vibrator.hasVibrator() - && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false); - mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, - mResources.getBoolean(R.bool.config_default_sound_enabled)); - - mPopupOn = isPopupEnabled(prefs); - mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); - mQuickFixes = isQuickFixesEnabled(prefs); - - mAutoCorrectEnabled = isAutoCorrectEnabled(prefs); - mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs); - loadAndSetAutoCorrectionThreshold(prefs); - - mVoiceConnector.loadSettings(attribute, prefs); - - updateCorrectionMode(); - updateAutoTextEnabled(); - updateSuggestionVisibility(prefs); - SubtypeSwitcher.getInstance().loadSettings(); - } - - /** - * Load Auto correction threshold from SharedPreferences, and modify mSuggest's threshold. - */ - private void loadAndSetAutoCorrectionThreshold(SharedPreferences sp) { - // When mSuggest is not initialized, cannnot modify mSuggest's threshold. - if (mSuggest == null) return; - // When auto correction setting is turned off, the threshold is ignored. - if (!isAutoCorrectEnabled(sp)) return; - - final String currentAutoCorrectionSetting = sp.getString( - Settings.PREF_AUTO_CORRECTION_THRESHOLD, - mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); - final String[] autoCorrectionThresholdValues = mResources.getStringArray( - R.array.auto_correction_threshold_values); - // When autoCrrectionThreshold is greater than 1.0, auto correction is virtually turned off. - double autoCorrectionThreshold = Double.MAX_VALUE; - try { - final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); - if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { - autoCorrectionThreshold = Double.parseDouble( - autoCorrectionThresholdValues[arrayIndex]); - } - } catch (NumberFormatException e) { - // Whenever the threshold settings are correct, never come here. - autoCorrectionThreshold = Double.MAX_VALUE; - Log.w(TAG, "Cannot load auto correction threshold setting." - + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting - + ", autoCorrectionThresholdValues: " - + Arrays.toString(autoCorrectionThresholdValues)); - } - // TODO: This should be refactored : - // setAutoCorrectionThreshold should be called outside of this method. - mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold); - } - - private boolean isPopupEnabled(SharedPreferences sp) { - final boolean showPopupOption = getResources().getBoolean( - R.bool.config_enable_show_popup_on_keypress_option); - if (!showPopupOption) return mResources.getBoolean(R.bool.config_default_popup_preview); - return sp.getBoolean(Settings.PREF_POPUP_ON, - mResources.getBoolean(R.bool.config_default_popup_preview)); - } - - 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) { - final String currentAutoCorrectionSetting = sp.getString( - Settings.PREF_AUTO_CORRECTION_THRESHOLD, - mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); - final String autoCorrectionOff = mResources.getString( - R.string.auto_correction_threshold_mode_index_off); - return !currentAutoCorrectionSetting.equals(autoCorrectionOff); - } - - private boolean isBigramSuggestionEnabled(SharedPreferences sp) { - final boolean showBigramSuggestionsOption = mResources.getBoolean( - 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() { - if (mSuggestPuncs != null || mSuggestPuncList != null) - return; - SuggestedWords.Builder builder = new SuggestedWords.Builder(); - String puncs = mResources.getString(R.string.suggested_punctuations); - if (puncs != null) { - for (int i = 0; i < puncs.length(); i++) { - builder.addWord(puncs.subSequence(i, i + 1)); - } - } - mSuggestPuncList = builder.build(); - mSuggestPuncs = puncs; - } - - private boolean isSuggestedPunctuation(int code) { - return mSuggestPuncs.contains(String.valueOf((char)code)); - } - private void showSubtypeSelectorAndSettings() { final CharSequence title = getString(R.string.english_ime_input_options); final CharSequence[] items = new CharSequence[] { @@ -2233,13 +1992,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen di.dismiss(); switch (position) { case 0: - Intent intent = new Intent( - android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + Intent intent = CompatUtils.getInputLanguageSelectionIntent( + mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.putExtra(android.provider.Settings.EXTRA_INPUT_METHOD_ID, - mInputMethodId); startActivity(intent); break; case 1: @@ -2276,7 +2032,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void showOptionsMenuInternal(CharSequence title, CharSequence[] items, DialogInterface.OnClickListener listener) { - final IBinder windowToken = mKeyboardSwitcher.getInputView().getWindowToken(); + final IBinder windowToken = mKeyboardSwitcher.getKeyboardView().getWindowToken(); if (windowToken == null) return; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setCancelable(true); @@ -2305,14 +2061,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen p.println(" mComposing=" + mComposing.toString()); p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn); p.println(" mCorrectionMode=" + mCorrectionMode); - p.println(" mHasValidSuggestions=" + mHasValidSuggestions); - p.println(" mAutoCorrectOn=" + mAutoCorrectOn); - p.println(" mAutoSpace=" + mAutoSpace); + p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars); + p.println(" mAutoCorrectEnabled=" + mSettingsValues.mAutoCorrectEnabled); + p.println(" mShouldInsertMagicSpace=" + mShouldInsertMagicSpace); p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn); p.println(" TextEntryState.state=" + TextEntryState.getState()); - p.println(" mSoundOn=" + mSoundOn); - p.println(" mVibrateOn=" + mVibrateOn); - p.println(" mPopupOn=" + mPopupOn); + p.println(" mSoundOn=" + mSettingsValues.mSoundOn); + p.println(" mVibrateOn=" + mSettingsValues.mVibrateOn); + p.println(" mKeyPreviewPopupOn=" + mSettingsValues.mKeyPreviewPopupOn); } // Characters per second measurement @@ -2332,9 +2088,4 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); } - - @Override - public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { - SubtypeSwitcher.getInstance().updateSubtype(subtype); - } } diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java index aaecfffdd..e460471a5 100644 --- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java +++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java @@ -45,10 +45,10 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang String before, String after, int position, List<CharSequence> suggestions) { } - public static void logOnAutoSuggestion(String before, String after) { + public static void logOnAutoCorrection(String before, String after, int separatorCode) { } - public static void logOnAutoSuggestionCanceled() { + public static void logOnAutoCorrectionCancelled() { } public static void logOnDelete() { @@ -57,6 +57,9 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang public static void logOnInputChar() { } + public static void logOnInputSeparator() { + } + public static void logOnException(String metaData, Throwable e) { } diff --git a/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java new file mode 100644 index 000000000..eb740e111 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java @@ -0,0 +1,29 @@ +/* + * 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 java.util.List; +import java.util.Locale; + +class PrivateBinaryDictionaryGetter { + private PrivateBinaryDictionaryGetter() {} + public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context) { + return null; + } +} diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 341d5add0..956c51e06 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -16,17 +16,21 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.voice.VoiceIMEConnector; -import com.android.inputmethod.voice.VoiceInputLogger; +import com.android.inputmethod.compat.CompatUtils; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; +import com.android.inputmethod.deprecated.VoiceProxy; +import com.android.inputmethod.compat.VibratorCompatWrapper; import android.app.AlertDialog; import android.app.Dialog; import android.app.backup.BackupManager; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.Resources; import android.os.Bundle; -import android.os.Vibrator; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; @@ -41,6 +45,7 @@ import android.text.method.LinkMovementMethod; import android.util.Log; import android.widget.TextView; +import java.util.Arrays; import java.util.Locale; public class Settings extends PreferenceActivity @@ -51,7 +56,7 @@ public class Settings extends PreferenceActivity public static final String PREF_GENERAL_SETTINGS_KEY = "general_settings"; public static final String PREF_VIBRATE_ON = "vibrate_on"; public static final String PREF_SOUND_ON = "sound_on"; - public static final String PREF_POPUP_ON = "popup_on"; + public static final String PREF_KEY_PREVIEW_POPUP_ON = "popup_on"; public static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled"; public static final String PREF_AUTO_CAP = "auto_cap"; public static final String PREF_SETTINGS_KEY = "settings_key"; @@ -60,29 +65,243 @@ public class Settings extends PreferenceActivity public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; public static final String PREF_SUBTYPES = "subtype_settings"; - public static final String PREF_PREDICTION_SETTINGS_KEY = "prediction_settings"; + public static final String PREF_CORRECTION_SETTINGS_KEY = "correction_settings"; public static final String PREF_QUICK_FIXES = "quick_fixes"; public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting"; public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold"; + public static final String PREF_DEBUG_SETTINGS = "debug_settings"; + + public static final String PREF_NGRAM_SETTINGS_KEY = "ngram_settings"; public static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion"; + public static final String PREF_BIGRAM_PREDICTIONS = "bigram_prediction"; + + public static final String PREF_MISC_SETTINGS_KEY = "misc_settings"; + + public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY = + "pref_key_preview_popup_dismiss_delay"; public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; // Dialog ids private static final int VOICE_INPUT_CONFIRM_DIALOG = 0; + public static class Values { + // From resources: + public final boolean mSwipeDownDismissKeyboardEnabled; + public final int mDelayBeforeFadeoutLanguageOnSpacebar; + public final int mDelayUpdateSuggestions; + public final int mDelayUpdateOldSuggestions; + public final int mDelayUpdateShiftState; + public final int mDurationOfFadeoutLanguageOnSpacebar; + public final float mFinalFadeoutFactorOfLanguageOnSpacebar; + public final long mDoubleSpacesTurnIntoPeriodTimeout; + public final String mWordSeparators; + public final String mMagicSpaceStrippers; + public final String mMagicSpaceSwappers; + public final String mSuggestPuncs; + public final SuggestedWords mSuggestPuncList; + + // From preferences: + public final boolean mSoundOn; // Sound setting private to Latin IME (see mSilentModeOn) + public final boolean mVibrateOn; + public final boolean mKeyPreviewPopupOn; + public final int mKeyPreviewPopupDismissDelay; + public final boolean mAutoCap; + public final boolean mQuickFixes; + public final boolean mAutoCorrectEnabled; + public final double mAutoCorrectionThreshold; + // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary + public final boolean mBigramSuggestionEnabled; + // Prediction: use bigrams to predict the next word when there is no input for it yet + public final boolean mBigramPredictionEnabled; + + public Values(final SharedPreferences prefs, final Context context, + final String localeStr) { + final Resources res = context.getResources(); + final Locale savedLocale; + if (null != localeStr) { + final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr); + savedLocale = Utils.setSystemLocale(res, keyboardLocale); + } else { + savedLocale = null; + } + + // Get the resources + mSwipeDownDismissKeyboardEnabled = res.getBoolean( + R.bool.config_swipe_down_dismiss_keyboard_enabled); + mDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger( + R.integer.config_delay_before_fadeout_language_on_spacebar); + mDelayUpdateSuggestions = + res.getInteger(R.integer.config_delay_update_suggestions); + mDelayUpdateOldSuggestions = res.getInteger( + R.integer.config_delay_update_old_suggestions); + mDelayUpdateShiftState = + res.getInteger(R.integer.config_delay_update_shift_state); + mDurationOfFadeoutLanguageOnSpacebar = res.getInteger( + R.integer.config_duration_of_fadeout_language_on_spacebar); + mFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger( + R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; + mDoubleSpacesTurnIntoPeriodTimeout = res.getInteger( + R.integer.config_double_spaces_turn_into_period_timeout); + mMagicSpaceStrippers = res.getString(R.string.magic_space_stripping_symbols); + mMagicSpaceSwappers = res.getString(R.string.magic_space_swapping_symbols); + String wordSeparators = mMagicSpaceStrippers + mMagicSpaceSwappers + + res.getString(R.string.magic_space_promoting_symbols); + final String notWordSeparators = res.getString(R.string.non_word_separator_symbols); + for (int i = notWordSeparators.length() - 1; i >= 0; --i) { + wordSeparators = wordSeparators.replace(notWordSeparators.substring(i, i + 1), ""); + } + mWordSeparators = wordSeparators; + mSuggestPuncs = res.getString(R.string.suggested_punctuations); + // TODO: it would be nice not to recreate this each time we change the configuration + mSuggestPuncList = createSuggestPuncList(mSuggestPuncs); + + // Get the settings preferences + final boolean hasVibrator = VibratorCompatWrapper.getInstance(context).hasVibrator(); + mVibrateOn = hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false); + mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, + res.getBoolean(R.bool.config_default_sound_enabled)); + + mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res); + mKeyPreviewPopupDismissDelay = getKeyPreviewPopupDismissDelay(prefs, res); + mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); + mQuickFixes = isQuickFixesEnabled(prefs, res); + + mAutoCorrectEnabled = isAutoCorrectEnabled(prefs, res); + mBigramSuggestionEnabled = mAutoCorrectEnabled + && isBigramSuggestionEnabled(prefs, res, mAutoCorrectEnabled); + mBigramPredictionEnabled = mBigramSuggestionEnabled + && isBigramPredictionEnabled(prefs, res); + + mAutoCorrectionThreshold = getAutoCorrectionThreshold(prefs, res); + + Utils.setSystemLocale(res, savedLocale); + } + + public boolean isSuggestedPunctuation(int code) { + return mSuggestPuncs.contains(String.valueOf((char)code)); + } + + public boolean isWordSeparator(int code) { + return mWordSeparators.contains(String.valueOf((char)code)); + } + + public boolean isMagicSpaceStripper(int code) { + return mMagicSpaceStrippers.contains(String.valueOf((char)code)); + } + + public boolean isMagicSpaceSwapper(int code) { + return mMagicSpaceSwappers.contains(String.valueOf((char)code)); + } + + // Helper methods + private static boolean isQuickFixesEnabled(SharedPreferences sp, Resources resources) { + final boolean showQuickFixesOption = resources.getBoolean( + R.bool.config_enable_quick_fixes_option); + if (!showQuickFixesOption) { + return isAutoCorrectEnabled(sp, resources); + } + return sp.getBoolean(Settings.PREF_QUICK_FIXES, resources.getBoolean( + R.bool.config_default_quick_fixes)); + } + + private static boolean isAutoCorrectEnabled(SharedPreferences sp, Resources resources) { + final String currentAutoCorrectionSetting = sp.getString( + Settings.PREF_AUTO_CORRECTION_THRESHOLD, + resources.getString(R.string.auto_correction_threshold_mode_index_modest)); + final String autoCorrectionOff = resources.getString( + R.string.auto_correction_threshold_mode_index_off); + return !currentAutoCorrectionSetting.equals(autoCorrectionOff); + } + + // Public to access from KeyboardSwitcher. Should it have access to some + // process-global instance instead? + public static boolean isKeyPreviewPopupEnabled(SharedPreferences sp, Resources resources) { + final boolean showPopupOption = resources.getBoolean( + R.bool.config_enable_show_popup_on_keypress_option); + if (!showPopupOption) return resources.getBoolean(R.bool.config_default_popup_preview); + return sp.getBoolean(Settings.PREF_KEY_PREVIEW_POPUP_ON, + resources.getBoolean(R.bool.config_default_popup_preview)); + } + + // Likewise + public static int getKeyPreviewPopupDismissDelay(SharedPreferences sp, + Resources resources) { + return Integer.parseInt(sp.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, + Integer.toString(resources.getInteger(R.integer.config_delay_after_preview)))); + } + + private static boolean isBigramSuggestionEnabled(SharedPreferences sp, Resources resources, + boolean autoCorrectEnabled) { + final boolean showBigramSuggestionsOption = resources.getBoolean( + R.bool.config_enable_bigram_suggestions_option); + if (!showBigramSuggestionsOption) { + return autoCorrectEnabled; + } + return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, resources.getBoolean( + R.bool.config_default_bigram_suggestions)); + } + + private static boolean isBigramPredictionEnabled(SharedPreferences sp, + Resources resources) { + return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, resources.getBoolean( + R.bool.config_default_bigram_prediction)); + } + + private static double getAutoCorrectionThreshold(SharedPreferences sp, + Resources resources) { + final String currentAutoCorrectionSetting = sp.getString( + Settings.PREF_AUTO_CORRECTION_THRESHOLD, + resources.getString(R.string.auto_correction_threshold_mode_index_modest)); + final String[] autoCorrectionThresholdValues = resources.getStringArray( + R.array.auto_correction_threshold_values); + // When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off. + double autoCorrectionThreshold = Double.MAX_VALUE; + try { + final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); + if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { + autoCorrectionThreshold = Double.parseDouble( + autoCorrectionThresholdValues[arrayIndex]); + } + } catch (NumberFormatException e) { + // Whenever the threshold settings are correct, never come here. + autoCorrectionThreshold = Double.MAX_VALUE; + Log.w(TAG, "Cannot load auto correction threshold setting." + + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting + + ", autoCorrectionThresholdValues: " + + Arrays.toString(autoCorrectionThresholdValues)); + } + return autoCorrectionThreshold; + } + + private static SuggestedWords createSuggestPuncList(final String puncs) { + SuggestedWords.Builder builder = new SuggestedWords.Builder(); + if (puncs != null) { + for (int i = 0; i < puncs.length(); i++) { + builder.addWord(puncs.subSequence(i, i + 1)); + } + } + return builder.build(); + } + } + private PreferenceScreen mInputLanguageSelection; private CheckBoxPreference mQuickFixes; private ListPreference mVoicePreference; private ListPreference mSettingsKeyPreference; private ListPreference mShowCorrectionSuggestionsPreference; private ListPreference mAutoCorrectionThreshold; + private ListPreference mKeyPreviewPopupDismissDelay; + // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary private CheckBoxPreference mBigramSuggestion; + // Prediction: use bigrams to predict the next word when there is no input for it yet + private CheckBoxPreference mBigramPrediction; + private Preference mDebugSettingsPreference; private boolean mVoiceOn; private AlertDialog mDialog; - private VoiceInputLogger mLogger; + private VoiceProxy.VoiceLoggerWrapper mVoiceLogger; private boolean mOkClicked = false; private String mVoiceModeOff; @@ -92,11 +311,14 @@ public class Settings extends PreferenceActivity R.string.auto_correction_threshold_mode_index_off); final String currentSetting = mAutoCorrectionThreshold.getValue(); mBigramSuggestion.setEnabled(!currentSetting.equals(autoCorrectionOff)); + mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff)); } @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); + final Resources res = getResources(); + addPreferencesFromResource(R.xml.prefs); mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES); mInputLanguageSelection.setOnPreferenceClickListener(this); @@ -111,69 +333,92 @@ public class Settings extends PreferenceActivity mVoiceModeOff = getString(R.string.voice_mode_off); mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff) .equals(mVoiceModeOff)); - mLogger = VoiceInputLogger.getLogger(this); + mVoiceLogger = VoiceProxy.VoiceLoggerWrapper.getInstance(this); mAutoCorrectionThreshold = (ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD); mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTIONS); + mBigramPrediction = (CheckBoxPreference) findPreference(PREF_BIGRAM_PREDICTIONS); + mDebugSettingsPreference = findPreference(PREF_DEBUG_SETTINGS); + if (mDebugSettingsPreference != null) { + final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN); + debugSettingsIntent.setClassName(getPackageName(), DebugSettings.class.getName()); + mDebugSettingsPreference.setIntent(debugSettingsIntent); + } + ensureConsistencyOfAutoCorrectionSettings(); final PreferenceGroup generalSettings = (PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS_KEY); final PreferenceGroup textCorrectionGroup = - (PreferenceGroup) findPreference(PREF_PREDICTION_SETTINGS_KEY); + (PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY); - final boolean showSettingsKeyOption = getResources().getBoolean( + final boolean showSettingsKeyOption = res.getBoolean( R.bool.config_enable_show_settings_key_option); if (!showSettingsKeyOption) { generalSettings.removePreference(mSettingsKeyPreference); } - final boolean showVoiceKeyOption = getResources().getBoolean( + final boolean showVoiceKeyOption = res.getBoolean( R.bool.config_enable_show_voice_key_option); if (!showVoiceKeyOption) { generalSettings.removePreference(mVoicePreference); } - Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); - if (vibrator == null || !vibrator.hasVibrator()) { + if (!VibratorCompatWrapper.getInstance(this).hasVibrator()) { generalSettings.removePreference(findPreference(PREF_VIBRATE_ON)); } - final boolean showSubtypeSettings = getResources().getBoolean( - R.bool.config_enable_show_subtype_settings); - if (!showSubtypeSettings) { + if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) { generalSettings.removePreference(findPreference(PREF_SUBTYPES)); } - final boolean showPopupOption = getResources().getBoolean( + final boolean showPopupOption = res.getBoolean( R.bool.config_enable_show_popup_on_keypress_option); if (!showPopupOption) { - generalSettings.removePreference(findPreference(PREF_POPUP_ON)); + generalSettings.removePreference(findPreference(PREF_KEY_PREVIEW_POPUP_ON)); } - final boolean showRecorrectionOption = getResources().getBoolean( + final boolean showRecorrectionOption = res.getBoolean( R.bool.config_enable_show_recorrection_option); if (!showRecorrectionOption) { generalSettings.removePreference(findPreference(PREF_RECORRECTION_ENABLED)); } - final boolean showQuickFixesOption = getResources().getBoolean( + final boolean showQuickFixesOption = res.getBoolean( R.bool.config_enable_quick_fixes_option); if (!showQuickFixesOption) { textCorrectionGroup.removePreference(findPreference(PREF_QUICK_FIXES)); } - final boolean showBigramSuggestionsOption = getResources().getBoolean( + final boolean showBigramSuggestionsOption = res.getBoolean( R.bool.config_enable_bigram_suggestions_option); if (!showBigramSuggestionsOption) { textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_SUGGESTIONS)); + textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_PREDICTIONS)); } - final boolean showUsabilityModeStudyOption = getResources().getBoolean( + final boolean showUsabilityModeStudyOption = res.getBoolean( R.bool.config_enable_usability_study_mode_option); if (!showUsabilityModeStudyOption) { getPreferenceScreen().removePreference(findPreference(PREF_USABILITY_STUDY_MODE)); } + + mKeyPreviewPopupDismissDelay = + (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); + final String[] entries = new String[] { + res.getString(R.string.key_preview_popup_dismiss_no_delay), + res.getString(R.string.key_preview_popup_dismiss_default_delay), + }; + final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger( + R.integer.config_delay_after_preview)); + mKeyPreviewPopupDismissDelay.setEntries(entries); + mKeyPreviewPopupDismissDelay.setEntryValues( + new String[] { "0", popupDismissDelayDefaultValue }); + if (null == mKeyPreviewPopupDismissDelay.getValue()) { + mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue); + } + mKeyPreviewPopupDismissDelay.setEnabled( + Settings.Values.isKeyPreviewPopupEnabled(prefs, res)); } @Override @@ -181,10 +426,10 @@ public class Settings extends PreferenceActivity super.onResume(); int autoTextSize = AutoText.getSize(getListView()); if (autoTextSize < 1) { - ((PreferenceGroup) findPreference(PREF_PREDICTION_SETTINGS_KEY)) + ((PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY)) .removePreference(mQuickFixes); } - if (!VoiceIMEConnector.VOICE_INSTALLED + if (!VoiceProxy.VOICE_INSTALLED || !SpeechRecognizer.isRecognitionAvailable(this)) { getPreferenceScreen().removePreference(mVoicePreference); } else { @@ -192,6 +437,7 @@ public class Settings extends PreferenceActivity } updateSettingsKeySummary(); updateShowCorrectionSuggestionsSummary(); + updateKeyPreviewPopupDelaySummary(); } @Override @@ -210,6 +456,12 @@ public class Settings extends PreferenceActivity .equals(mVoiceModeOff)) { showVoiceConfirmation(); } + } else if (key.equals(PREF_KEY_PREVIEW_POPUP_ON)) { + final ListPreference popupDismissDelay = + (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); + if (null != popupDismissDelay) { + popupDismissDelay.setEnabled(prefs.getBoolean(PREF_KEY_PREVIEW_POPUP_ON, true)); + } } ensureConsistencyOfAutoCorrectionSettings(); mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff) @@ -217,21 +469,15 @@ public class Settings extends PreferenceActivity updateVoiceModeSummary(); updateSettingsKeySummary(); updateShowCorrectionSuggestionsSummary(); + updateKeyPreviewPopupDelaySummary(); } @Override public boolean onPreferenceClick(Preference pref) { if (pref == mInputLanguageSelection) { - final String action; - if (android.os.Build.VERSION.SDK_INT - >= /* android.os.Build.VERSION_CODES.HONEYCOMB */ 11) { - // Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS - // TODO: Can this be a constant instead of literal String constant? - action = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; - } else { - action = "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION"; - } - startActivity(new Intent(action)); + startActivity(CompatUtils.getInputLanguageSelectionIntent( + Utils.getInputMethodId(InputMethodManagerCompatWrapper.getInstance(this), + getApplicationInfo().packageName), 0)); return true; } return false; @@ -250,6 +496,11 @@ public class Settings extends PreferenceActivity [mSettingsKeyPreference.findIndexOfValue(mSettingsKeyPreference.getValue())]); } + private void updateKeyPreviewPopupDelaySummary() { + final ListPreference lp = mKeyPreviewPopupDismissDelay; + lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]); + } + private void showVoiceConfirmation() { mOkClicked = false; showDialog(VOICE_INPUT_CONFIRM_DIALOG); @@ -277,10 +528,10 @@ public class Settings extends PreferenceActivity public void onClick(DialogInterface dialog, int whichButton) { if (whichButton == DialogInterface.BUTTON_NEGATIVE) { mVoicePreference.setValue(mVoiceModeOff); - mLogger.settingsWarningDialogCancel(); + mVoiceLogger.settingsWarningDialogCancel(); } else if (whichButton == DialogInterface.BUTTON_POSITIVE) { mOkClicked = true; - mLogger.settingsWarningDialogOk(); + mVoiceLogger.settingsWarningDialogOk(); } updateVoicePreference(); } @@ -311,7 +562,7 @@ public class Settings extends PreferenceActivity AlertDialog dialog = builder.create(); mDialog = dialog; dialog.setOnDismissListener(this); - mLogger.settingsWarningDialogShown(); + mVoiceLogger.settingsWarningDialogShown(); return dialog; default: Log.e(TAG, "unknown dialog " + id); @@ -321,7 +572,7 @@ public class Settings extends PreferenceActivity @Override public void onDismiss(DialogInterface dialog) { - mLogger.settingsWarningDialogDismissed(); + mVoiceLogger.settingsWarningDialogDismissed(); if (!mOkClicked) { // This assumes that onPreferenceClick gets called first, and this if the user // agreed after the warning, we set the mOkClicked value to true. @@ -331,10 +582,6 @@ public class Settings extends PreferenceActivity private void updateVoicePreference() { boolean isChecked = !mVoicePreference.getValue().equals(mVoiceModeOff); - if (isChecked) { - mLogger.voiceInputSettingEnabled(); - } else { - mLogger.voiceInputSettingDisabled(); - } + mVoiceLogger.voiceInputSettingEnabled(isChecked); } } diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index dc14d770a..8b51af880 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -16,11 +16,12 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; +import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.LatinKeyboard; -import com.android.inputmethod.voice.SettingsUtil; -import com.android.inputmethod.voice.VoiceIMEConnector; -import com.android.inputmethod.voice.VoiceInput; import android.content.Context; import android.content.Intent; @@ -31,12 +32,10 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.AsyncTask; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.InputMethodSubtype; import java.util.ArrayList; import java.util.Arrays; @@ -53,32 +52,37 @@ public class SubtypeSwitcher { private static final String VOICE_MODE = "voice"; private static final String SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY = "requireNetworkConnectivity"; + public static final String USE_SPACEBAR_LANGUAGE_SWITCH_KEY = "use_spacebar_language_switch"; + private final TextUtils.SimpleStringSplitter mLocaleSplitter = new TextUtils.SimpleStringSplitter(LOCALE_SEPARATER); private static final SubtypeSwitcher sInstance = new SubtypeSwitcher(); private /* final */ LatinIME mService; - private /* final */ SharedPreferences mPrefs; - private /* final */ InputMethodManager mImm; + private /* final */ InputMethodManagerCompatWrapper mImm; private /* final */ Resources mResources; private /* final */ ConnectivityManager mConnectivityManager; private /* final */ boolean mConfigUseSpacebarLanguageSwitcher; - private final ArrayList<InputMethodSubtype> mEnabledKeyboardSubtypesOfCurrentInputMethod = - new ArrayList<InputMethodSubtype>(); + private /* final */ SharedPreferences mPrefs; + private final ArrayList<InputMethodSubtypeCompatWrapper> + mEnabledKeyboardSubtypesOfCurrentInputMethod = + new ArrayList<InputMethodSubtypeCompatWrapper>(); private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>(); + private final LanguageBarInfo mLanguageBarInfo = new LanguageBarInfo(); /*-----------------------------------------------------------*/ // Variants which should be changed only by reload functions. private boolean mNeedsToDisplayLanguage; private boolean mIsSystemLanguageSameAsInputLanguage; - private InputMethodInfo mShortcutInputMethodInfo; - private InputMethodSubtype mShortcutSubtype; - private List<InputMethodSubtype> mAllEnabledSubtypesOfCurrentInputMethod; - private InputMethodSubtype mCurrentSubtype; + private InputMethodInfoCompatWrapper mShortcutInputMethodInfo; + private InputMethodSubtypeCompatWrapper mShortcutSubtype; + private List<InputMethodSubtypeCompatWrapper> mAllEnabledSubtypesOfCurrentInputMethod; + private InputMethodSubtypeCompatWrapper mCurrentSubtype; private Locale mSystemLocale; private Locale mInputLocale; private String mInputLocaleStr; - private VoiceInput mVoiceInput; + private String mInputMethodId; + private VoiceProxy.VoiceInputWrapper mVoiceInputWrapper; /*-----------------------------------------------------------*/ private boolean mIsNetworkConnected; @@ -88,10 +92,9 @@ public class SubtypeSwitcher { } public static void init(LatinIME service, SharedPreferences prefs) { + SubtypeLocale.init(service); sInstance.initialize(service, prefs); sInstance.updateAllParameters(); - - SubtypeLocale.init(service); } private SubtypeSwitcher() { @@ -100,9 +103,8 @@ public class SubtypeSwitcher { private void initialize(LatinIME service, SharedPreferences prefs) { mService = service; - mPrefs = prefs; mResources = service.getResources(); - mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE); + mImm = InputMethodManagerCompatWrapper.getInstance(service); mConnectivityManager = (ConnectivityManager) service.getSystemService( Context.CONNECTIVITY_SERVICE); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); @@ -112,15 +114,12 @@ public class SubtypeSwitcher { mInputLocaleStr = null; mCurrentSubtype = null; mAllEnabledSubtypesOfCurrentInputMethod = null; - // TODO: Voice input should be created here - mVoiceInput = null; - mConfigUseSpacebarLanguageSwitcher = mResources.getBoolean( - R.bool.config_use_spacebar_language_switcher); - if (mConfigUseSpacebarLanguageSwitcher) - initLanguageSwitcher(service); + mVoiceInputWrapper = null; + mPrefs = prefs; final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); mIsNetworkConnected = (info != null && info.isConnected()); + mInputMethodId = Utils.getInputMethodId(mImm, service.getPackageName()); } // Update all parameters stored in SubtypeSwitcher. @@ -134,11 +133,10 @@ public class SubtypeSwitcher { // Update parameters which are changed outside LatinIME. This parameters affect UI so they // should be updated every time onStartInputview. public void updateParametersOnStartInputView() { - if (mConfigUseSpacebarLanguageSwitcher) { - updateForSpacebarLanguageSwitch(); - } else { - updateEnabledSubtypes(); - } + mConfigUseSpacebarLanguageSwitcher = mPrefs.getBoolean(USE_SPACEBAR_LANGUAGE_SWITCH_KEY, + mService.getResources().getBoolean( + R.bool.config_use_spacebar_language_switcher)); + updateEnabledSubtypes(); updateShortcutIME(); } @@ -150,7 +148,7 @@ public class SubtypeSwitcher { null, true); mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); - for (InputMethodSubtype ims: mAllEnabledSubtypesOfCurrentInputMethod) { + for (InputMethodSubtypeCompatWrapper ims : mAllEnabledSubtypesOfCurrentInputMethod) { final String locale = ims.getLocale(); final String mode = ims.getMode(); mLocaleSplitter.setString(locale); @@ -172,6 +170,10 @@ public class SubtypeSwitcher { Log.w(TAG, "Last subtype was disabled. Update to the current one."); } updateSubtype(mImm.getCurrentInputMethodSubtype()); + } else { + // mLanguageBarInfo.update() will be called in updateSubtype so there is no need + // to call this in the if-clause above. + mLanguageBarInfo.update(); } } @@ -184,10 +186,10 @@ public class SubtypeSwitcher { + ", " + mShortcutSubtype.getMode()))); } // TODO: Update an icon for shortcut IME - Map<InputMethodInfo, List<InputMethodSubtype>> shortcuts = + final Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcuts = mImm.getShortcutInputMethodsAndSubtypes(); - for (InputMethodInfo imi: shortcuts.keySet()) { - List<InputMethodSubtype> subtypes = shortcuts.get(imi); + for (InputMethodInfoCompatWrapper imi : shortcuts.keySet()) { + List<InputMethodSubtypeCompatWrapper> subtypes = shortcuts.get(imi); // TODO: Returns the first found IMI for now. Should handle all shortcuts as // appropriate. mShortcutInputMethodInfo = imi; @@ -206,7 +208,7 @@ public class SubtypeSwitcher { } // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function. - public void updateSubtype(InputMethodSubtype newSubtype) { + public void updateSubtype(InputMethodSubtypeCompatWrapper newSubtype) { final String newLocale; final String newMode; final String oldMode = getCurrentSubtypeMode(); @@ -243,32 +245,33 @@ public class SubtypeSwitcher { // We cancel its status when we change mode, while we reset otherwise. if (isKeyboardMode()) { if (modeChanged) { - if (VOICE_MODE.equals(oldMode) && mVoiceInput != null) { - mVoiceInput.cancel(); + if (VOICE_MODE.equals(oldMode) && mVoiceInputWrapper != null) { + mVoiceInputWrapper.cancel(); } } if (modeChanged || languageChanged) { updateShortcutIME(); mService.onRefreshKeyboard(); } - } else if (isVoiceMode() && mVoiceInput != null) { + } else if (isVoiceMode() && mVoiceInputWrapper != null) { if (VOICE_MODE.equals(oldMode)) { - mVoiceInput.reset(); + mVoiceInputWrapper.reset(); } // If needsToShowWarningDialog is true, voice input need to show warning before // show recognition view. if (languageChanged || modeChanged - || VoiceIMEConnector.getInstance().needsToShowWarningDialog()) { + || VoiceProxy.getInstance().needsToShowWarningDialog()) { triggerVoiceIME(); } } else { Log.w(TAG, "Unknown subtype mode: " + newMode); - if (VOICE_MODE.equals(oldMode) && mVoiceInput != null) { + if (VOICE_MODE.equals(oldMode) && mVoiceInputWrapper != null) { // We need to reset the voice input to release the resources and to reset its status // as it is not the current input mode. - mVoiceInput.reset(); + mVoiceInputWrapper.reset(); } } + mLanguageBarInfo.update(); } // Update the current input locale from Locale string. @@ -277,14 +280,8 @@ public class SubtypeSwitcher { // "en_US" --> language: en & country: US // "en" --> language: en // "" --> the system locale - mLocaleSplitter.setString(inputLocaleStr); - if (mLocaleSplitter.hasNext()) { - String language = mLocaleSplitter.next(); - if (mLocaleSplitter.hasNext()) { - mInputLocale = new Locale(language, mLocaleSplitter.next()); - } else { - mInputLocale = new Locale(language); - } + if (!TextUtils.isEmpty(inputLocaleStr)) { + mInputLocale = Utils.constructLocaleFromString(inputLocaleStr); mInputLocaleStr = inputLocaleStr; } else { mInputLocale = mSystemLocale; @@ -303,25 +300,47 @@ public class SubtypeSwitcher { //////////////////////////// public void switchToShortcutIME() { - final IBinder token = mService.getWindow().getWindow().getAttributes().token; - if (token == null || mShortcutInputMethodInfo == null) { + if (mShortcutInputMethodInfo == null) { return; } + final String imiId = mShortcutInputMethodInfo.getId(); - final InputMethodSubtype subtype = mShortcutSubtype; - new Thread("SwitchToShortcutIME") { + final InputMethodSubtypeCompatWrapper subtype = mShortcutSubtype; + switchToTargetIME(imiId, subtype); + } + + private void switchToTargetIME( + final String imiId, final InputMethodSubtypeCompatWrapper subtype) { + final IBinder token = mService.getWindow().getWindow().getAttributes().token; + if (token == null) { + return; + } + new AsyncTask<Void, Void, Void>() { @Override - public void run() { + protected Void doInBackground(Void... params) { mImm.setInputMethodAndSubtype(token, imiId, subtype); + return null; } - }.start(); + + @Override + protected void onPostExecute(Void result) { + // Calls in this method need to be done in the same thread as the thread which + // called switchToShortcutIME(). + + // Notify an event that the current subtype was changed. This event will be + // handled if "onCurrentInputMethodSubtypeChanged" can't be implemented + // when the API level is 10 or previous. + mService.notifyOnCurrentInputMethodSubtypeChanged(subtype); + } + }.execute(); } public Drawable getShortcutIcon() { return getSubtypeIcon(mShortcutInputMethodInfo, mShortcutSubtype); } - private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) { + private Drawable getSubtypeIcon( + InputMethodInfoCompatWrapper imi, InputMethodSubtypeCompatWrapper subtype) { final PackageManager pm = mService.getPackageManager(); if (imi != null) { final String imiPackageName = imi.getPackageName(); @@ -360,11 +379,16 @@ public class SubtypeSwitcher { return false; if (mShortcutSubtype == null) return true; + // For compatibility, if the shortcut subtype is dummy, we assume the shortcut IME + // (built-in voice dummy subtype) is available. + if (!mShortcutSubtype.hasOriginalObject()) return true; final boolean allowsImplicitlySelectedSubtypes = true; - for (final InputMethodSubtype enabledSubtype : mImm.getEnabledInputMethodSubtypeList( - mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) { - if (enabledSubtype.equals(mShortcutSubtype)) + for (final InputMethodSubtypeCompatWrapper enabledSubtype : + mImm.getEnabledInputMethodSubtypeList( + mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) { + if (enabledSubtype.equals(mShortcutSubtype)) { return true; + } } return false; } @@ -389,7 +413,7 @@ public class SubtypeSwitcher { final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance(); final LatinKeyboard keyboard = switcher.getLatinKeyboard(); if (keyboard != null) { - keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getInputView()); + keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getKeyboardView()); } } @@ -398,11 +422,7 @@ public class SubtypeSwitcher { ////////////////////////////////// public int getEnabledKeyboardLocaleCount() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getLocaleCount(); - } else { - return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); - } + return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); } public boolean useSpacebarLanguageSwitcher() { @@ -414,90 +434,40 @@ public class SubtypeSwitcher { } public Locale getInputLocale() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getInputLocale(); - } else { - return mInputLocale; - } + return mInputLocale; } public String getInputLocaleStr() { - if (mConfigUseSpacebarLanguageSwitcher) { - String inputLanguage = null; - inputLanguage = mLanguageSwitcher.getInputLanguage(); - // Should return system locale if there is no Language available. - if (inputLanguage == null) { - inputLanguage = getSystemLocale().getLanguage(); - } - return inputLanguage; - } else { - return mInputLocaleStr; - } + return mInputLocaleStr; } public String[] getEnabledLanguages() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getEnabledLanguages(); - } else { - int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); - // Workaround for explicitly specifying the voice language - if (enabledLanguageCount == 1) { - mEnabledLanguagesOfCurrentInputMethod.add( - mEnabledLanguagesOfCurrentInputMethod.get(0)); - ++enabledLanguageCount; - } - return mEnabledLanguagesOfCurrentInputMethod.toArray( - new String[enabledLanguageCount]); + int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); + // Workaround for explicitly specifying the voice language + if (enabledLanguageCount == 1) { + mEnabledLanguagesOfCurrentInputMethod.add(mEnabledLanguagesOfCurrentInputMethod + .get(0)); + ++enabledLanguageCount; } + return mEnabledLanguagesOfCurrentInputMethod.toArray(new String[enabledLanguageCount]); } public Locale getSystemLocale() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getSystemLocale(); - } else { - return mSystemLocale; - } + return mSystemLocale; } public boolean isSystemLanguageSameAsInputLanguage() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getSystemLocale().getLanguage().equalsIgnoreCase( - getInputLocaleStr().substring(0, 2)); - } else { - return mIsSystemLanguageSameAsInputLanguage; - } + return mIsSystemLanguageSameAsInputLanguage; } public void onConfigurationChanged(Configuration conf) { final Locale systemLocale = conf.locale; // If system configuration was changed, update all parameters. if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) { - if (mConfigUseSpacebarLanguageSwitcher) { - // If the system locale changes and is different from the saved - // locale (mSystemLocale), then reload the input locale list from the - // latin ime settings (shared prefs) and reset the input locale - // to the first one. - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(systemLocale); - } else { - updateAllParameters(); - } + updateAllParameters(); } } - /** - * Change system locale for this application - * @param newLocale - * @return oldLocale - */ - public Locale changeSystemLocale(Locale newLocale) { - Configuration conf = mResources.getConfiguration(); - Locale oldLocale = conf.locale; - conf.locale = newLocale; - mResources.updateConfiguration(conf, mResources.getDisplayMetrics()); - return oldLocale; - } - public boolean isKeyboardMode() { return KEYBOARD_MODE.equals(getCurrentSubtypeMode()); } @@ -507,9 +477,9 @@ public class SubtypeSwitcher { // Voice Input functions // /////////////////////////// - public boolean setVoiceInput(VoiceInput vi) { - if (mVoiceInput == null && vi != null) { - mVoiceInput = vi; + public boolean setVoiceInputWrapper(VoiceProxy.VoiceInputWrapper vi) { + if (mVoiceInputWrapper == null && vi != null) { + mVoiceInputWrapper = vi; if (isVoiceMode()) { if (DBG) { Log.d(TAG, "Set and call voice input.: " + getInputLocaleStr()); @@ -525,17 +495,85 @@ public class SubtypeSwitcher { return null == mCurrentSubtype ? false : VOICE_MODE.equals(getCurrentSubtypeMode()); } + public boolean isDummyVoiceMode() { + return mCurrentSubtype != null && mCurrentSubtype.getOriginalObject() == null + && VOICE_MODE.equals(getCurrentSubtypeMode()); + } + private void triggerVoiceIME() { if (!mService.isInputViewShown()) return; - VoiceIMEConnector.getInstance().startListening(false, - KeyboardSwitcher.getInstance().getInputView().getWindowToken()); + VoiceProxy.getInstance().startListening(false, + KeyboardSwitcher.getInstance().getKeyboardView().getWindowToken()); } ////////////////////////////////////// // Spacebar Language Switch support // ////////////////////////////////////// - private LanguageSwitcher mLanguageSwitcher; + private class LanguageBarInfo { + private int mCurrentKeyboardSubtypeIndex; + private InputMethodSubtypeCompatWrapper mNextKeyboardSubtype; + private InputMethodSubtypeCompatWrapper mPreviousKeyboardSubtype; + private String mNextLanguage; + private String mPreviousLanguage; + public LanguageBarInfo() { + update(); + } + + private String getNextLanguage() { + return mNextLanguage; + } + + private String getPreviousLanguage() { + return mPreviousLanguage; + } + + public InputMethodSubtypeCompatWrapper getNextKeyboardSubtype() { + return mNextKeyboardSubtype; + } + + public InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtype() { + return mPreviousKeyboardSubtype; + } + + public void update() { + if (!mConfigUseSpacebarLanguageSwitcher + || mEnabledKeyboardSubtypesOfCurrentInputMethod == null + || mEnabledKeyboardSubtypesOfCurrentInputMethod.size() == 0) return; + mCurrentKeyboardSubtypeIndex = getCurrentIndex(); + mNextKeyboardSubtype = getNextKeyboardSubtypeInternal(mCurrentKeyboardSubtypeIndex); + Locale locale = Utils.constructLocaleFromString(mNextKeyboardSubtype.getLocale()); + mNextLanguage = getFullDisplayName(locale, true); + mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal( + mCurrentKeyboardSubtypeIndex); + locale = Utils.constructLocaleFromString(mPreviousKeyboardSubtype.getLocale()); + mPreviousLanguage = getFullDisplayName(locale, true); + } + + private int normalize(int index) { + final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); + final int ret = index % N; + return ret < 0 ? ret + N : ret; + } + + private int getCurrentIndex() { + final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); + for (int i = 0; i < N; ++i) { + if (mEnabledKeyboardSubtypesOfCurrentInputMethod.get(i).equals(mCurrentSubtype)) { + return i; + } + } + return 0; + } + + private InputMethodSubtypeCompatWrapper getNextKeyboardSubtypeInternal(int index) { + return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index + 1)); + } + + private InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtypeInternal(int index) { + return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index - 1)); + } + } public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { if (returnsNameInThisLocale) { @@ -546,7 +584,12 @@ public class SubtypeSwitcher { } public static String getDisplayLanguage(Locale locale) { - return toTitleCase(locale.getDisplayLanguage(locale)); + return toTitleCase(SubtypeLocale.getFullDisplayName(locale)); + } + + public static String getMiddleDisplayLanguage(Locale locale) { + return toTitleCase((Utils.constructLocaleFromString( + locale.getLanguage()).getDisplayLanguage(locale))); } public static String getShortDisplayLanguage(Locale locale) { @@ -560,32 +603,16 @@ public class SubtypeSwitcher { return Character.toUpperCase(s.charAt(0)) + s.substring(1); } - private void updateForSpacebarLanguageSwitch() { - // We need to update mNeedsToDisplayLanguage in onStartInputView because - // getEnabledKeyboardLocaleCount could have been changed. - mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1 - && getSystemLocale().getLanguage().equalsIgnoreCase( - getInputLocale().getLanguage())); - } - public String getInputLanguageName() { return getDisplayLanguage(getInputLocale()); } public String getNextInputLanguageName() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale()); - } else { - return ""; - } + return mLanguageBarInfo.getNextLanguage(); } public String getPreviousInputLanguageName() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale()); - } else { - return ""; - } + return mLanguageBarInfo.getPreviousLanguage(); } ///////////////////////////// @@ -612,60 +639,36 @@ public class SubtypeSwitcher { } - // A list of locales which are supported by default for voice input, unless we get a - // different list from Gservices. - private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = - "en " + - "en_US " + - "en_GB " + - "en_AU " + - "en_CA " + - "en_IE " + - "en_IN " + - "en_NZ " + - "en_SG " + - "en_ZA "; - public boolean isVoiceSupported(String locale) { // Get the current list of supported locales and check the current locale against that // list. We cache this value so as not to check it every time the user starts a voice // input. Because this method is called by onStartInputView, this should mean that as // long as the locale doesn't change while the user is keeping the IME open, the // value should never be stale. - String supportedLocalesString = SettingsUtil.getSettingsString( - mService.getContentResolver(), - SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, - DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); + String supportedLocalesString = VoiceProxy.getSupportedLocalesString( + mService.getContentResolver()); List<String> voiceInputSupportedLocales = Arrays.asList( supportedLocalesString.split("\\s+")); return voiceInputSupportedLocales.contains(locale); } - public void loadSettings() { - if (mConfigUseSpacebarLanguageSwitcher) { - mLanguageSwitcher.loadLocales(mPrefs); - } + private void changeToNextSubtype() { + final InputMethodSubtypeCompatWrapper subtype = + mLanguageBarInfo.getNextKeyboardSubtype(); + switchToTargetIME(mInputMethodId, subtype); } - public void toggleLanguage(boolean reset, boolean next) { - if (mConfigUseSpacebarLanguageSwitcher) { - if (reset) { - mLanguageSwitcher.reset(); - } else { - if (next) { - mLanguageSwitcher.next(); - } else { - mLanguageSwitcher.prev(); - } - } - mLanguageSwitcher.persist(mPrefs); - } + private void changeToPreviousSubtype() { + final InputMethodSubtypeCompatWrapper subtype = + mLanguageBarInfo.getPreviousKeyboardSubtype(); + switchToTargetIME(mInputMethodId, subtype); } - private void initLanguageSwitcher(LatinIME service) { - final Configuration conf = service.getResources().getConfiguration(); - mLanguageSwitcher = new LanguageSwitcher(service); - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(conf.locale); + public void toggleLanguage(boolean next) { + if (next) { + changeToNextSubtype(); + } else { + changeToPreviousSubtype(); + } } } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 0de474e59..ca75866c0 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -47,7 +48,7 @@ public class Suggest implements Dictionary.WordCallback { /** * Words that appear in both bigram and unigram data gets multiplier ranging from - * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the frequency score from + * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the score from * bigram data. */ public static final double BIGRAM_MULTIPLIER_MIN = 1.2; @@ -55,7 +56,7 @@ public class Suggest implements Dictionary.WordCallback { /** * Maximum possible bigram frequency. Will depend on how many bits are being used in data - * structure. Maximum bigram freqeuncy will get the BIGRAM_MULTIPLIER_MAX as the multiplier. + * structure. Maximum bigram frequency will get the BIGRAM_MULTIPLIER_MAX as the multiplier. */ public static final int MAXIMUM_BIGRAM_FREQUENCY = 127; @@ -74,13 +75,11 @@ public class Suggest implements Dictionary.WordCallback { public static final String DICT_KEY_USER_BIGRAM = "user_bigram"; public static final String DICT_KEY_WHITELIST ="whitelist"; - static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000; - private static final boolean DBG = LatinImeLogger.sDBG; private AutoCorrection mAutoCorrection; - private BinaryDictionary mMainDict; + private Dictionary mMainDict; private WhitelistDictionary mWhiteListDictionary; private final Map<String, Dictionary> mUnigramDictionaries = new HashMap<String, Dictionary>(); private final Map<String, Dictionary> mBigramDictionaries = new HashMap<String, Dictionary>(); @@ -92,13 +91,13 @@ public class Suggest implements Dictionary.WordCallback { private boolean mQuickFixesEnabled; private double mAutoCorrectionThreshold; - private int[] mPriorities = new int[mPrefMaxSuggestions]; - private int[] mBigramPriorities = new int[PREF_MAX_BIGRAMS]; + private int[] mScores = new int[mPrefMaxSuggestions]; + private int[] mBigramScores = new int[PREF_MAX_BIGRAMS]; private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>(); ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>(); private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>(); - private String mLowerOriginalWord; + private CharSequence mTypedWord; // TODO: Remove these member variables by passing more context to addWord() callback method private boolean mIsFirstCharCapitalized; @@ -106,15 +105,18 @@ public class Suggest implements Dictionary.WordCallback { private int mCorrectionMode = CORRECTION_BASIC; - public Suggest(Context context, int dictionaryResId) { - init(context, BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN)); + public Suggest(Context context, int dictionaryResId, Locale locale) { + init(context, DictionaryFactory.createDictionaryFromManager(context, locale, + dictionaryResId)); } - /* package for test */ Suggest(File dictionary, long startOffset, long length) { - init(null, BinaryDictionary.initDictionary(dictionary, startOffset, length, DIC_MAIN)); + /* package for test */ Suggest(Context context, File dictionary, long startOffset, long length, + Flag[] flagArray) { + init(null, DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset, + length, flagArray)); } - private void init(Context context, BinaryDictionary mainDict) { + private void init(Context context, Dictionary mainDict) { if (mainDict != null) { mMainDict = mainDict; mUnigramDictionaries.put(DICT_KEY_MAIN, mainDict); @@ -128,6 +130,19 @@ public class Suggest implements Dictionary.WordCallback { initPool(); } + public void resetMainDict(Context context, int dictionaryResId, Locale locale) { + final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager( + context, locale, dictionaryResId); + mMainDict = newMainDict; + if (null == newMainDict) { + mUnigramDictionaries.remove(DICT_KEY_MAIN); + mBigramDictionaries.remove(DICT_KEY_MAIN); + } else { + mUnigramDictionaries.put(DICT_KEY_MAIN, newMainDict); + mBigramDictionaries.put(DICT_KEY_MAIN, newMainDict); + } + } + private void initPool() { for (int i = 0; i < mPrefMaxSuggestions; i++) { StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); @@ -148,7 +163,7 @@ public class Suggest implements Dictionary.WordCallback { } public boolean hasMainDictionary() { - return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD; + return mMainDict != null; } public Map<String, Dictionary> getUnigramDictionaries() { @@ -207,8 +222,8 @@ public class Suggest implements Dictionary.WordCallback { throw new IllegalArgumentException("maxSuggestions must be between 1 and 100"); } mPrefMaxSuggestions = maxSuggestions; - mPriorities = new int[mPrefMaxSuggestions]; - mBigramPriorities = new int[PREF_MAX_BIGRAMS]; + mScores = new int[mPrefMaxSuggestions]; + mBigramScores = new int[PREF_MAX_BIGRAMS]; collectGarbage(mSuggestions, mPrefMaxSuggestions); while (mStringPool.size() < mPrefMaxSuggestions) { StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); @@ -248,6 +263,16 @@ public class Suggest implements Dictionary.WordCallback { return sb; } + protected void addBigramToSuggestions(CharSequence bigram) { + final int poolSize = mStringPool.size(); + final StringBuilder sb = poolSize > 0 ? + (StringBuilder) mStringPool.remove(poolSize - 1) + : new StringBuilder(getApproxMaxWordLength()); + sb.setLength(0); + sb.append(bigram); + mSuggestions.add(sb); + } + // TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder public SuggestedWords.Builder getSuggestedWordBuilder(View view, WordComposer wordComposer, CharSequence prevWordForBigram) { @@ -256,25 +281,23 @@ public class Suggest implements Dictionary.WordCallback { mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); mIsAllUpperCase = wordComposer.isAllUpperCase(); collectGarbage(mSuggestions, mPrefMaxSuggestions); - Arrays.fill(mPriorities, 0); + Arrays.fill(mScores, 0); // Save a lowercase version of the original word CharSequence typedWord = wordComposer.getTypedWord(); if (typedWord != null) { final String typedWordString = typedWord.toString(); typedWord = typedWordString; - mLowerOriginalWord = typedWordString.toLowerCase(); // Treating USER_TYPED as UNIGRAM suggestion for logging now. LatinImeLogger.onAddSuggestedWord(typedWordString, Suggest.DIC_USER_TYPED, Dictionary.DataType.UNIGRAM); - } else { - mLowerOriginalWord = ""; } + mTypedWord = typedWord; - if (wordComposer.size() == 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM + if (wordComposer.size() <= 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM || mCorrectionMode == CORRECTION_BASIC)) { // At first character typed, search only the bigrams - Arrays.fill(mBigramPriorities, 0); + Arrays.fill(mBigramScores, 0); collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS); if (!TextUtils.isEmpty(prevWordForBigram)) { @@ -285,21 +308,26 @@ public class Suggest implements Dictionary.WordCallback { for (final Dictionary dictionary : mBigramDictionaries.values()) { dictionary.getBigrams(wordComposer, prevWordForBigram, this); } - char currentChar = wordComposer.getTypedWord().charAt(0); - char currentCharUpper = Character.toUpperCase(currentChar); - int count = 0; - int bigramSuggestionSize = mBigramSuggestions.size(); - for (int i = 0; i < bigramSuggestionSize; i++) { - if (mBigramSuggestions.get(i).charAt(0) == currentChar - || mBigramSuggestions.get(i).charAt(0) == currentCharUpper) { - int poolSize = mStringPool.size(); - StringBuilder sb = poolSize > 0 ? - (StringBuilder) mStringPool.remove(poolSize - 1) - : new StringBuilder(getApproxMaxWordLength()); - sb.setLength(0); - sb.append(mBigramSuggestions.get(i)); - mSuggestions.add(count++, sb); - if (count > mPrefMaxSuggestions) break; + if (TextUtils.isEmpty(typedWord)) { + // Nothing entered: return all bigrams for the previous word + int insertCount = Math.min(mBigramSuggestions.size(), mPrefMaxSuggestions); + for (int i = 0; i < insertCount; ++i) { + addBigramToSuggestions(mBigramSuggestions.get(i)); + } + } else { + // Word entered: return only bigrams that match the first char of the typed word + final char currentChar = typedWord.charAt(0); + final char currentCharUpper = Character.toUpperCase(currentChar); + int count = 0; + final int bigramSuggestionSize = mBigramSuggestions.size(); + for (int i = 0; i < bigramSuggestionSize; i++) { + final CharSequence bigramSuggestion = mBigramSuggestions.get(i); + final char bigramSuggestionFirstChar = bigramSuggestion.charAt(0); + if (bigramSuggestionFirstChar == currentChar + || bigramSuggestionFirstChar == currentCharUpper) { + addBigramToSuggestions(bigramSuggestion); + if (++count > mPrefMaxSuggestions) break; + } } } } @@ -346,7 +374,7 @@ public class Suggest implements Dictionary.WordCallback { mWhiteListDictionary.getWhiteListedWord(typedWordString)); mAutoCorrection.updateAutoCorrectionStatus(mUnigramDictionaries, wordComposer, - mSuggestions, mPriorities, typedWord, mAutoCorrectionThreshold, mCorrectionMode, + mSuggestions, mScores, typedWord, mAutoCorrectionThreshold, mCorrectionMode, autoText, whitelistedWord); if (autoText != null) { @@ -364,26 +392,25 @@ public class Suggest implements Dictionary.WordCallback { if (DBG) { double normalizedScore = mAutoCorrection.getNormalizedScore(); - ArrayList<SuggestedWords.SuggestedWordInfo> frequencyInfoList = + ArrayList<SuggestedWords.SuggestedWordInfo> scoreInfoList = new ArrayList<SuggestedWords.SuggestedWordInfo>(); - frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo("+", false)); - final int priorityLength = mPriorities.length; - for (int i = 0; i < priorityLength; ++i) { + scoreInfoList.add(new SuggestedWords.SuggestedWordInfo("+", false)); + for (int i = 0; i < mScores.length; ++i) { if (normalizedScore > 0) { - final String priorityThreshold = Integer.toString(mPriorities[i]) + " (" + - normalizedScore + ")"; - frequencyInfoList.add( - new SuggestedWords.SuggestedWordInfo(priorityThreshold, false)); + final String scoreThreshold = String.format("%d (%4.2f)", mScores[i], + normalizedScore); + scoreInfoList.add( + new SuggestedWords.SuggestedWordInfo(scoreThreshold, false)); normalizedScore = 0.0; } else { - final String priority = Integer.toString(mPriorities[i]); - frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo(priority, false)); + final String score = Integer.toString(mScores[i]); + scoreInfoList.add(new SuggestedWords.SuggestedWordInfo(score, false)); } } - for (int i = priorityLength; i < mSuggestions.size(); ++i) { - frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo("--", false)); + for (int i = mScores.length; i < mSuggestions.size(); ++i) { + scoreInfoList.add(new SuggestedWords.SuggestedWordInfo("--", false)); } - return new SuggestedWords.Builder().addWords(mSuggestions, frequencyInfoList); + return new SuggestedWords.Builder().addWords(mSuggestions, scoreInfoList); } return new SuggestedWords.Builder().addWords(mSuggestions, null); } @@ -419,52 +446,37 @@ public class Suggest implements Dictionary.WordCallback { return mAutoCorrection.hasAutoCorrection(); } - private static boolean compareCaseInsensitive(final String lowerOriginalWord, - final char[] word, final int offset, final int length) { - final int originalLength = lowerOriginalWord.length(); - if (originalLength == length && Character.isUpperCase(word[offset])) { - for (int i = 0; i < originalLength; i++) { - if (lowerOriginalWord.charAt(i) != Character.toLowerCase(word[offset+i])) { - return false; - } - } - return true; - } - return false; - } - @Override - public boolean addWord(final char[] word, final int offset, final int length, int freq, + public boolean addWord(final char[] word, final int offset, final int length, int score, final int dicTypeId, final Dictionary.DataType dataType) { Dictionary.DataType dataTypeForLog = dataType; - ArrayList<CharSequence> suggestions; - int[] priorities; - int prefMaxSuggestions; + final ArrayList<CharSequence> suggestions; + final int[] sortedScores; + final int prefMaxSuggestions; if(dataType == Dictionary.DataType.BIGRAM) { suggestions = mBigramSuggestions; - priorities = mBigramPriorities; + sortedScores = mBigramScores; prefMaxSuggestions = PREF_MAX_BIGRAMS; } else { suggestions = mSuggestions; - priorities = mPriorities; + sortedScores = mScores; prefMaxSuggestions = mPrefMaxSuggestions; } int pos = 0; // Check if it's the same word, only caps are different - if (compareCaseInsensitive(mLowerOriginalWord, word, offset, length)) { + if (Utils.equalsIgnoreCase(mTypedWord, word, offset, length)) { // TODO: remove this surrounding if clause and move this logic to // getSuggestedWordBuilder. if (suggestions.size() > 0) { - final String currentHighestWordLowerCase = - suggestions.get(0).toString().toLowerCase(); + final String currentHighestWord = suggestions.get(0).toString(); // If the current highest word is also equal to typed word, we need to compare // frequency to determine the insertion position. This does not ensure strictly // correct ordering, but ensures the top score is on top which is enough for // removing duplicates correctly. - if (compareCaseInsensitive(currentHighestWordLowerCase, word, offset, length) - && freq <= priorities[0]) { + if (Utils.equalsIgnoreCase(currentHighestWord, word, offset, length) + && score <= sortedScores[0]) { pos = 1; } } @@ -475,24 +487,24 @@ public class Suggest implements Dictionary.WordCallback { if(bigramSuggestion >= 0) { dataTypeForLog = Dictionary.DataType.BIGRAM; // turn freq from bigram into multiplier specified above - double multiplier = (((double) mBigramPriorities[bigramSuggestion]) + double multiplier = (((double) mBigramScores[bigramSuggestion]) / MAXIMUM_BIGRAM_FREQUENCY) * (BIGRAM_MULTIPLIER_MAX - BIGRAM_MULTIPLIER_MIN) + BIGRAM_MULTIPLIER_MIN; /* Log.d(TAG,"bigram num: " + bigramSuggestion + " wordB: " + mBigramSuggestions.get(bigramSuggestion).toString() - + " currentPriority: " + freq + " bigramPriority: " - + mBigramPriorities[bigramSuggestion] + + " currentScore: " + score + " bigramScore: " + + mBigramScores[bigramSuggestion] + " multiplier: " + multiplier); */ - freq = (int)Math.round((freq * multiplier)); + score = (int)Math.round((score * multiplier)); } } - // Check the last one's priority and bail - if (priorities[prefMaxSuggestions - 1] >= freq) return true; + // Check the last one's score and bail + if (sortedScores[prefMaxSuggestions - 1] >= score) return true; while (pos < prefMaxSuggestions) { - if (priorities[pos] < freq - || (priorities[pos] == freq && length < suggestions.get(pos).length())) { + if (sortedScores[pos] < score + || (sortedScores[pos] == score && length < suggestions.get(pos).length())) { break; } pos++; @@ -502,8 +514,8 @@ public class Suggest implements Dictionary.WordCallback { return true; } - System.arraycopy(priorities, pos, priorities, pos + 1, prefMaxSuggestions - pos - 1); - priorities[pos] = freq; + System.arraycopy(sortedScores, pos, sortedScores, pos + 1, prefMaxSuggestions - pos - 1); + sortedScores[pos] = score; int poolSize = mStringPool.size(); StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1) : new StringBuilder(getApproxMaxWordLength()); diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index fe7aac7c2..a8cdfc02e 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -32,14 +32,14 @@ public class SuggestedWords { public final List<SuggestedWordInfo> mSuggestedWordInfoList; private SuggestedWords(List<CharSequence> words, boolean typedWordValid, - boolean hasMinamlSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) { + boolean hasMinimalSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) { if (words != null) { mWords = words; } else { mWords = Collections.emptyList(); } mTypedWordValid = typedWordValid; - mHasMinimalSuggestion = hasMinamlSuggestion; + mHasMinimalSuggestion = hasMinimalSuggestion; mSuggestedWordInfoList = suggestedWordInfoList; } @@ -113,8 +113,8 @@ public class SuggestedWords { return this; } - public Builder setHasMinimalSuggestion(boolean hasMinamlSuggestion) { - mHasMinimalSuggestion = hasMinamlSuggestion; + public Builder setHasMinimalSuggestion(boolean hasMinimalSuggestion) { + mHasMinimalSuggestion = hasMinimalSuggestion; return this; } diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java index 63196430b..de13f3ae4 100644 --- a/java/src/com/android/inputmethod/latin/TextEntryState.java +++ b/java/src/com/android/inputmethod/latin/TextEntryState.java @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.latin.Utils.RingCharBuffer; + import android.util.Log; public class TextEntryState { @@ -43,10 +45,12 @@ public class TextEntryState { sState = newState; } - public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) { + public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord, + int separatorCode) { if (typedWord == null) return; setState(ACCEPTED_DEFAULT); - LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString()); + LatinImeLogger.logOnAutoCorrection( + typedWord.toString(), actualWord.toString(), separatorCode); if (DEBUG) displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord); } @@ -95,7 +99,7 @@ public class TextEntryState { if (DEBUG) displayState("onAbortRecorrection"); } - public static void typedCharacter(char c, boolean isSeparator) { + public static void typedCharacter(char c, boolean isSeparator, int x, int y) { final boolean isSpace = (c == ' '); switch (sState) { case IN_WORD: @@ -149,13 +153,19 @@ public class TextEntryState { setState(START); break; } + RingCharBuffer.getInstance().push(c, x, y); + if (isSeparator) { + LatinImeLogger.logOnInputSeparator(); + } else { + LatinImeLogger.logOnInputChar(); + } if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator); } public static void backspace() { if (sState == ACCEPTED_DEFAULT) { setState(UNDO_COMMIT); - LatinImeLogger.logOnAutoSuggestionCanceled(); + LatinImeLogger.logOnAutoCorrectionCancelled(); } else if (sState == UNDO_COMMIT) { setState(IN_WORD); } diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java index 656e6f8e0..5b615ca29 100644 --- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java @@ -44,12 +44,6 @@ public class UserBigramDictionary extends ExpandableDictionary { /** Maximum frequency for all pairs */ private static final int FREQUENCY_MAX = 127; - /** - * If this pair is typed 6 times, it would be suggested. - * Should be smaller than ContactsDictionary.FREQUENCY_FOR_CONTACTS_BIGRAM - */ - protected static final int SUGGEST_THRESHOLD = 6 * FREQUENCY_FOR_TYPED; - /** Maximum number of pairs. Pruning will start when databases goes above this number. */ private static int sMaxUserBigrams = 10000; @@ -164,10 +158,14 @@ public class UserBigramDictionary extends ExpandableDictionary { * Pair will be added to the userbigram database. */ public int addBigrams(String word1, String word2) { - // remove caps + // remove caps if second word is autocapitalized if (mIme != null && mIme.getCurrentWord().isAutoCapitalized()) { word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1); } + // Do not insert a word as a bigram of itself + if (word1.equals(word2)) { + return 0; + } int freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED); if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX; diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index 727e3f16d..5207f38ad 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -16,8 +16,14 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputTypeCompatUtils; +import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; +import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.os.AsyncTask; @@ -28,8 +34,6 @@ import android.text.InputType; import android.text.format.DateUtils; import android.util.Log; import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; import java.io.BufferedReader; import java.io.File; @@ -40,11 +44,14 @@ import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; +import java.util.Locale; public class Utils { private static final String TAG = Utils.class.getSimpleName(); private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; private static boolean DBG = LatinImeLogger.sDBG; + private static boolean DBG_EDIT_DISTANCE = false; private Utils() { // Intentional empty constructor for utility class. @@ -101,17 +108,22 @@ public class Utils { } } - public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm) { + public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManagerCompatWrapper imm) { return imm.getEnabledInputMethodList().size() > 1 // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled // input method subtype (The current IME should be LatinIME.) || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1; } - public static String getInputMethodId(InputMethodManager imm, String packageName) { - for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) { + public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) { + return getInputMethodInfo(imm, packageName).getId(); + } + + public static InputMethodInfoCompatWrapper getInputMethodInfo( + InputMethodManagerCompatWrapper imm, String packageName) { + for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) { if (imi.getPackageName().equals(packageName)) - return imi.getId(); + return imi; } throw new RuntimeException("Can not find input method id for " + packageName); } @@ -202,11 +214,11 @@ public class Utils { return mCharBuf[mEnd]; } } - public char getLastChar() { - if (mLength < 1) { + public char getBackwardNthChar(int n) { + if (mLength <= n || n < 0) { return PLACEHOLDER_DELIMITER_CHAR; } else { - return mCharBuf[normalize(mEnd - 1)]; + return mCharBuf[normalize(mEnd - n - 1)]; } } public int getPreviousX(char c, int back) { @@ -227,9 +239,16 @@ public class Utils { return mYBuf[index]; } } - public String getLastString() { + public String getLastWord(int ignoreCharCount) { StringBuilder sb = new StringBuilder(); - for (int i = 0; i < mLength; ++i) { + int i = ignoreCharCount; + for (; i < mLength; ++i) { + char c = mCharBuf[normalize(mEnd - 1 - i)]; + if (!((LatinIME)mContext).isWordSeparator(c)) { + break; + } + } + for (; i < mLength; ++i) { char c = mCharBuf[normalize(mEnd - 1 - i)]; if (!((LatinIME)mContext).isWordSeparator(c)) { sb.append(c); @@ -244,6 +263,8 @@ public class Utils { } } + + /* Damerau-Levenshtein distance */ public static int editDistance(CharSequence s, CharSequence t) { if (s == null || t == null) { throw new IllegalArgumentException("editDistance: Arguments should not be null."); @@ -259,12 +280,27 @@ public class Utils { } for (int i = 0; i < sl; ++i) { for (int j = 0; j < tl; ++j) { - if (Character.toLowerCase(s.charAt(i)) == Character.toLowerCase(t.charAt(j))) { - dp[i + 1][j + 1] = dp[i][j]; - } else { - dp[i + 1][j + 1] = 1 + Math.min(dp[i][j], - Math.min(dp[i + 1][j], dp[i][j + 1])); + final char sc = Character.toLowerCase(s.charAt(i)); + final char tc = Character.toLowerCase(t.charAt(j)); + final int cost = sc == tc ? 0 : 1; + dp[i + 1][j + 1] = Math.min( + dp[i][j + 1] + 1, Math.min(dp[i + 1][j] + 1, dp[i][j] + cost)); + // Overwrite for transposition cases + if (i > 0 && j > 0 + && sc == Character.toLowerCase(t.charAt(j - 1)) + && tc == Character.toLowerCase(s.charAt(i - 1))) { + dp[i + 1][j + 1] = Math.min(dp[i + 1][j + 1], dp[i - 1][j - 1] + cost); + } + } + } + if (DBG_EDIT_DISTANCE) { + Log.d(TAG, "editDistance:" + s + "," + t); + for (int i = 0; i < dp.length; ++i) { + StringBuffer sb = new StringBuffer(); + for (int j = 0; j < dp[i].length; ++j) { + sb.append(dp[i][j]).append(','); } + Log.d(TAG, i + ":" + sb.toString()); } } return dp[sl][tl]; @@ -285,7 +321,7 @@ public class Utils { // In dictionary.cpp, getSuggestion() method, // suggestion scores are computed using the below formula. - // original score (called 'frequency') + // original score // := pow(mTypedLetterMultiplier (this is defined 2), // (the number of matched characters between typed word and suggested word)) // * (individual word's score which defined in the unigram dictionary, @@ -295,7 +331,7 @@ public class Utils { // (full match up to min(before.length(), after.length()) // => Then multiply by FULL_MATCHED_WORDS_PROMOTION_RATE (this is defined 1.2) // - If the word is a true full match except for differences in accents or - // capitalization, then treat it as if the frequency was 255. + // capitalization, then treat it as if the score was 255. // - If before.length() == after.length() // => multiply by mFullWordMultiplier (this is defined 2)) // So, maximum original score is pow(2, min(before.length(), after.length())) * 255 * 2 * 1.2 @@ -306,6 +342,7 @@ public class Utils { private static final int MAX_INITIAL_SCORE = 255; private static final int TYPED_LETTER_MULTIPLIER = 2; private static final int FULL_WORD_MULTIPLIER = 2; + private static final int S_INT_MAX = 2147483647; public static double calcNormalizedScore(CharSequence before, CharSequence after, int score) { final int beforeLength = before.length(); final int afterLength = after.length(); @@ -313,8 +350,16 @@ public class Utils { final int distance = editDistance(before, after); // If afterLength < beforeLength, the algorithm is suggesting a word by excessive character // correction. - final double maximumScore = MAX_INITIAL_SCORE - * Math.pow(TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength)) + int spaceCount = 0; + for (int i = 0; i < afterLength; ++i) { + if (after.charAt(i) == Keyboard.CODE_SPACE) { + ++spaceCount; + } + } + if (spaceCount == afterLength) return 0; + final double maximumScore = score == S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE + * Math.pow( + TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength - spaceCount)) * FULL_WORD_MULTIPLIER; // add a weight based on edit distance. // distance <= max(afterLength, beforeLength) == afterLength, @@ -485,7 +530,7 @@ public class Utils { case InputType.TYPE_CLASS_PHONE: return KeyboardId.MODE_PHONE; case InputType.TYPE_CLASS_TEXT: - if (Utils.isEmailVariation(variation)) { + if (InputTypeCompatUtils.isEmailVariation(variation)) { return KeyboardId.MODE_EMAIL; } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { return KeyboardId.MODE_URL; @@ -503,31 +548,6 @@ public class Utils { } } - public static boolean isEmailVariation(int variation) { - return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS - || variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; - } - - // Please refer to TextView.isPasswordInputType - public static boolean isPasswordInputType(int inputType) { - final int variation = - inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); - return (variation - == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)) - || (variation - == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)) - || (variation - == (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD)); - } - - // Please refer to TextView.isVisiblePasswordInputType - public static boolean isVisiblePasswordInputType(int inputType) { - final int variation = - inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); - return variation - == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); - } - public static boolean containsInCsv(String key, String csv) { if (csv == null) return false; @@ -551,7 +571,9 @@ public class Utils { * @return main dictionary resource id */ public static int getMainDictionaryResourceId(Resources res) { - return res.getIdentifier("main", "raw", LatinIME.class.getPackage().getName()); + final String MAIN_DIC_NAME = "main"; + String packageName = LatinIME.class.getPackage().getName(); + return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); } public static void loadNativeLibrary() { @@ -561,4 +583,108 @@ public class Utils { Log.e(TAG, "Could not load native library jni_latinime"); } } + + /** + * Returns true if a and b are equal ignoring the case of the character. + * @param a first character to check + * @param b second character to check + * @return {@code true} if a and b are equal, {@code false} otherwise. + */ + public static boolean equalsIgnoreCase(char a, char b) { + // Some language, such as Turkish, need testing both cases. + return a == b + || Character.toLowerCase(a) == Character.toLowerCase(b) + || Character.toUpperCase(a) == Character.toUpperCase(b); + } + + /** + * Returns true if a and b are equal ignoring the case of the characters, including if they are + * both null. + * @param a first CharSequence to check + * @param b second CharSequence to check + * @return {@code true} if a and b are equal, {@code false} otherwise. + */ + public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) { + if (a == b) + return true; // including both a and b are null. + if (a == null || b == null) + return false; + final int length = a.length(); + if (length != b.length()) + return false; + for (int i = 0; i < length; i++) { + if (!equalsIgnoreCase(a.charAt(i), b.charAt(i))) + return false; + } + return true; + } + + /** + * Returns true if a and b are equal ignoring the case of the characters, including if a is null + * and b is zero length. + * @param a CharSequence to check + * @param b character array to check + * @param offset start offset of array b + * @param length length of characters in array b + * @return {@code true} if a and b are equal, {@code false} otherwise. + * @throws IndexOutOfBoundsException + * if {@code offset < 0 || length < 0 || offset + length > data.length}. + * @throws NullPointerException if {@code b == null}. + */ + public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) { + if (offset < 0 || length < 0 || length > b.length - offset) + throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset + + " length=" + length); + if (a == null) + return length == 0; // including a is null and b is zero length. + if (a.length() != length) + return false; + for (int i = 0; i < length; i++) { + if (!equalsIgnoreCase(a.charAt(i), b[offset + i])) + return false; + } + return true; + } + + public static float getDipScale(Context context) { + final float scale = context.getResources().getDisplayMetrics().density; + return scale; + } + + /** Convert pixel to DIP */ + public static int dipToPixel(float scale, int dip) { + return (int) (dip * scale + 0.5); + } + + public static Locale setSystemLocale(Resources res, Locale newLocale) { + final Configuration conf = res.getConfiguration(); + final Locale saveLocale = conf.locale; + conf.locale = newLocale; + res.updateConfiguration(conf, res.getDisplayMetrics()); + return saveLocale; + } + + private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>(); + + public static Locale constructLocaleFromString(String localeStr) { + if (localeStr == null) + return null; + synchronized (sLocaleCache) { + if (sLocaleCache.containsKey(localeStr)) + return sLocaleCache.get(localeStr); + Locale retval = null; + String[] localeParams = localeStr.split("_", 3); + if (localeParams.length == 1) { + retval = new Locale(localeParams[0]); + } else if (localeParams.length == 2) { + retval = new Locale(localeParams[0], localeParams[1]); + } else if (localeParams.length == 3) { + retval = new Locale(localeParams[0], localeParams[1], localeParams[2]); + } + if (retval != null) { + sLocaleCache.put(localeStr, retval); + } + return retval; + } + } } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 02583895b..af5e4b179 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -31,18 +31,18 @@ public class WordComposer { /** * The list of unicode values for each keystroke (including surrounding keys) */ - private final ArrayList<int[]> mCodes; + private ArrayList<int[]> mCodes; private int mTypedLength; - private final int[] mXCoordinates; - private final int[] mYCoordinates; + private int[] mXCoordinates; + private int[] mYCoordinates; /** * The word chosen from the candidate list, until it is committed. */ private String mPreferredWord; - private final StringBuilder mTypedWord; + private StringBuilder mTypedWord; private int mCapsCount; @@ -62,7 +62,11 @@ public class WordComposer { mYCoordinates = new int[N]; } - WordComposer(WordComposer source) { + public WordComposer(WordComposer source) { + init(source); + } + + public void init(WordComposer source) { mCodes = new ArrayList<int[]>(source.mCodes); mPreferredWord = source.mPreferredWord; mTypedWord = new StringBuilder(source.mTypedWord); |