diff options
122 files changed, 1922 insertions, 1392 deletions
diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml index a6ea38ba4..26cc042ab 100644 --- a/java/res/layout/emoji_palettes_view.xml +++ b/java/res/layout/emoji_palettes_view.xml @@ -20,10 +20,10 @@ <com.android.inputmethod.keyboard.emoji.EmojiPalettesView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/emoji_keyboard_view" - android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:orientation="vertical" style="?attr/emojiPalettesViewStyle" > <LinearLayout diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml index a4bcdcc8a..46551f63f 100644 --- a/java/res/layout/input_view.xml +++ b/java/res/layout/input_view.xml @@ -21,38 +21,11 @@ <com.android.inputmethod.latin.InputView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="bottom|center_horizontal" - android:orientation="vertical" > - <!-- The height of key_preview_backing view will automatically be determined by code. --> - <FrameLayout - android:id="@+id/key_preview_backing" - android:layout_width="match_parent" - android:layout_height="0dp" /> - <LinearLayout + android:layout_height="wrap_content"> + <include android:id="@+id/main_keyboard_frame" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" > - - <!-- To ensure that key preview popup is correctly placed when the current system locale is - one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> - <com.android.inputmethod.latin.suggestions.SuggestionStripView - android:id="@+id/suggestion_strip_view" - android:layoutDirection="ltr" - android:layout_width="match_parent" - android:layout_height="@dimen/config_suggestions_strip_height" - android:gravity="center_vertical" - style="?attr/suggestionStripViewStyle" /> - - <!-- To ensure that key preview popup is correctly placed when the current system locale is - one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> - <com.android.inputmethod.keyboard.MainKeyboardView - android:id="@+id/keyboard_view" - android:layoutDirection="ltr" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - </LinearLayout> + layout="@layout/main_keyboard_frame" /> <include + android:id="@+id/emoji_palettes_view" layout="@layout/emoji_palettes_view" /> </com.android.inputmethod.latin.InputView> diff --git a/java/res/layout/main_keyboard_frame.xml b/java/res/layout/main_keyboard_frame.xml new file mode 100644 index 000000000..ebf746679 --- /dev/null +++ b/java/res/layout/main_keyboard_frame.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:orientation="vertical" > + + <!-- To ensure that key preview popup is correctly placed when the current system locale is + one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> + <com.android.inputmethod.latin.suggestions.SuggestionStripView + android:id="@+id/suggestion_strip_view" + android:layoutDirection="ltr" + android:layout_width="match_parent" + android:layout_height="@dimen/config_suggestions_strip_height" + android:gravity="center_vertical" + style="?attr/suggestionStripViewStyle" /> + + <!-- To ensure that key preview popup is correctly placed when the current system locale is + one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> + <com.android.inputmethod.keyboard.MainKeyboardView + android:id="@+id/keyboard_view" + android:layoutDirection="ltr" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> +</LinearLayout> diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml index c1b7b765e..e90e54367 100644 --- a/java/res/values-af/strings.xml +++ b/java/res/values-af/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Hulp en terugvoering"</string> <string name="select_language" msgid="3693815588777926848">"Invoertale"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Raak weer om te stoor"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Raak hier om te stoor"</string> <string name="has_dictionary" msgid="6071847973466625007">"Woordeboek beskikbaar"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Sleutelbordtema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Engels (VK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Engels (VS)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spaans (VS)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engels (VK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engels (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaans (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisioneel)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cyrillies)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latyns)"</string> diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml index 15440fca7..34f4890bf 100644 --- a/java/res/values-am/strings.xml +++ b/java/res/values-am/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"እገዛ እና ግብረመልስ"</string> <string name="select_language" msgid="3693815588777926848">"ቋንቋዎች አግቤት"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"ለማስቀመጥ እንደገና ንካ"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"ለማስቀመጥ እዚህ ይንኩ"</string> <string name="has_dictionary" msgid="6071847973466625007">"መዝገበ ቃላት አለ"</string> <string name="keyboard_layout" msgid="8451164783510487501">"የቁልፍ ሰሌዳ ገጽታ"</string> <string name="subtype_en_GB" msgid="88170601942311355">"እንግሊዘኛ (የታላቋ ብሪታንያ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"እንግሊዘኛ (ዩ.ኤስ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ስፓኒሽኛ (ዩኤስ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ሂንግሊሽ"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"እንግሊዝኛ (ዩኬ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"እንግሊዝኛ (አሜሪካ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ስፓኒሽ (አሜሪካ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ሂንግሊሽ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ተለምዷዊ)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ሳይሪሊክ)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ላቲን)"</string> diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml index b6252c82d..2b4686bd3 100644 --- a/java/res/values-ar/strings.xml +++ b/java/res/values-ar/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"المساعدة والتعليقات"</string> <string name="select_language" msgid="3693815588777926848">"لغات الإدخال"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"المس مرة أخرى للحفظ"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"المس هنا للحفظ"</string> <string name="has_dictionary" msgid="6071847973466625007">"القاموس متاح"</string> <string name="keyboard_layout" msgid="8451164783510487501">"مظهر لوحة المفاتيح"</string> <string name="subtype_en_GB" msgid="88170601942311355">"الإنجليزية (المملكة المتحدة)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"الإنجليزية (الولايات المتحدة)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"الإسبانية (الأميركية)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"هنجليزية"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"الإنجليزية (المملكة المتحدة) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"الإنجليزية (الولايات المتحدة) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"الإسبانية (الولايات المتحدة) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"هنجليزية (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (التقليدية)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (السريلية)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (اللاتينية)"</string> diff --git a/java/res/values-az-rAZ/strings.xml b/java/res/values-az-rAZ/strings.xml index 1d11e84cf..2487748c9 100644 --- a/java/res/values-az-rAZ/strings.xml +++ b/java/res/values-az-rAZ/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Yardım və geri əlaqə"</string> <string name="select_language" msgid="3693815588777926848">"Daxiletmə dilləri"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Yadda saxlamaq üçün yenidən toxunun"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Yadda saxlamaq üçün buraya toxunun"</string> <string name="has_dictionary" msgid="6071847973466625007">"Lüğət mövcuddur"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatura teması"</string> <string name="subtype_en_GB" msgid="88170601942311355">"İngilis (BK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"İngilis (ABŞ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"İspan (ABŞ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hingilis"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"İngilis (Britaniya) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"İngilis (Amerika) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"İspan (Amerika) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hingilis (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Ənənəvi)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kiril)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latın)"</string> diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml index f4af1db30..1ead030ae 100644 --- a/java/res/values-bg/strings.xml +++ b/java/res/values-bg/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Помощ и отзиви"</string> <string name="select_language" msgid="3693815588777926848">"Езици за въвеждане"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Докоснете отново, за да запазите"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Докоснете тук, за да запазите"</string> <string name="has_dictionary" msgid="6071847973466625007">"Има достъп до речник"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Тема на клавиатурата"</string> <string name="subtype_en_GB" msgid="88170601942311355">"английски (Великобритания)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"английски (САЩ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"испански (САЩ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хинглиш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"английски (Великобр.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"английски (САЩ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"испански (САЩ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционна клавиатура)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (кирилица)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (латиница)"</string> diff --git a/java/res/values-bn-rBD/strings.xml b/java/res/values-bn-rBD/strings.xml index b52409e7b..f8ea9ad10 100644 --- a/java/res/values-bn-rBD/strings.xml +++ b/java/res/values-bn-rBD/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"সহায়তা এবং প্রতিক্রিয়া"</string> <string name="select_language" msgid="3693815588777926848">"ইনপুট ভাষাগুলি"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"সংরক্ষণ করতে আবার ছোঁন"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"সংরক্ষণ করতে এখানে স্পর্শ করুন"</string> <string name="has_dictionary" msgid="6071847973466625007">"অভিধান উপলব্ধ"</string> <string name="keyboard_layout" msgid="8451164783510487501">"কীবোর্ড থিম"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ইংরেজি (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ইংরেজি (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"স্প্যানিশ (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"হিংলিশ"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ইংরেজি (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ইংরেজি (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"স্প্যানিশ (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"হিংলিশ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ঐতিহ্যবাহি)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (সিরিলিক)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ল্যাটিন)"</string> diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml index 2fab1b790..e37bd05bf 100644 --- a/java/res/values-ca/strings.xml +++ b/java/res/values-ca/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ajuda i opinió"</string> <string name="select_language" msgid="3693815588777926848">"Idiomes d\'introducció"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Torna a tocar per desar"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Toca aquí per desar."</string> <string name="has_dictionary" msgid="6071847973466625007">"Diccionari disponible"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclat"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Anglès (Regne Unit)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Anglès (EUA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Espanyol (EUA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Anglès (Regne Unit) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Anglès (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Espanyol (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ciríl·lic)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (llatí)"</string> diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml index 265e457ca..883fbdf5e 100644 --- a/java/res/values-cs/strings.xml +++ b/java/res/values-cs/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Nápověda a zpětná vazba"</string> <string name="select_language" msgid="3693815588777926848">"Vstupní jazyky"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Opětovným dotykem provedete uložení"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Klepnutím sem položku uložíte"</string> <string name="has_dictionary" msgid="6071847973466625007">"Slovník k dispozici"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Motiv klávesnice"</string> <string name="subtype_en_GB" msgid="88170601942311355">"angličtina (Velká Británie)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"angličtina (USA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"španělština (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angličtina (VB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angličtina (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španělština (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradiční)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cyrilice)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latinka)"</string> diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml index 2e7c88abf..caaafccfa 100644 --- a/java/res/values-da/strings.xml +++ b/java/res/values-da/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Hjælp og feedback"</string> <string name="select_language" msgid="3693815588777926848">"Inputsprog"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Tryk igen for at gemme"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Klik her for at gemme"</string> <string name="has_dictionary" msgid="6071847973466625007">"Ordbog er tilgængelig"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Engelsk (Storbritannien)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Engelsk (USA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spansk (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelsk (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelsk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spansk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionelt)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kyrillisk)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latin)"</string> diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml index cf4c5543a..0a6155ad6 100644 --- a/java/res/values-de/strings.xml +++ b/java/res/values-de/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Hilfe & Feedback"</string> <string name="select_language" msgid="3693815588777926848">"Eingabesprachen"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Zum Speichern erneut berühren"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Tippen Sie hier zum Speichern."</string> <string name="has_dictionary" msgid="6071847973466625007">"Wörterbuch verfügbar"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tastaturdesign"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Englisch (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Englisch (USA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spanisch (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Englisch (GB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Englisch (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanisch (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionell)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kyrillisch)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (lateinisch)"</string> diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml index 239541f0f..825af727d 100644 --- a/java/res/values-el/strings.xml +++ b/java/res/values-el/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Βοήθεια και σχόλια"</string> <string name="select_language" msgid="3693815588777926848">"Γλώσσες εισόδου"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Αγγίξτε ξανά για αποθήκευση"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Αγγίξτε εδώ για αποθήκευση"</string> <string name="has_dictionary" msgid="6071847973466625007">"Λεξικό διαθέσιμο"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Θέμα πληκτρολογίου"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Αγγλικά (Η.Β.)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Αγγλικά (Η.Π.Α)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Ισπανικά (ΗΠΑ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Αγγλικά (Ηνωμένο Βασίλειο) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Αγγλικά (ΗΠΑ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Ισπανικά (ΗΠΑ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Παραδοσιακά)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Κυριλλικά)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Λατινικά)"</string> diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml index a8a7ade52..a671c2aec 100644 --- a/java/res/values-en-rGB/strings.xml +++ b/java/res/values-en-rGB/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Help & feedback"</string> <string name="select_language" msgid="3693815588777926848">"Input languages"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Touch again to save"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Touch here to save"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string> <string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spanish (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"English (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"English (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cyrillic)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latin)"</string> diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml index a8a7ade52..a671c2aec 100644 --- a/java/res/values-en-rIN/strings.xml +++ b/java/res/values-en-rIN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Help & feedback"</string> <string name="select_language" msgid="3693815588777926848">"Input languages"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Touch again to save"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Touch here to save"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string> <string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spanish (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"English (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"English (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cyrillic)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latin)"</string> diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml index 84135efef..b643d5a2f 100644 --- a/java/res/values-es-rUS/strings.xml +++ b/java/res/values-es-rUS/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ayuda y comentarios"</string> <string name="select_language" msgid="3693815588777926848">"Idiomas de entrada"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Vuelve a tocar para guardar."</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Tocar aquí para guardar."</string> <string name="has_dictionary" msgid="6071847973466625007">"Diccionario disponible"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglés (Reino Unido)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Inglés (EE.UU.)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Español (EE.UU.)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglés, Reino Unido (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglés, EE. UU. (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Español, EE. UU. (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cirílico)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latinoamérica)"</string> diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml index 98b985b6d..07b4bffb4 100644 --- a/java/res/values-es/strings.xml +++ b/java/res/values-es/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ayuda y opiniones"</string> <string name="select_language" msgid="3693815588777926848">"Idiomas de introducción"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Toca otra vez para guardar"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Toca aquí para guardar"</string> <string name="has_dictionary" msgid="6071847973466625007">"Hay un diccionario disponible"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema de teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"inglés (Reino Unido)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"inglés (EE.UU.)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Español (EE.UU.)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglés (Reino Unido) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglés (EE.UU.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Español (EE.UU.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cirílico)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latinoamérica)"</string> diff --git a/java/res/values-et-rEE/strings.xml b/java/res/values-et-rEE/strings.xml index 042f7cfac..c4f940b95 100644 --- a/java/res/values-et-rEE/strings.xml +++ b/java/res/values-et-rEE/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Abi ja tagasiside"</string> <string name="select_language" msgid="3693815588777926848">"Sisestuskeeled"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Salvestamiseks puudutage uuesti"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Salvestamiseks puudutage siin"</string> <string name="has_dictionary" msgid="6071847973466625007">"Sõnastik saadaval"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatuuri teema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglise (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Inglise (USA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"hispaania (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindi-inglise"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglise (Ühendk.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglise (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Hispaania (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi-inglise (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditsiooniline)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kirillitsa)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ladina)"</string> diff --git a/java/res/values-eu-rES/strings.xml b/java/res/values-eu-rES/strings.xml index f3128ae52..f3704ad4c 100644 --- a/java/res/values-eu-rES/strings.xml +++ b/java/res/values-eu-rES/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Laguntza eta iritziak"</string> <string name="select_language" msgid="3693815588777926848">"Idazketa-hizkuntzak"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Gordetzeko, ukitu berriro"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Gordetzeko, ukitu hau"</string> <string name="has_dictionary" msgid="6071847973466625007">"Hiztegia erabilgarri"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Teklatuaren gaia"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Ingelesa (Erresuma Batua)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Ingelesa (AEB)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Gaztelania (AEB)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglisha"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Ingelesa (Erresuma Batua) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Ingelesa (AEB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Gaztelania (AEB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglisha (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradizionala)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (zirilikoa)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latindarra)"</string> diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml index ff6831389..dbde38fac 100644 --- a/java/res/values-fa/strings.xml +++ b/java/res/values-fa/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"راهنما و بازخورد"</string> <string name="select_language" msgid="3693815588777926848">"زبانهای ورودی"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"برای ذخیره دوباره لمس کنید"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"برای ذخیره اینجا را لمس کنید"</string> <string name="has_dictionary" msgid="6071847973466625007">"دیکشنری موجود است"</string> <string name="keyboard_layout" msgid="8451164783510487501">"طرح زمینه صفحهکلید"</string> <string name="subtype_en_GB" msgid="88170601942311355">"انگلیسی (بریتانیا)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"انگلیسی (امریکا)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"اسپانیایی (آمریکا)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"هندی انگلیسی"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"انگلیسی (بریتانیا) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"انگلیسی (آمریکا) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"اسپانیایی (آمریکا) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"هندی انگلیسی (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (سنتی)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (سیریلیک)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (لاتین)"</string> diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml index 1f06b0729..1dbdb5ab7 100644 --- a/java/res/values-fi/strings.xml +++ b/java/res/values-fi/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ohje ja palaute"</string> <string name="select_language" msgid="3693815588777926848">"Syöttökielet"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Tallenna koskettamalla uudelleen"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Tallenna koskettamalla tätä"</string> <string name="has_dictionary" msgid="6071847973466625007">"Sanakirja saatavilla"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Näppäimistöteema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"englanti (Iso-Britannia)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"englanti (Yhdysvallat)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"espanja (Yhdysvallat)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindienglanti"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"englanti (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"englanti (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"espanja (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindienglanti (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (perinteinen)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kyrillinen)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latinalainen)"</string> diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml index e2cf8cfda..dbfb588e9 100644 --- a/java/res/values-fr-rCA/strings.xml +++ b/java/res/values-fr-rCA/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Aide et commentaires"</string> <string name="select_language" msgid="3693815588777926848">"Langues de saisie"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Appuyer de nouveau pour enregistrer"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Touchez ici pour enregistrer le mot dans le dictionnaire"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Anglais (britannique)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Anglais (États-Unis)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Espagnol (États-Unis)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"anglais (Royaume-Uni) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"anglais (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"espagnol (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cyrillique)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latin)"</string> diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml index 75961d1f4..3a308f970 100644 --- a/java/res/values-fr/strings.xml +++ b/java/res/values-fr/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Aide et commentaires"</string> <string name="select_language" msgid="3693815588777926848">"Langues de saisie"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Appuyer de nouveau pour enregistrer"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Appuyez ici pour enregistrer."</string> <string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Anglais (Royaume-Uni)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Anglais (États-Unis)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Espagnol (États-Unis)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindi/Anglais"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"anglais (Royaume-Uni) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"anglais (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"espagnol (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi/Anglais (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cyrillique)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latin)"</string> diff --git a/java/res/values-gl-rES/strings.xml b/java/res/values-gl-rES/strings.xml index 40431e754..9b2494989 100644 --- a/java/res/values-gl-rES/strings.xml +++ b/java/res/values-gl-rES/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Axuda e opinións"</string> <string name="select_language" msgid="3693815588777926848">"Idiomas de entrada"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Toca de novo para gardar"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Toca aquí para gardar"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dicionario dispoñible"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglés (Reino Unido)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Inglés (EUA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Español (EUA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglés (Reino Unido) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglés (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Español (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cirílico)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latino)"</string> diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml index 86d513058..ab6eb8137 100644 --- a/java/res/values-hi/strings.xml +++ b/java/res/values-hi/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"सहायता और फ़ीडबैक"</string> <string name="select_language" msgid="3693815588777926848">"इनपुट भाषाएं"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"सहेजने के लिए पुन: स्पर्श करें"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"सहेजने के लिए यहां स्पर्श करें"</string> <string name="has_dictionary" msgid="6071847973466625007">"शब्दकोश उपलब्ध है"</string> <string name="keyboard_layout" msgid="8451164783510487501">"कीबोर्ड थीम"</string> <string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेज़ी (यूके)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेज़ी (यूएस)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"स्पेनिश (यूएस)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"हिंग्लिश"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"अंग्रेज़ी (यूके) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"अंग्रेज़ी (यूएस) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"स्पेनिश (यूएस) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"हिंग्लिश (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (पारंपरिक)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (सिरिलिक)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (लैटिन)"</string> diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml index d6b1352e4..668d6c5f2 100644 --- a/java/res/values-hr/strings.xml +++ b/java/res/values-hr/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Pomoć i povratne informacije"</string> <string name="select_language" msgid="3693815588777926848">"Jezici unosa"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Dodirnite ponovo za spremanje"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Dodirnite ovdje za spremanje"</string> <string name="has_dictionary" msgid="6071847973466625007">"Rječnik je dostupan"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Engleski (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Engleski (SAD)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"španjolski (SAD)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"engleska (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"engleska (SAD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španjolska (SAD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalni)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ćirilica)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latinica)"</string> diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml index b38d1bf8c..456078802 100644 --- a/java/res/values-hu/strings.xml +++ b/java/res/values-hu/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Súgó és visszajelzés"</string> <string name="select_language" msgid="3693815588777926848">"Beviteli nyelvek"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Érintse meg újból a mentéshez"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"A mentéshez érintse meg itt"</string> <string name="has_dictionary" msgid="6071847973466625007">"Van elérhető szótár"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Billentyűzettéma"</string> <string name="subtype_en_GB" msgid="88170601942311355">"angol (brit)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"angol (amerikai)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"spanyol (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish (hindi-angol)"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angol (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angol (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"spanyol (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (hindi-angol, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (hagyományos)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cirill)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latin)"</string> diff --git a/java/res/values-hy-rAM/strings.xml b/java/res/values-hy-rAM/strings.xml index 26a3b0266..1e14263cf 100644 --- a/java/res/values-hy-rAM/strings.xml +++ b/java/res/values-hy-rAM/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Օգնություն և հետադարձ կապ"</string> <string name="select_language" msgid="3693815588777926848">"Մուտքագրման լեզուներ"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Պահպանելու համար կրկին հպեք"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Պահելու համար հպեք այստեղ"</string> <string name="has_dictionary" msgid="6071847973466625007">"Բառարանն առկա է"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Ստեղնաշարի թեման"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Անգլերեն (ՄԹ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Անգլերեն (ԱՄՆ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Իսպաներեն (ԱՄՆ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Հինգլիշ"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Անգլերեն (ՄԹ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Անգլերեն (ԱՄՆ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Իսպաներեն (ԱՄՆ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Հինգլիշ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ավանդական)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (կյուրեղյան)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (լատինական)"</string> diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml index 9c898b7d7..0169995d0 100644 --- a/java/res/values-in/strings.xml +++ b/java/res/values-in/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Bantuan & masukan"</string> <string name="select_language" msgid="3693815588777926848">"Bahasa masukan"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Sentuh lagi untuk menyimpan"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Sentuh di sini untuk menyimpan"</string> <string name="has_dictionary" msgid="6071847973466625007">"Kamus yang tersedia"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema keyboard"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inggris (Inggris)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Inggris (AS)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spanyol (AS)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>) Inggris (Inggris)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>) Inggris (AS)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>) Spanyol (AS)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Sirilik)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latin)"</string> diff --git a/java/res/values-is-rIS/strings.xml b/java/res/values-is-rIS/strings.xml index 8d46c896b..51f4f9b6d 100644 --- a/java/res/values-is-rIS/strings.xml +++ b/java/res/values-is-rIS/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Hjálp og ábendingar"</string> <string name="select_language" msgid="3693815588777926848">"Innsláttartungumál"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Snertu aftur til að vista"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Snertu hér til að vista"</string> <string name="has_dictionary" msgid="6071847973466625007">"Orðabók í boði"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Þema lyklaborðs"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Enskt (Bretland)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Enskt (Bandaríkin)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spænskt (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Enskt (Bretland) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Enskt (Bandaríkin) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spænskt (Bandaríkin) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (hefðbundið)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kyrillískt)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latneskt)"</string> diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml index 4f81588d4..32a9e37d0 100644 --- a/java/res/values-it/strings.xml +++ b/java/res/values-it/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Guida e feedback"</string> <string name="select_language" msgid="3693815588777926848">"Lingue comandi"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Tocca di nuovo per salvare"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Tocca qui per salvare"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dizionario disponibile"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema della tastiera"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglese (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Inglese (USA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spagnolo (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglese (Regno Unito) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglese (Stati Uniti) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spagnolo (Stati Uniti) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradizionale)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cirillico)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latino)"</string> diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml index 4f331a3a9..be4f8fedb 100644 --- a/java/res/values-iw/strings.xml +++ b/java/res/values-iw/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"עזרה ומשוב"</string> <string name="select_language" msgid="3693815588777926848">"שפות קלט"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"גע שוב כדי לשמור"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"גע כאן כדי לשמור"</string> <string name="has_dictionary" msgid="6071847973466625007">"מילון זמין"</string> <string name="keyboard_layout" msgid="8451164783510487501">"עיצוב מקלדת"</string> <string name="subtype_en_GB" msgid="88170601942311355">"אנגלית (בריטניה)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"אנגלית (ארה\"ב)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ספרדית (ארצות הברית)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"אנגלית הודית"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"אנגלית (בריטניה) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"אנגלית (ארה\"ב) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ספרדית (ארה\"ב) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"אנגלית הודית (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (מסורתית)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (קירילית)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (לטינית)"</string> diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml index 97f84e7f8..26da0440b 100644 --- a/java/res/values-ja/strings.xml +++ b/java/res/values-ja/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"ヘルプとフィードバック"</string> <string name="select_language" msgid="3693815588777926848">"入力言語"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"保存するにはもう一度タップ"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"ここをタップして保存します"</string> <string name="has_dictionary" msgid="6071847973466625007">"辞書を利用できます"</string> <string name="keyboard_layout" msgid="8451164783510487501">"キーボードのテーマ"</string> <string name="subtype_en_GB" msgid="88170601942311355">"英語 (英国)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"英語 (米国)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"スペイン語 (米国)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ヒングリッシュ"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英語(英国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英語(米国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"スペイン語(米国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ヒングリッシュ(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(伝統言語)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(キリル文字)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(ラテン文字)"</string> diff --git a/java/res/values-ka-rGE/strings.xml b/java/res/values-ka-rGE/strings.xml index a42b6dfb4..784edd2d9 100644 --- a/java/res/values-ka-rGE/strings.xml +++ b/java/res/values-ka-rGE/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"დახმარება და უკუკავშირი"</string> <string name="select_language" msgid="3693815588777926848">"შეყვანის ენები"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"შეეხეთ ისევ შესანახად"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"აქ შეეხეთ, რომ შეინახოს"</string> <string name="has_dictionary" msgid="6071847973466625007">"ხელმისაწვდომია ლექსიკონი"</string> <string name="keyboard_layout" msgid="8451164783510487501">"კლავიატურის თემა"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ინგლისური (გართ. სამ.)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ინგლისური (აშშ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ესპანური (აშშ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ჰინგლისური"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ინგლისური (გაერთ.სამ.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ინგლისური (აშშ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ესპანური (აშშ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ჰინგლისური (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ტრადიციული)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (კირილიცა)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ლათინური)"</string> diff --git a/java/res/values-kk-rKZ/strings.xml b/java/res/values-kk-rKZ/strings.xml index 64ee430fc..490c357ca 100644 --- a/java/res/values-kk-rKZ/strings.xml +++ b/java/res/values-kk-rKZ/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Анықтама және кері байланыс"</string> <string name="select_language" msgid="3693815588777926848">"Енгізу тілдері"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Сақтау үшін қайта түртіңіз"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Сақтау үшін осы жерді түртіңіз"</string> <string name="has_dictionary" msgid="6071847973466625007">"Сөздік қолжетімді"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Пернетақта тақырыбы"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ағылшын (ҰБ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ағылшын (АҚШ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Испан (АҚШ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хинглиш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Ағылшын (Құрама Корольдік) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Ағылшын (АҚШ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Испан (АҚШ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (дәстүрлі)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (кириллица)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (латиница)"</string> diff --git a/java/res/values-km-rKH/strings.xml b/java/res/values-km-rKH/strings.xml index 2ea86b9c6..31efc8b97 100644 --- a/java/res/values-km-rKH/strings.xml +++ b/java/res/values-km-rKH/strings.xml @@ -38,7 +38,7 @@ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"បង្ហាញនៅពេលដែលបើកភាសាបញ្ចូលច្រើន"</string> <string name="sliding_key_input_preview" msgid="6604262359510068370">"បង្ហាញទ្រនិចបង្ហាញស្លាយ"</string> <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"បង្ហាញសញ្ញាមើលឃើញខណៈពេលដែលរុញពីឆ្វេង ឬគ្រាប់ចុចនិមិត្តសញ្ញា"</string> - <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"សោលេចឡើងបោះបង់ការពន្យារពេល"</string> + <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"សោលេចឡើងបោះបង់ការពន្យារពេល"</string> <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"គ្មានការពន្យារពេល"</string> <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"លំនាំដើម"</string> <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> មិល្លីវិនាទី"</string> @@ -49,7 +49,7 @@ <string name="enable_metrics_logging" msgid="5506372337118822837">"ធ្វើឲ្យ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ប្រសើរឡើង"</string> <string name="use_double_space_period" msgid="8781529969425082860">"រយៈពេលចុចដកឃ្លាពីរដង"</string> <string name="use_double_space_period_summary" msgid="6532892187247952799">"ប៉ះដកឃ្លាពីរដងបញ្ចូលរយៈពេលដែលអនុវត្តតាមដកឃ្លា"</string> - <string name="auto_cap" msgid="1719746674854628252">"ការសរសេរជាអក្សរធំស្វ័យប្រវត្តិ"</string> + <string name="auto_cap" msgid="1719746674854628252">"ការសរសេរជាអក្សរធំស្វ័យប្រវត្តិ"</string> <string name="auto_cap_summary" msgid="7934452761022946874">"សរសេរពាក្យដំបូងជាអក្សរធំនៃប្រយោគនីមួយៗ"</string> <string name="edit_personal_dictionary" msgid="3996910038952940420">"វចនានុក្រមផ្ទាល់ខ្លួន"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"ផ្នែកបន្ថែមវចនានុក្រម"</string> @@ -57,7 +57,7 @@ <string name="prefs_show_suggestions" msgid="8026799663445531637">"បង្ហាញការស្នើកែ"</string> <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"បង្ហាញពាក្យបានផ្ដល់ស្នើខណៈពេលវាយបញ្ចូល"</string> <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"ទប់ស្កាត់ពាក្យបំពាន"</string> - <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"កុំស្នើឲ្យពាក្យបំពានមានសក្ដានុពល"</string> + <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"កុំស្នើឲ្យពាក្យបំពានមានសក្ដានុពល"</string> <string name="auto_correction" msgid="7630720885194996950">"ការកែស្វ័យប្រវត្តិ"</string> <string name="auto_correction_summary" msgid="5625751551134658006">"ចន្លោះមិនឃើញ និងសញ្ញាវណ្ណយុត្តកែពាក្យដែលបានវាយខុសស្វ័យប្រវត្តិ"</string> <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"បិទ"</string> @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"ជំនួយ & មតិត្រឡប់"</string> <string name="select_language" msgid="3693815588777926848">"បញ្ចូលភាសា"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"ប៉ះម្ដងទៀត ដើម្បីរក្សាទុក"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"ប៉ះទីនេះដើម្បីរក្សាទុក"</string> <string name="has_dictionary" msgid="6071847973466625007">"មានវចនានុក្រម"</string> <string name="keyboard_layout" msgid="8451164783510487501">"រូបរាងក្ដារចុច"</string> <string name="subtype_en_GB" msgid="88170601942311355">"អង់គ្លេស (អង់គ្លេស)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"អង់គ្លេស (សហរដ្ឋអាមេរិក)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"អេស្ប៉ាញ (សហរដ្ឋអាមេរិក)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"អង់គ្លេស (ចក្រភពអង់គ្លេស) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"អង់គ្លេស (អាមេរិក) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"អេស្ប៉ាញ (អាមេរិក) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (អក្សរពេញ)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ស៊ីរី)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ឡាតាំង)"</string> @@ -115,7 +118,7 @@ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ថិរវេលាញ័រពេលចុចគ្រាប់ចុច"</string> <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"កម្រិតសំឡេងពេលចុចគ្រាប់ចុច"</string> <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"អានឯកសារវចនានុក្រមខាងក្រៅ"</string> - <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"គ្មានឯកសារវចនានុក្រមនៅក្នុងថតទាញយក"</string> + <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"គ្មានឯកសារវចនានុក្រមនៅក្នុងថតទាញយក"</string> <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ជ្រើសឯកសារវចនានុក្រម ដើម្បីដំឡើង"</string> <string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"ពិតជាដំឡើងឯកសារនេះសម្រាប់ <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string> <string name="error" msgid="8940763624668513648">"មានកំហុស"</string> @@ -142,7 +145,7 @@ <string name="dictionary_provider_name" msgid="3027315045397363079">"កម្មវិធីផ្ដល់វចនានុក្រម"</string> <string name="dictionary_service_name" msgid="6237472350693511448">"សេវាកម្មវចនានុក្រម"</string> <string name="download_description" msgid="6014835283119198591">"ព័ត៌មានបច្ចុប្បន្នភាពវចនានុក្រម"</string> - <string name="dictionary_settings_title" msgid="8091417676045693313">"ផ្នែកបន្ថែមវចនានុក្រម"</string> + <string name="dictionary_settings_title" msgid="8091417676045693313">"ផ្នែកបន្ថែមវចនានុក្រម"</string> <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"វចនានុក្រមអាចប្រើបាន"</string> <string name="dictionary_settings_summary" msgid="5305694987799824349">"ការកំណត់សម្រាប់វចនានុក្រម"</string> <string name="user_dictionaries" msgid="3582332055892252845">"វចនានុក្រមអ្នកប្រើ"</string> @@ -158,10 +161,10 @@ <string name="message_updating" msgid="4457761393932375219">"ពិនិត្យមើលបច្ចុប្បន្នភាព"</string> <string name="message_loading" msgid="5638680861387748936">"កំពុងផ្ទុក..."</string> <string name="main_dict_description" msgid="3072821352793492143">"វចនានុក្រមចម្បង"</string> - <string name="cancel" msgid="6830980399865683324">"បោះបង់"</string> + <string name="cancel" msgid="6830980399865683324">"បោះបង់"</string> <string name="go_to_settings" msgid="3876892339342569259">"ការកំណត់"</string> <string name="install_dict" msgid="180852772562189365">"ដំឡើង"</string> - <string name="cancel_download_dict" msgid="7843340278507019303">"បោះបង់"</string> + <string name="cancel_download_dict" msgid="7843340278507019303">"បោះបង់"</string> <string name="delete_dict" msgid="756853268088330054">"លុប"</string> <string name="should_download_over_metered_prompt" msgid="1583881200688185508">"ភាសាដែលបានជ្រើសនៅលើឧបករណ៍ចល័តមានវចនានុក្រមអាចប្រើបាន។<br/> យើងផ្ដល់អនុសាសន៍ឲ្យ <b>ទាញយក</b> វចនានុក្រមភាសា <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> ដើម្បីបង្កើនបទពិសោធន៍វាយបញ្ចូលរបស់អ្នក។<br/> <br/> ការទាញយកអាចចំណាយពេលប្រហែលពីរនាទីនៅតាម 3G។ ការគិតថ្លៃអាចអនុវត្តប្រសិនបើអ្នកមិនប្រើ <b>ផែនការទិន្នន័យគ្មានដែនកំណត់</b>.<br/> បើអ្នកមិនប្រាកដថាផែនការណាមួយដែលអ្នកមាន យើងផ្ដល់អនុសាសន៍ឲ្យភ្ជាប់វ៉ាយហ្វាយ ដើម្បីចាប់ផ្ដើមទាញយកដោយស្វ័យប្រវត្តិ។<br/> <br/> ជំនួយ៖ អ្នកអាចទាញយក និងលុបវចនានុក្រមដោយចូលទៅ <b>ភាសា & ការបញ្ចូល</b> នៅក្នុងម៉ឺនុយ <b>ការកំណត់</b> សម្រាប់ឧបករណ៍ចល័ត។"</string> <string name="download_over_metered" msgid="1643065851159409546">"ទាញយកឥឡូវនេះ (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> មេកាបៃ)"</string> @@ -179,7 +182,7 @@ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"ពាក្យ៖"</string> <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"ផ្លូវកាត់៖"</string> <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ភាសា៖"</string> - <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"វាយបញ្ចូលពាក្យ"</string> + <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"វាយបញ្ចូលពាក្យ"</string> <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"ផ្លូវកាត់ជាជម្រើស"</string> <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"កែពាក្យ"</string> <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"កែ"</string> diff --git a/java/res/values-kn-rIN/strings.xml b/java/res/values-kn-rIN/strings.xml index 4fcf06f80..4a9bd5257 100644 --- a/java/res/values-kn-rIN/strings.xml +++ b/java/res/values-kn-rIN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"ಸಹಾಯ & ಪ್ರತಿಕ್ರಿಯೆ"</string> <string name="select_language" msgid="3693815588777926848">"ಇನ್ಪುಟ್ ಭಾಷೆಗಳು"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"ಉಳಿಸಲು ಮತ್ತೆ ಸ್ಪರ್ಶಿಸಿ"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"ಉಳಿಸಲು ಇಲ್ಲಿ ಸ್ಪರ್ಶಿಸಿ"</string> <string name="has_dictionary" msgid="6071847973466625007">"ನಿಘಂಟು ಲಭ್ಯವಿದೆ"</string> <string name="keyboard_layout" msgid="8451164783510487501">"ಕೀಬೋರ್ಡ್ ಥೀಮ್"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ಇಂಗ್ಲಿಷ್ (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ಇಂಗ್ಲಿಷ್ (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ಸ್ಪ್ಯಾನಿಷ್ (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ಹಿಂಗ್ಲಿಷ್"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ಇಂಗ್ಲಿಷ್ (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ಇಂಗ್ಲಿಷ್ (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ಸ್ಪ್ಯಾನಿಷ್ (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ಹಿಂಗ್ಲಿಷ್ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ಸಾಂಪ್ರದಾಯಿಕ)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ಸಿರಿಲಿಕ್)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ಲ್ಯಾಟಿನ್)"</string> diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml index 73f8f8606..12ca8019f 100644 --- a/java/res/values-ko/strings.xml +++ b/java/res/values-ko/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"도움말 및 의견"</string> <string name="select_language" msgid="3693815588777926848">"입력 언어"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"저장하려면 다시 터치"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"저장하려면 여기를 터치하세요."</string> <string name="has_dictionary" msgid="6071847973466625007">"사전 사용 가능"</string> <string name="keyboard_layout" msgid="8451164783510487501">"키보드 테마"</string> <string name="subtype_en_GB" msgid="88170601942311355">"영어(영국)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"영어(미국)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"스페인어(미국)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"인도 영어"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"영어(영국)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"영어(미국)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"스페인어(미국)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"인도 영어(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(번체)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(키릴어)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(라틴어)"</string> diff --git a/java/res/values-ky-rKG/strings.xml b/java/res/values-ky-rKG/strings.xml index ad8317db1..6552aff42 100644 --- a/java/res/values-ky-rKG/strings.xml +++ b/java/res/values-ky-rKG/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Жардам & жооп пикир"</string> <string name="select_language" msgid="3693815588777926848">"Киргизүү тилдери"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Сактоо үчүн кайра тийип коюңуз"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Сактоо үчүн бул жерди басыңыз"</string> <string name="has_dictionary" msgid="6071847973466625007">"Сөздүк бар"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Баскычтоп темасы"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Англисче (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Англисче (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Испанча (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хинглиш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Англисче (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Англисче (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Испанча (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Салттык)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Кирилл)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Латын)"</string> diff --git a/java/res/values-lo-rLA/strings.xml b/java/res/values-lo-rLA/strings.xml index eed5380f6..906bd3e39 100644 --- a/java/res/values-lo-rLA/strings.xml +++ b/java/res/values-lo-rLA/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"ຊ່ວຍເຫຼືອ & ຄຳຕິຊົມ"</string> <string name="select_language" msgid="3693815588777926848">"ພາສາການປ້ອນຂໍ້ມູນ"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"ກົດອີກຄັ້ງເພື່ອບັນທຶກ"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"ແຕະບ່ອນນີ້ເພື່ອບັນທຶກ"</string> <string name="has_dictionary" msgid="6071847973466625007">"ມີວັດຈະນານຸກົມ"</string> <string name="keyboard_layout" msgid="8451164783510487501">"ສີສັນແປ້ນພິມ"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ອັງກິດ (ສະຫະລາດຊະອານາຈັກ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ອັງກິດ (ສະຫະລັດຯ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ສະເປນ (ອາເມລິກາ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ຮິງລິສ"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ອັງກິດ (ສະຫະລາດຊະອານາຈັກ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ອັງກິດ (ສະຫະລັດຯ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ສະແປນນິດ (ສະຫະລັດຯ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ຮິງລິສ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ດັ້ງເດີມ)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ຊິຣິວລິກ)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ລາຕິນ)"</string> diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml index c1ef8aa62..0e4b31674 100644 --- a/java/res/values-lt/strings.xml +++ b/java/res/values-lt/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Pagalba ir atsiliepimai"</string> <string name="select_language" msgid="3693815588777926848">"Įvesties kalbos"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Jei norite išsaugoti, palieskite dar kartą"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Palieskite čia, kad išsaugotumėte"</string> <string name="has_dictionary" msgid="6071847973466625007">"Žodynas galimas"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatūros tema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Anglų k. (JK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Anglų k. (JAV)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Ispanų k. (JAV)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindi ir anglų k. derinys"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Anglų (JK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Anglų (JAV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Ispanų (JAV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi ir anglų derinys (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicinė)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kirilica)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (lotynų)"</string> diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml index 58789829f..80dd00c0a 100644 --- a/java/res/values-lv/strings.xml +++ b/java/res/values-lv/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Palīdzība un atsauksmes"</string> <string name="select_language" msgid="3693815588777926848">"Ievades valodas"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Pieskarieties vēlreiz, lai saglabātu."</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Lai saglabātu, pieskarieties šeit"</string> <string name="has_dictionary" msgid="6071847973466625007">"Ir pieejama vārdnīca."</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tastatūras motīvs"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Angļu valoda (Lielbritānija)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Angļu valoda (ASV)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spāņu (ASV)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindi–angļu valoda"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Angļu (Lielbritānija) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Angļu (ASV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spāņu (ASV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi–angļu valoda (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionālā)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kirilica)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latīņu)"</string> diff --git a/java/res/values-mk-rMK/strings.xml b/java/res/values-mk-rMK/strings.xml index 3c6d8725c..7ef9ff391 100644 --- a/java/res/values-mk-rMK/strings.xml +++ b/java/res/values-mk-rMK/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Помош и повратни информации"</string> <string name="select_language" msgid="3693815588777926848">"Влезни јазици"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Допрете повторно за да се зачува"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Допри тука да се зачува"</string> <string name="has_dictionary" msgid="6071847973466625007">"Речникот е достапен"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Тема на тастатурата"</string> <string name="subtype_en_GB" msgid="88170601942311355">"англиски (ОК)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"англиски (САД)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"шпански (САД)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хинглиш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"англиски (ОК) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"англиски (САД) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"шпански (САД) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционален)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (кирилица)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (латиница)"</string> diff --git a/java/res/values-ml-rIN/strings.xml b/java/res/values-ml-rIN/strings.xml index 5826eab2f..b87c0afea 100644 --- a/java/res/values-ml-rIN/strings.xml +++ b/java/res/values-ml-rIN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"സഹായവും ഫീഡ്ബാക്കും"</string> <string name="select_language" msgid="3693815588777926848">"ടൈപ്പുചെയ്യൽ ഭാഷകൾ"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"സംരക്ഷിക്കുന്നതിനായി വീണ്ടും സ്പർശിക്കുക"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"സംരക്ഷിക്കാൻ ഇവിടെ സ്പർശിക്കുക"</string> <string name="has_dictionary" msgid="6071847973466625007">"നിഘണ്ടു ലഭ്യമാണ്"</string> <string name="keyboard_layout" msgid="8451164783510487501">"കീബോർഡ് തീം"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ഇംഗ്ലീഷ് (യുകെ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ഇംഗ്ലീഷ് (യുഎസ്)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"സ്പാനിഷ് (യുഎസ്)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ഹിംഗ്ലീഷ്"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ഇംഗ്ലീഷ് (യുകെ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ഇംഗ്ലീഷ് (യുഎസ്) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"സ്പാനിഷ് (യുഎസ്) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ഹിംഗ്ലീഷ് (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (പരമ്പരാഗതം)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (സിറിലിക്)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ലാറ്റിൻ)"</string> diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml index db04f604a..f922c0eb9 100644 --- a/java/res/values-mn-rMN/strings.xml +++ b/java/res/values-mn-rMN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Тусламж & санал хүсэлт"</string> <string name="select_language" msgid="3693815588777926848">"Оруулах хэл"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Хадгалахын тулд дахин хүрнэ үү"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Хадгалахын тулд хүрнэ үү"</string> <string name="has_dictionary" msgid="6071847973466625007">"Толь бичиг байна"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Гарын загвар"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Англи (ИБ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Англи (АНУ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Испани (АНУ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хинглиш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Англи (ИБ) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Англи (АНУ) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Испани (АНУ-ын) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (уламжлалт)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Кирилл)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Латин)"</string> diff --git a/java/res/values-mr-rIN/strings.xml b/java/res/values-mr-rIN/strings.xml index 677438c73..c950e285e 100644 --- a/java/res/values-mr-rIN/strings.xml +++ b/java/res/values-mr-rIN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"मदत आणि अभिप्राय"</string> <string name="select_language" msgid="3693815588777926848">"इनपुट भाषा"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"जतन करण्यासाठी पुन्हा स्पर्श करा"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"जतन करण्यासाठी येथे स्पर्श करा"</string> <string name="has_dictionary" msgid="6071847973466625007">"शब्दकोश उपलब्ध"</string> <string name="keyboard_layout" msgid="8451164783510487501">"कीबोर्ड थीम"</string> <string name="subtype_en_GB" msgid="88170601942311355">"इंग्रजी (यूके)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"इंग्रजी (यूएस)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"स्पॅनिश (यूएस)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"हिंग्लिश"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"इंग्रजी (यूके) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"इंग्रजी (यूएस) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"स्पॅनिश (यूएस) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"हिंग्लिश (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (पारंपारिक)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (सिरिलिक)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (लॅटिन)"</string> diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml index 758ff10b3..a07e77d71 100644 --- a/java/res/values-ms-rMY/strings.xml +++ b/java/res/values-ms-rMY/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Bantuan & m/balas"</string> <string name="select_language" msgid="3693815588777926848">"Bahasa input"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Sentuh lagi untuk menyimpan"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Sentuh di sini untuk menyimpan"</string> <string name="has_dictionary" msgid="6071847973466625007">"Kamus tersedia"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema papan kekunci"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Bahasa Inggeris (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Bahasa Inggeris (Australia)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Bahasa Sepanyol (AS)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Bahasa Inggeris (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Bahasa Inggeris (AS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Bahasa Sepanyol (AS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cyril)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latin)"</string> diff --git a/java/res/values-my-rMM/strings.xml b/java/res/values-my-rMM/strings.xml index 6862124c3..f07d88791 100644 --- a/java/res/values-my-rMM/strings.xml +++ b/java/res/values-my-rMM/strings.xml @@ -31,7 +31,7 @@ <string name="settings_screen_multi_lingual" msgid="6829970893413937235">"ဘာသာများစွာ ရွေးချယ်မှု"</string> <string name="settings_screen_gesture" msgid="9113437621722871665">"အမူယာစာရိုက်ခြင်း စိတ်ကြိုက်များ"</string> <string name="settings_screen_correction" msgid="1616818407747682955">"စာအမှားပြပြင်ခြင်း"</string> - <string name="settings_screen_advanced" msgid="7472408607625972994">"အဆင့်မြင့်"</string> + <string name="settings_screen_advanced" msgid="7472408607625972994">"အဆင့်မြင့်"</string> <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"အခြားထည့်သွင်းမည့် နည်းလမ်းများသို့ ပြောင်းရန်"</string> <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"ဘာသာပြောင်းသည့် ကီးသည် အခြားထည့်သွင်းရန် နည်းလမ်းများလည်း ပါဝင်သည်"</string> <string name="show_language_switch_key" msgid="5915478828318774384">"ဘာသာစကား ပြောင်းခလုတ်"</string> @@ -46,7 +46,7 @@ <string name="use_contacts_dict" msgid="4435317977804180815">"အဆယ်ကသွယ်အမည်များ အကြံပြုမည်"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"အကြံပြုချက်များနှင့် အမှားပြင်ခြင်းများအတွက် အဆက်သွယ်မှ အမည်များ အသုံးပြုမည်"</string> <string name="use_personalized_dicts" msgid="5167396352105467626">"ကိုယ်ရေးကိုယ်တာ အကြံပြုချက်များ"</string> - <string name="enable_metrics_logging" msgid="5506372337118822837">"မြှင့်တင်ပါ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="enable_metrics_logging" msgid="5506372337118822837">"မြှင့်တင်ပါ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="use_double_space_period" msgid="8781529969425082860">"နှစ်နေရာခြား အဆုံးသတ်"</string> <string name="use_double_space_period_summary" msgid="6532892187247952799">"အချိန်ကာလ"</string> <string name="auto_cap" msgid="1719746674854628252">"အော်တိုစာလုံးကြီးပြောင်း"</string> @@ -76,18 +76,21 @@ <string name="voice_input" msgid="3583258583521397548">"အသံထည့်သွင်းရန် ခလုတ်"</string> <string name="voice_input_disabled_summary" msgid="8141750303464726129">"မည်သည့် Check Language & input settings."</string> <string name="configure_input_method" msgid="373356270290742459">"ထည့်သွင်းရန် နည်းလမ်းကို ပြုပြင်မည်"</string> - <string name="language_selection_title" msgid="1651299598555326750">"ထည့်သွင်းမှု ဘာသာ"</string> + <string name="language_selection_title" msgid="1651299598555326750">"ထည့်သွင်းမှု ဘာသာ"</string> <string name="help_and_feedback" msgid="5328219371839879161">"အကူအညီ & တုံ့ပြန်ချက်"</string> - <string name="select_language" msgid="3693815588777926848">"ထည့်သွင်းမှု ဘာသာ"</string> + <string name="select_language" msgid="3693815588777926848">"ထည့်သွင်းမှု ဘာသာ"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"သိမ်းရန် နောက်တစ်ကြိမ်နှိပ်ပါ"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"သိမ်းရန် ဤနေရာကို ထိပါ"</string> <string name="has_dictionary" msgid="6071847973466625007">"အဘိဓါန်ရနိုင်"</string> <string name="keyboard_layout" msgid="8451164783510487501">"ကီးဘုတ်အရောင်"</string> <string name="subtype_en_GB" msgid="88170601942311355">"အင်္ဂလိပ်(ယူကေ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"အင်္ဂလိပ် (ယူအက်စ်)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"စပိန် (ယူအက်စ်)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ဟင်ဂလိပ်"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"အင်္ဂလိပ် (ယူကေ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"အင်္ဂလိပ် (ယူအက်စ်) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"စပိန် (ယူအက်စ်) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ဟင်ဂလိပ် (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ရိုးရာ)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ဗျည်းအက္ခရာ)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (လက်တင်)"</string> @@ -149,7 +152,7 @@ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"သုံးစွဲသူ၏ အဘိဓာန်"</string> <string name="dictionary_available" msgid="4728975345815214218">"အဘိဓါန်ရရှိနိုင်"</string> <string name="dictionary_downloading" msgid="2982650524622620983">"လက်ရှိ ဒေါင်းလုပ်လုပ်နေသည်"</string> - <string name="dictionary_installed" msgid="8081558343559342962">"ထည့်သွင်းပြီး"</string> + <string name="dictionary_installed" msgid="8081558343559342962">"ထည့်သွင်းပြီး"</string> <string name="dictionary_disabled" msgid="8950383219564621762">"ထည့်သွင်းထားပြီး၊ ပိတ်ထားသည်"</string> <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"အဘိဓါန်ဝန်ဆောင်မှုသို့ ချိတ်ဆက်ရန် ပြဿနာရှိနေသည်"</string> <string name="no_dictionaries_available" msgid="8039920716566132611">"အဘိဓါန်မရှိ"</string> @@ -163,7 +166,7 @@ <string name="install_dict" msgid="180852772562189365">"တပ်ဆင်ပါ"</string> <string name="cancel_download_dict" msgid="7843340278507019303">"ပယ်ဖျက်ရန်"</string> <string name="delete_dict" msgid="756853268088330054">"ဖျက်ရန်"</string> - <string name="should_download_over_metered_prompt" msgid="1583881200688185508">"သင့်ဖုန်းရှိ ရွေးချယ်ထားသည့် ဘာသာအတွက် အဘိဓါန်ရှိပါသည်။ <br/> အဘိဓါန်အား <b>ဒေါင်းလုပ်လုပ်ကာ</b> the <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> သင့်စာရိုက် အတွေ့အကြုံတိုးတက်စေရန် ကျွန်ုပ်တို့အကြံပြုပါသည်။ <br/> <br/> ဒေါင်းလုပ်လုပ်ရန် 3G ပေါ်တွင် ၁ မှ ၂ မိနစ်ခန့်ကြာနိုင်သည်။ သင့်တွင် <b>အကန့်သတ်မှရိ အချက်လက် သုံးစွဲမှု</b>မရှိလျှင် ငွေကျသင့်နိုင်ပါသည်။ <br/> သင့်တွင် မည်သည့်အချက်လက်သုံးစွဲမှု ရှိနေသည်ကိုမသိလျှင်၊ အလိုအလျောက် ဒေါင်းလုပ်လုပ်ရန် Wi-Fi ကွန်ရက်တစ်ခု ရှာဖွေရန် တိုက်တွန်းပါသည်။ <br/> <br/> နည်းလမ်း: သင့်ဖုန်းကိရိယာရှိ <b>ဆက်တင်ထဲတွင်</b> <b>ဘာသာ & ထည့်သွင်းမှု</b> သို့သွားကာ အဘိဓါန်များကို ဒေါင်းလုပ်လုပ်နိုင် ဖယ်ရှားနိုင်ပါသည်။"</string> + <string name="should_download_over_metered_prompt" msgid="1583881200688185508">"သင့်ဖုန်းရှိ ရွေးချယ်ထားသည့် ဘာသာအတွက် အဘိဓါန်ရှိပါသည်။ <br/> အဘိဓါန်အား <b>ဒေါင်းလုပ်လုပ်ကာ</b> the <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> သင့်စာရိုက် အတွေ့အကြုံတိုးတက်စေရန် ကျွန်ုပ်တို့အကြံပြုပါသည်။ <br/> <br/> ဒေါင်းလုပ်လုပ်ရန် 3G ပေါ်တွင် ၁ မှ ၂ မိနစ်ခန့်ကြာနိုင်သည်။ သင့်တွင် <b>အကန့်သတ်မှရိ အချက်လက် သုံးစွဲမှု</b>မရှိလျှင် ငွေကျသင့်နိုင်ပါသည်။ <br/> သင့်တွင် မည်သည့်အချက်လက်သုံးစွဲမှု ရှိနေသည်ကိုမသိလျှင်၊ အလိုအလျောက် ဒေါင်းလုပ်လုပ်ရန် Wi-Fi ကွန်ရက်တစ်ခု ရှာဖွေရန် တိုက်တွန်းပါသည်။ <br/> <br/> နည်းလမ်း: သင့်ဖုန်းကိရိယာရှိ <b>ဆက်တင်ထဲတွင်</b> <b>ဘာသာ & ထည့်သွင်းမှု</b> သို့သွားကာ အဘိဓါန်များကို ဒေါင်းလုပ်လုပ်နိုင် ဖယ်ရှားနိုင်ပါသည်။"</string> <string name="download_over_metered" msgid="1643065851159409546">"ယခုဒေါင်းလုပ်လုပ်မည် (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string> <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi အသုံးပြု၍ ဒေါင်းလုပ်လုပ်ရန်"</string> <string name="dict_available_notification_title" msgid="4583842811218581658">"<xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> အတွက် အဘိဓါန် ရနိုင်ပါသည်"</string> @@ -184,7 +187,7 @@ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"စာလုံးကို ပြင်ဆင်မည်"</string> <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"တည်းဖြတ်ရန်"</string> <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"ဖျက်ရန်"</string> - <string name="user_dict_settings_empty_text" msgid="558499587532668203">"သင့်အဘိဓာန်ထဲတွင် မည်သည့်စာလုံးမှမရှိပါ။ ထပ်ထည့်ခြင်း(+)ခလုတ်ကို ထိ၍ စာလုံးထည့်ပါ။"</string> + <string name="user_dict_settings_empty_text" msgid="558499587532668203">"သင့်အဘိဓာန်ထဲတွင် မည်သည့်စာလုံးမှမရှိပါ။ ထပ်ထည့်ခြင်း(+)ခလုတ်ကို ထိ၍ စာလုံးထည့်ပါ။"</string> <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"ဘာသာစကားအားလုံးအတွက်"</string> <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"ဘာသာစကားပိုများများ…"</string> <string name="user_dict_settings_delete" msgid="110413335187193859">"ဖျက်သိမ်းရန်"</string> diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml index e4507172e..fcc5c9770 100644 --- a/java/res/values-nb/strings.xml +++ b/java/res/values-nb/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Hjelp og tilbakemelding"</string> <string name="select_language" msgid="3693815588777926848">"Inndataspråk"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Trykk på nytt for å lagre"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Trykk her for å lagre"</string> <string name="has_dictionary" msgid="6071847973466625007">"Ordbok tilgjengelig"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Engelsk (Storbritannia)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Engelsk (USA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spansk (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelsk (Storbritannia) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelsk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spansk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradisjonelt)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kyrillisk)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latin)"</string> diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml index 926ae137d..c7c95aeb2 100644 --- a/java/res/values-ne-rNP/strings.xml +++ b/java/res/values-ne-rNP/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"मद्दत र प्रतिक्रिया"</string> <string name="select_language" msgid="3693815588777926848">"इनपुट भाषाहरू"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"बचत गर्न पुनः छुनुहोस्"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"बचत गर्न यहाँ छुनुहोस्"</string> <string name="has_dictionary" msgid="6071847973466625007">"उपलब्ध शब्दकोश"</string> <string name="keyboard_layout" msgid="8451164783510487501">"किबोर्ड थिम"</string> <string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेजी (युके)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेजी (युएस्)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"स्पेनिस (युएस्)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"हिङ्लिस"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"अंग्रेजी (बेलायत) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"अंग्रेजी (अमेरिका) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"स्पेनेली (अमेरिका) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"हिङ्लिस (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (परम्परागत)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (सिरिलिक)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ल्याटिन)"</string> diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml index aa4aca80d..8ee5e4b33 100644 --- a/java/res/values-nl/strings.xml +++ b/java/res/values-nl/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Help en feedback"</string> <string name="select_language" msgid="3693815588777926848">"Invoertalen"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Tik nogmaals om op te slaan"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Tik hier om op te slaan"</string> <string name="has_dictionary" msgid="6071847973466625007">"Woordenboek beschikbaar"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Toetsenbordthema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Engels (GB)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Engels (VS)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spaans (VS)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindi-Engels"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engels (VK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engels (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaans (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi-Engels (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditioneel)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cyrillisch)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latijns)"</string> diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml index 2c709adce..70fb091be 100644 --- a/java/res/values-pl/strings.xml +++ b/java/res/values-pl/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Pomoc i opinie"</string> <string name="select_language" msgid="3693815588777926848">"Języki wprowadzania"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Dotknij ponownie, aby zapisać"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Kliknij tutaj, by zapisać"</string> <string name="has_dictionary" msgid="6071847973466625007">"Słownik dostępny"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Motyw klawiatury"</string> <string name="subtype_en_GB" msgid="88170601942311355">"angielski (Wielka Brytania)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"angielski (Stany Zjednoczone)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"hiszpański (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Angielski (Wielka Brytania) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Angielski (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Hiszpański (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradycyjny)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cyrylica)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (alfabet łaciński)"</string> diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml index 9bd407eac..9c3bc4c1e 100644 --- a/java/res/values-pt-rPT/strings.xml +++ b/java/res/values-pt-rPT/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ajuda e comentários"</string> <string name="select_language" msgid="3693815588777926848">"Idiomas de introdução"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para guardar"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Toque aqui para guardar"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglês (RU)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Inglês (EUA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Espanhol (EUA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglês (RU) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglês (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Espanhol (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cirílico)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latim)"</string> diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml index 4faee4b5a..7bc858193 100644 --- a/java/res/values-pt/strings.xml +++ b/java/res/values-pt/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ajuda e feedback"</string> <string name="select_language" msgid="3693815588777926848">"Idiomas de entrada"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para salvar"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Toque aqui para salvar"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"inglês (Reino Unido)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"inglês (EUA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"espanhol (EUA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Híndi-inglês"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglês (Reino Unido) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglês (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Espanhol (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Híndi-inglês (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cirílico)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latino)"</string> diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml index 412ec0e27..8af7b2f50 100644 --- a/java/res/values-ro/strings.xml +++ b/java/res/values-ro/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Ajutor și feedback"</string> <string name="select_language" msgid="3693815588777926848">"Limbi de introducere de text"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Atingeţi din nou pentru a salva"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Atingeți aici pentru a salva"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dicţionar disponibil"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Temă pentru tastatură"</string> <string name="subtype_en_GB" msgid="88170601942311355">"engleză (Regatul Unit)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"engleză (S.U.A.)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"spaniolă (S.U.A.)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engleză (Regatul Unit) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engleză (S.U.A.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaniolă (S.U.A.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradițională)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Chirilică)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latină)"</string> diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml index eada31354..15843ea56 100644 --- a/java/res/values-ru/strings.xml +++ b/java/res/values-ru/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Справка/отзыв"</string> <string name="select_language" msgid="3693815588777926848">"Языки ввода"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Нажмите, чтобы сохранить"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Нажмите, чтобы сохранить"</string> <string name="has_dictionary" msgid="6071847973466625007">"Доступен словарь"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Тема клавиатуры"</string> <string name="subtype_en_GB" msgid="88170601942311355">"английский (Великобритания)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"английский (США)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Испанский (США)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хинглиш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Английский (Великобритания, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Английский (США, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Испанский (США, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (классическая)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (кириллица)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (латиница)"</string> diff --git a/java/res/values-si-rLK/strings.xml b/java/res/values-si-rLK/strings.xml index 4829988a5..7c1ebcbf2 100644 --- a/java/res/values-si-rLK/strings.xml +++ b/java/res/values-si-rLK/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"උදවු සහ ප්රතිපෝෂණ"</string> <string name="select_language" msgid="3693815588777926848">"ආදාන භාෂා"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"සුරැකීමට නැවත ස්පර්ශ කරන්න"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"සුරැකීමට මෙතැන ස්පර්ෂ කරන්න"</string> <string name="has_dictionary" msgid="6071847973466625007">"ශබ්ද කෝෂය ලබාගත හැක"</string> <string name="keyboard_layout" msgid="8451164783510487501">"යතුරු පුවරු තේමාව"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ඉංග්රීසි (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ඉංග්රීසි (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ස්පාඤ්ඤ (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"හින්ග්ලිෂ්"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ඉංග්රීසි (එ.රා) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ඉංග්රීසි (එ.ජ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ස්පාඤ්ඤ (එ.ජ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"හින්ග්ලිෂ් (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (සාම්ප්රදායික)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (සිරිලික්)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ලතින්)"</string> diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml index 107f3794a..02e7c97c5 100644 --- a/java/res/values-sk/strings.xml +++ b/java/res/values-sk/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Pomocník a spätná väzba"</string> <string name="select_language" msgid="3693815588777926848">"Jazyky vstupu"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Opätovným dotykom uložíte"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Klepnutím tu uložíte"</string> <string name="has_dictionary" msgid="6071847973466625007">"K dispozícii je slovník"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Motív klávesnice"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Anglická klávesnica (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Anglická klávesnica (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"španielčina (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angličtina (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angličtina (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španielčina (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradičná)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cyrilika)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latinka)"</string> diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml index db24507eb..237414725 100644 --- a/java/res/values-sl/strings.xml +++ b/java/res/values-sl/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Pomoč in povratne informacije"</string> <string name="select_language" msgid="3693815588777926848">"Jeziki vnosa"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Dotaknite se še enkrat, da shranite"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Če želite shraniti, se dotaknite tukaj"</string> <string name="has_dictionary" msgid="6071847973466625007">"Slovar je na voljo"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string> <string name="subtype_en_GB" msgid="88170601942311355">"angleščina (Združeno kraljestvo)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"angleščina (ZDA)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"španščina (ZDA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindujska angleščina"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angleščina (VB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angleščina (ZDA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španščina (ZDA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindujska angleščina (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalna)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cirilica)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latinica)"</string> diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml index 8cef0d0d9..c217775f0 100644 --- a/java/res/values-sr/strings.xml +++ b/java/res/values-sr/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Помоћ и повратне информације"</string> <string name="select_language" msgid="3693815588777926848">"Језици уноса"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Поново додирните да бисте сачували"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Додирните овде да бисте сачували"</string> <string name="has_dictionary" msgid="6071847973466625007">"Речник је доступан"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Тема тастатуре"</string> <string name="subtype_en_GB" msgid="88170601942311355">"енглески (УК)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"енглески (САД)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"шпански (САД)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"хенглески"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"енглески (УК) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"енглески (САД) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"шпански (САД) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"хенглески (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционални)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ћирилица)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (латиница)"</string> diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml index c5782cd45..30a390bcb 100644 --- a/java/res/values-sv/strings.xml +++ b/java/res/values-sv/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Hjälp och feedback"</string> <string name="select_language" msgid="3693815588777926848">"Inmatningsspråk"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Spara genom att trycka igen"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Tryck här om du vill spara"</string> <string name="has_dictionary" msgid="6071847973466625007">"En ordlista är tillgänglig"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tangentbordstema"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Engelskt (brittiskt)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Engelskt (amerikanskt)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"spanska (USA)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hindi/engelska"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelska (Storbritannien) <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelska (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanska (USA (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi/engelska (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionell)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kyrillisk)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (latinsk)"</string> diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml index f5b8dcbbb..6060d0873 100644 --- a/java/res/values-sw/strings.xml +++ b/java/res/values-sw/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Usaidizi na maoni"</string> <string name="select_language" msgid="3693815588777926848">"Lugha zinazoruhusiwa"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Gusa tena ili kuhifadhi"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Gusa hapa ili uhifadhi"</string> <string name="has_dictionary" msgid="6071847973466625007">"Kamusi inapatikana"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Maandhari ya kibodi"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Kiingereza cha (Uingereza)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Kiingereza cha (Marekani)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Kihispania (Marekani)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Kiingereza (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Kiingereza (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Kihispania (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cha Jadi)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kikriliki)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kilatini)"</string> diff --git a/java/res/values-ta-rIN/strings.xml b/java/res/values-ta-rIN/strings.xml index 606a25524..475a1efc3 100644 --- a/java/res/values-ta-rIN/strings.xml +++ b/java/res/values-ta-rIN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"உதவி & கருத்து"</string> <string name="select_language" msgid="3693815588777926848">"உள்ளீட்டு மொழிகள்"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"சேமிக்க தொடவும்"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"சேமிக்க இங்கு தொடவும்"</string> <string name="has_dictionary" msgid="6071847973466625007">"அகராதி உள்ளது"</string> <string name="keyboard_layout" msgid="8451164783510487501">"விசைப்பலகை தீம்"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ஆங்கிலம் (யூகே)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ஆங்கிலம் (யூஎஸ்)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ஸ்பானிஷ் (யூஎஸ்)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ஹிங்கிலிஷ்"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ஆங்கிலம் (யூகே) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ஆங்கிலம் (யூஎஸ்) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ஸ்பானிஷ் (யூஎஸ்) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ஹிங்கிலிஷ் (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (பாரம்பரியமானது)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (சிரிலிக்)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (இலத்தீன்)"</string> diff --git a/java/res/values-te-rIN/strings.xml b/java/res/values-te-rIN/strings.xml index 75152db15..2b961c042 100644 --- a/java/res/values-te-rIN/strings.xml +++ b/java/res/values-te-rIN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"సహాయం & అభిప్రాయం"</string> <string name="select_language" msgid="3693815588777926848">"ఇన్పుట్ భాషలు"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"సేవ్ చేయడానికి మళ్లీ తాకండి"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"సేవ్ చేయడానికి ఇక్కడ తాకండి"</string> <string name="has_dictionary" msgid="6071847973466625007">"నిఘంటువు అందుబాటులో ఉంది"</string> <string name="keyboard_layout" msgid="8451164783510487501">"కీబోర్డ్ థీమ్"</string> <string name="subtype_en_GB" msgid="88170601942311355">"ఆంగ్లం (యుకె)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"ఆంగ్లం (యుఎస్)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"స్పానిష్ (యుఎస్)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"హింగ్లీష్"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ఆంగ్లం (యుకె) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ఆంగ్లం (యుఎస్) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"స్పానిష్ (యుఎస్) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"హింగ్లీష్ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (సాంప్రదాయకం)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (సిరిలిక్)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (లాటిన్)"</string> diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml index f69c63cce..9f4d9b6c0 100644 --- a/java/res/values-th/strings.xml +++ b/java/res/values-th/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"ความช่วยเหลือและความคิดเห็น"</string> <string name="select_language" msgid="3693815588777926848">"ภาษาสำหรับการป้อนข้อมูล"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"แตะอีกครั้งเพื่อบันทึก"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"แตะที่นี่เพื่อบันทึก"</string> <string name="has_dictionary" msgid="6071847973466625007">"มีพจนานุกรมให้ใช้งาน"</string> <string name="keyboard_layout" msgid="8451164783510487501">"ชุดรูปแบบแป้นพิมพ์"</string> <string name="subtype_en_GB" msgid="88170601942311355">"อังกฤษ (สหราชอาณาจักร)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"อังกฤษ (อเมริกัน)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"สเปน (สหรัฐอเมริกา)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ภาษาอังกฤษผสมกับฮินดู"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"อังกฤษ (สหราชอาณาจักร) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"อังกฤษ (สหรัฐอเมริกา) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"สเปน (สหรัฐอเมริกา) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ภาษาอังกฤษผสมกับฮินดู (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ดั้งเดิม)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ซีริลลิก)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ละติน)"</string> diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml index e22845a3d..dd9332d59 100644 --- a/java/res/values-tl/strings.xml +++ b/java/res/values-tl/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Tulong at feedback"</string> <string name="select_language" msgid="3693815588777926848">"Mga wika ng input"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Pinduting muli upang i-save"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Pumindot dito upang mag-save"</string> <string name="has_dictionary" msgid="6071847973466625007">"Available ang diksyunaryo"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema ng keyboard"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Ingles (UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Ingles (Estados Unidos)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Spanish (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Ingles (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Ingles (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Cyrillic)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latin)"</string> diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml index 38ad5691e..09f5409ef 100644 --- a/java/res/values-tr/strings.xml +++ b/java/res/values-tr/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Yardım ve geri bildirim"</string> <string name="select_language" msgid="3693815588777926848">"Giriş dilleri"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Kaydetmek için tekrar dokunun"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Kaydetmek için buraya dokunun"</string> <string name="has_dictionary" msgid="6071847973466625007">"Sözlük kullanılabilir"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Klavye teması"</string> <string name="subtype_en_GB" msgid="88170601942311355">"İngilizce (BK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"İngilizce (ABD)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"İspanyolca (ABD)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hingilizce"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"İngilizce (İngiltere) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"İngilizce (ABD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"İspanyolca (ABD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hingilizce (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Geleneksel)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kiril)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Latin)"</string> diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml index f0048aefe..762dd227a 100644 --- a/java/res/values-uk/strings.xml +++ b/java/res/values-uk/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Довідка й відгуки"</string> <string name="select_language" msgid="3693815588777926848">"Мови введення"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Торкніться знову, щоб зберегти"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Торкніться тут, щоб зберегти"</string> <string name="has_dictionary" msgid="6071847973466625007">"Словник доступний"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Тема клавіатури"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Англійська (Великобританія)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Англійська (США)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"іспанська (США)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Хінґліш"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Англійська (Британія) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Англійська (США) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Іспанська (США) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хінґліш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиційна)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (кирилиця)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (латиниця)"</string> diff --git a/java/res/values-ur-rPK/strings.xml b/java/res/values-ur-rPK/strings.xml index b1ad5fa0f..28eebd2cd 100644 --- a/java/res/values-ur-rPK/strings.xml +++ b/java/res/values-ur-rPK/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"مدد اور تاثرات"</string> <string name="select_language" msgid="3693815588777926848">"ان پٹ زبانیں"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"محفوظ کرنے کیلئے دوبارہ ٹچ کریں"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"محفوظ کرنے کیلئے یہاں ٹچ کریں"</string> <string name="has_dictionary" msgid="6071847973466625007">"لغت دستیاب ہے"</string> <string name="keyboard_layout" msgid="8451164783510487501">"کی بورڈ تھیم"</string> <string name="subtype_en_GB" msgid="88170601942311355">"انگریزی (برطانیہ)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"انگریزی (امریکہ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"ہسپانوی (امریکہ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"ہنگلش"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"انگریزی (برطانیہ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"انگریزی (امریکہ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ہسپانوی (امریکہ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ہنگلش (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (روایتی)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (سیریلک)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (لاطینی)"</string> diff --git a/java/res/values-uz-rUZ/strings.xml b/java/res/values-uz-rUZ/strings.xml index 41321e753..eb7d63080 100644 --- a/java/res/values-uz-rUZ/strings.xml +++ b/java/res/values-uz-rUZ/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Yordam va fikr-mulohaza"</string> <string name="select_language" msgid="3693815588777926848">"Matn kiritish tillari"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Saqlash uchun yana bosing"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Saqlash uchun bu yerga bosing"</string> <string name="has_dictionary" msgid="6071847973466625007">"Lug‘at mavjud"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatura mavzusi"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Ingliz (Buyuk Britaniya)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Ingliz (AQSH)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Ispan (AQSH)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Ingliz (Buyuk Britaniya) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Ingliz (AQSH) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Ispan (AQSH) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (an’anaviy)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kirill)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (lotin)"</string> diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml index 30c8d9dbf..a0057e624 100644 --- a/java/res/values-vi/strings.xml +++ b/java/res/values-vi/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Trợ giúp và phản hồi"</string> <string name="select_language" msgid="3693815588777926848">"Ngôn ngữ nhập"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Chạm lại để lưu"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Chạm vào đây để lưu"</string> <string name="has_dictionary" msgid="6071847973466625007">"Có sẵn từ điển"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Chủ đề bàn phím"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Tiếng Anh (Anh)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"Tiếng Anh (Mỹ)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"Tiếng Tây Ban Nha (Mỹ)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Tiếng Anh-Hindi"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Tiếng Anh (Anh) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Tiếng Anh (Mỹ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Tiếng Tây Ban Nha (Mỹ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Tiếng Anh-Hindi (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Truyền thống)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tiếng Kirin)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tiếng Latin)"</string> diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml index 0dfb9f989..0986a8eae 100644 --- a/java/res/values-zh-rCN/strings.xml +++ b/java/res/values-zh-rCN/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"帮助和反馈"</string> <string name="select_language" msgid="3693815588777926848">"输入语言"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"再次触摸即可保存"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"触摸此处即可保存"</string> <string name="has_dictionary" msgid="6071847973466625007">"有可用字典"</string> <string name="keyboard_layout" msgid="8451164783510487501">"键盘主题"</string> <string name="subtype_en_GB" msgid="88170601942311355">"英语(英国)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"英语(美国)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"西班牙语(美国)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"印地英语"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英式英语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"美式英语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"美式西班牙语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"印地英语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(传统)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(西里尔文)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(拉丁文)"</string> diff --git a/java/res/values-zh-rHK/strings.xml b/java/res/values-zh-rHK/strings.xml index 791074c6e..cd744d6f8 100644 --- a/java/res/values-zh-rHK/strings.xml +++ b/java/res/values-zh-rHK/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"說明與意見反映"</string> <string name="select_language" msgid="3693815588777926848">"輸入語言"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"再次輕觸即可儲存"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"輕觸即可儲存"</string> <string name="has_dictionary" msgid="6071847973466625007">"可使用字典"</string> <string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string> <string name="subtype_en_GB" msgid="88170601942311355">"英文 (英國)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"英文 (美國)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"西班牙文 (美國)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"印度英文"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英文 (英國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"西班牙文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"印度英文 (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (西里爾文)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (拉丁文)"</string> diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml index 97a00525b..726c6975e 100644 --- a/java/res/values-zh-rTW/strings.xml +++ b/java/res/values-zh-rTW/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"說明與意見回饋"</string> <string name="select_language" msgid="3693815588777926848">"輸入語言"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"再次輕觸即可儲存"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"輕觸這裡即可儲存"</string> <string name="has_dictionary" msgid="6071847973466625007">"可用的字典"</string> <string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string> <string name="subtype_en_GB" msgid="88170601942311355">"英文 (英國)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"英文 (美國)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"西班牙文 (美國)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"印度英文"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英文 (英國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"西班牙文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"印度英文 (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (斯拉夫文)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (拉丁文)"</string> diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml index 689d501f0..1ad0f1e52 100644 --- a/java/res/values-zu/strings.xml +++ b/java/res/values-zu/strings.xml @@ -80,14 +80,17 @@ <string name="help_and_feedback" msgid="5328219371839879161">"Usizo nempendulo"</string> <string name="select_language" msgid="3693815588777926848">"Izilimi zokufakwayo"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Thinta futhi ukuze ulondoloze"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Thinta lapha ukuze ulondoloze"</string> <string name="has_dictionary" msgid="6071847973466625007">"Isichazamazwi siyatholakala"</string> <string name="keyboard_layout" msgid="8451164783510487501">"Indikimba yekhibhodi"</string> <string name="subtype_en_GB" msgid="88170601942311355">"i-English(UK)"</string> <string name="subtype_en_US" msgid="6160452336634534239">"i-English (US)"</string> <string name="subtype_es_US" msgid="5583145191430180200">"I-Spanish (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"I-Hinglish"</string> <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"I-English (UK) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string> <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"I-English (US) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string> <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Isi-Spanish (US) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"I-Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> <string name="subtype_generic_traditional" msgid="8584594350973800586">"Isi-<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradition)"</string> <string name="subtype_generic_cyrillic" msgid="7486451947618138947">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Isi-Cyrillic)"</string> <string name="subtype_generic_latin" msgid="9128716486310604145">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Isi-Latin)"</string> diff --git a/java/res/values/donottranslate-text-decorator.xml b/java/res/values/donottranslate-text-decorator.xml new file mode 100644 index 000000000..9c39a4689 --- /dev/null +++ b/java/res/values/donottranslate-text-decorator.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<resources> + <!-- The delay time in milliseconds from to show the commit indicator --> + <integer name="text_decorator_delay_in_milliseconds_to_show_commit_indicator"> + 500 + </integer> + + <!-- The extra margin in dp around the hit area of the commit/add-to-dictionary indicator --> + <integer name="text_decorator_hit_area_margin_in_dp"> + 4 + </integer> + + <!-- If true, the commit/add-to-text indicator will be suppressed when the word isn't going to + trigger auto-correction. --> + <bool name="text_decorator_only_for_auto_correction">false</bool> + + <!-- If true, the commit/add-to-text indicator will be suppressed when the word is already in + the dictionary. --> + <bool name="text_decorator_only_for_out_of_vocabulary">false</bool> + + <!-- Background color to be used to highlight the target text when the commit indicator is + visible. --> + <color name="text_decorator_commit_indicator_text_highlight_color"> + #B6E2DE + </color> + + <!-- Background color of the commit indicator. --> + <color name="text_decorator_commit_indicator_background_color"> + #48B6AC + </color> + + <!-- Foreground color of the commit indicator. --> + <color name="text_decorator_commit_indicator_foreground_color"> + #FFFFFF + </color> + + <!-- Viewport size of "text_decorator_commit_indicator_path". --> + <integer name="text_decorator_commit_indicator_path_size"> + 480 + </integer> + + <!-- Coordinates of the closed path to be used to render the commit indicator. + The format is: X[0], Y[0], X[1], Y[1], ..., X[N-1], Y[N-1] --> + <integer-array name="text_decorator_commit_indicator_path"> + <item>180</item> + <item>323</item> + <item>97</item> + <item>240</item> + <item>68</item> + <item>268</item> + <item>180</item> + <item>380</item> + <item>420</item> + <item>140</item> + <item>392</item> + <item>112</item> + </integer-array> + + <!-- Background color to be used to highlight the target text when the add-to-dictionary + indicator is visible. --> + <color name="text_decorator_add_to_dictionary_indicator_text_highlight_color"> + #D1E7B7 + </color> + + <!-- Foreground color of the commit indicator. --> + <color name="text_decorator_add_to_dictionary_indicator_background_color"> + #4EB848 + </color> + + <!-- Foreground color of the add-to-dictionary indicator. --> + <color name="text_decorator_add_to_dictionary_indicator_foreground_color"> + #FFFFFF + </color> + + <!-- Viewport size of "text_decorator_add_to_dictionary_indicator_path". --> + <integer name="text_decorator_add_to_dictionary_indicator_path_size"> + 480 + </integer> + + <!-- Coordinates of the closed path to be used to render the add-to-dictionary indicator. + The format is: X[0], Y[0], X[1], Y[1], ..., X[N-1], Y[N-1] --> + <integer-array name="text_decorator_add_to_dictionary_indicator_path"> + <item>380</item> + <item>260</item> + <item>260</item> + <item>260</item> + <item>260</item> + <item>380</item> + <item>220</item> + <item>380</item> + <item>220</item> + <item>260</item> + <item>100</item> + <item>260</item> + <item>100</item> + <item>220</item> + <item>220</item> + <item>220</item> + <item>220</item> + <item>100</item> + <item>260</item> + <item>100</item> + <item>260</item> + <item>220</item> + <item>380</item> + <item>220</item> + </integer-array> +</resources> diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 1d9dedbb4..30bd1dfda 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -360,7 +360,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { R.layout.input_view, null); mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame); mEmojiPalettesView = (EmojiPalettesView)mCurrentInputView.findViewById( - R.id.emoji_keyboard_view); + R.id.emoji_palettes_view); mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled); diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java new file mode 100644 index 000000000..178516134 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/TextDecorator.java @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard; + +import android.graphics.Matrix; +import android.graphics.PointF; +import android.graphics.RectF; +import android.inputmethodservice.InputMethodService; +import android.os.Message; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.view.inputmethod.CursorAnchorInfo; + +import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; + +import javax.annotation.Nonnull; + +/** + * A controller class of commit/add-to-dictionary indicator (a.k.a. TextDecorator). This class + * is designed to be independent of UI subsystems such as {@link View}. All the UI related + * operations are delegated to {@link TextDecoratorUi} via {@link TextDecoratorUiOperator}. + */ +public class TextDecorator { + private static final String TAG = TextDecorator.class.getSimpleName(); + private static final boolean DEBUG = false; + + private static final int MODE_NONE = 0; + private static final int MODE_COMMIT = 1; + private static final int MODE_ADD_TO_DICTIONARY = 2; + + private int mMode = MODE_NONE; + + private final PointF mLocalOrigin = new PointF(); + private final RectF mRelativeIndicatorBounds = new RectF(); + private final RectF mRelativeComposingTextBounds = new RectF(); + + private boolean mIsFullScreenMode = false; + private SuggestedWordInfo mWaitingWord = null; + private CursorAnchorInfoCompatWrapper mCursorAnchorInfoWrapper = null; + + @Nonnull + private final Listener mListener; + + @Nonnull + private TextDecoratorUiOperator mUiOperator = EMPTY_UI_OPERATOR; + + public interface Listener { + /** + * Called when the user clicks the composing text to commit. + * @param wordInfo the suggested word which the user clicked on. + */ + void onClickComposingTextToCommit(final SuggestedWordInfo wordInfo); + + /** + * Called when the user clicks the composing text to add the word into the dictionary. + * @param wordInfo the suggested word which the user clicked on. + */ + void onClickComposingTextToAddToDictionary(final SuggestedWordInfo wordInfo); + } + + public TextDecorator(final Listener listener) { + mListener = (listener != null) ? listener : EMPTY_LISTENER; + } + + /** + * Sets the UI operator for {@link TextDecorator}. Any user visible operations will be + * delegated to the associated UI operator. + * @param uiOperator the UI operator to be associated. + */ + public void setUiOperator(final TextDecoratorUiOperator uiOperator) { + mUiOperator.disposeUi(); + mUiOperator = uiOperator; + mUiOperator.setOnClickListener(getOnClickHandler()); + } + + private final Runnable mDefaultOnClickHandler = new Runnable() { + @Override + public void run() { + onClickIndicator(); + } + }; + + @UsedForTesting + final Runnable getOnClickHandler() { + return mDefaultOnClickHandler; + } + + /** + * Shows the "Commit" indicator and associates it with the given suggested word. + * + * <p>The effect of {@link #showCommitIndicator(SuggestedWordInfo)} and + * {@link #showAddToDictionaryIndicator(SuggestedWordInfo)} are exclusive to each other. Call + * {@link #reset()} to hide the indicator.</p> + * + * @param wordInfo the suggested word which should be associated with the indicator. This object + * will be passed back in {@link Listener#onClickComposingTextToCommit(SuggestedWordInfo)} + */ + public void showCommitIndicator(final SuggestedWordInfo wordInfo) { + if (mMode == MODE_COMMIT && wordInfo != null && + TextUtils.equals(mWaitingWord.mWord, wordInfo.mWord)) { + // Skip layout for better performance. + return; + } + mWaitingWord = wordInfo; + mMode = MODE_COMMIT; + layoutLater(); + } + + /** + * Shows the "Add to dictionary" indicator and associates it with associating the given + * suggested word. + * + * <p>The effect of {@link #showCommitIndicator(SuggestedWordInfo)} and + * {@link #showAddToDictionaryIndicator(SuggestedWordInfo)} are exclusive to each other. Call + * {@link #reset()} to hide the indicator.</p> + * + * @param wordInfo the suggested word which should be associated with the indicator. This object + * will be passed back in + * {@link Listener#onClickComposingTextToAddToDictionary(SuggestedWordInfo)}. + */ + public void showAddToDictionaryIndicator(final SuggestedWordInfo wordInfo) { + if (mMode == MODE_ADD_TO_DICTIONARY && wordInfo != null && + TextUtils.equals(mWaitingWord.mWord, wordInfo.mWord)) { + // Skip layout for better performance. + return; + } + mWaitingWord = wordInfo; + mMode = MODE_ADD_TO_DICTIONARY; + layoutLater(); + return; + } + + /** + * Must be called when the input method is about changing to for from the full screen mode. + * @param fullScreenMode {@code true} if the input method is entering the full screen mode. + * {@code false} is the input method is finishing the full screen mode. + */ + public void notifyFullScreenMode(final boolean fullScreenMode) { + final boolean currentFullScreenMode = mIsFullScreenMode; + if (!currentFullScreenMode && fullScreenMode) { + // Currently full screen mode is not supported. + // TODO: Support full screen mode. + mUiOperator.hideUi(); + } + mIsFullScreenMode = fullScreenMode; + } + + /** + * Resets previous requests and makes indicator invisible. + */ + public void reset() { + mWaitingWord = null; + mMode = MODE_NONE; + mLocalOrigin.set(0.0f, 0.0f); + mRelativeIndicatorBounds.set(0.0f, 0.0f, 0.0f, 0.0f); + mRelativeComposingTextBounds.set(0.0f, 0.0f, 0.0f, 0.0f); + cancelLayoutInternalExpectedly("Resetting internal state."); + } + + /** + * Must be called when the {@link InputMethodService#onUpdateCursorAnchorInfo()} is called. + * + * <p>CAVEAT: Currently the input method author is responsible for ignoring + * {@link InputMethodService#onUpdateCursorAnchorInfo()} called in full screen mode.</p> + * @param info the compatibility wrapper object for the received {@link CursorAnchorInfo}. + */ + public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) { + if (mIsFullScreenMode) { + // TODO: Consider to call InputConnection#requestCursorAnchorInfo to disable the + // event callback to suppress unnecessary event callbacks. + return; + } + mCursorAnchorInfoWrapper = info; + // Do not use layoutLater() to minimize the latency. + layoutImmediately(); + } + + /** + * Hides indicator if the new composing text doesn't match the expected one. + * + * <p>Calling this method is optional but recommended whenever the new composition is passed to + * the application. The motivation of this method is to reduce the UI latency. With this method, + * we can hide the indicator without waiting the arrival of the + * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} callback, assuming that + * the application accepts the new composing text without any modification. Even if this + * assumption is false, the indicator will be shown again when + * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is actually received. + * </p> + * + * @param newComposingText the new composing text that is being passed to the application. + */ + public void hideIndicatorIfNecessary(final CharSequence newComposingText) { + if (mMode != MODE_COMMIT && mMode != MODE_ADD_TO_DICTIONARY) { + return; + } + if (!TextUtils.equals(newComposingText, mWaitingWord.mWord)) { + mUiOperator.hideUi(); + } + } + + private void cancelLayoutInternalUnexpectedly(final String message) { + mUiOperator.hideUi(); + Log.d(TAG, message); + } + + private void cancelLayoutInternalExpectedly(final String message) { + mUiOperator.hideUi(); + if (DEBUG) { + Log.d(TAG, message); + } + } + + private void layoutLater() { + mLayoutInvalidator.invalidateLayout(); + } + + + private void layoutImmediately() { + // Clear pending layout requests. + mLayoutInvalidator.cancelInvalidateLayout(); + layoutMain(); + } + + private void layoutMain() { + if (mIsFullScreenMode) { + cancelLayoutInternalUnexpectedly("Full screen mode isn't yet supported."); + return; + } + + if (mMode != MODE_COMMIT && mMode != MODE_ADD_TO_DICTIONARY) { + if (mMode == MODE_NONE) { + cancelLayoutInternalExpectedly("Not ready for layouting."); + } else { + cancelLayoutInternalUnexpectedly("Unknown mMode=" + mMode); + } + return; + } + + final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper; + + if (info == null) { + cancelLayoutInternalExpectedly("CursorAnchorInfo isn't available."); + return; + } + + final Matrix matrix = info.getMatrix(); + if (matrix == null) { + cancelLayoutInternalUnexpectedly("Matrix is null"); + } + + final CharSequence composingText = info.getComposingText(); + if (mMode == MODE_COMMIT) { + if (composingText == null) { + cancelLayoutInternalExpectedly("composingText is null."); + return; + } + final int composingTextStart = info.getComposingTextStart(); + final int lastCharRectIndex = composingTextStart + composingText.length() - 1; + final RectF lastCharRect = info.getCharacterRect(lastCharRectIndex); + final int lastCharRectFlag = info.getCharacterRectFlags(lastCharRectIndex); + final int lastCharRectType = + lastCharRectFlag & CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_MASK; + if (lastCharRect == null || matrix == null || lastCharRectType != + CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_FULLY_VISIBLE) { + mUiOperator.hideUi(); + return; + } + final RectF segmentStartCharRect = new RectF(lastCharRect); + for (int i = composingText.length() - 2; i >= 0; --i) { + final RectF charRect = info.getCharacterRect(composingTextStart + i); + if (charRect == null) { + break; + } + if (charRect.top != segmentStartCharRect.top) { + break; + } + if (charRect.bottom != segmentStartCharRect.bottom) { + break; + } + segmentStartCharRect.set(charRect); + } + + mLocalOrigin.set(lastCharRect.right, lastCharRect.top); + mRelativeIndicatorBounds.set(lastCharRect.right, lastCharRect.top, + lastCharRect.right + lastCharRect.height(), lastCharRect.bottom); + mRelativeIndicatorBounds.offset(-mLocalOrigin.x, -mLocalOrigin.y); + + mRelativeIndicatorBounds.set(lastCharRect.right, lastCharRect.top, + lastCharRect.right + lastCharRect.height(), lastCharRect.bottom); + mRelativeIndicatorBounds.offset(-mLocalOrigin.x, -mLocalOrigin.y); + + mRelativeComposingTextBounds.set(segmentStartCharRect.left, segmentStartCharRect.top, + segmentStartCharRect.right, segmentStartCharRect.bottom); + mRelativeComposingTextBounds.offset(-mLocalOrigin.x, -mLocalOrigin.y); + + if (mWaitingWord == null) { + cancelLayoutInternalExpectedly("mWaitingText is null."); + return; + } + if (TextUtils.isEmpty(mWaitingWord.mWord)) { + cancelLayoutInternalExpectedly("mWaitingText.mWord is empty."); + return; + } + if (!TextUtils.equals(composingText, mWaitingWord.mWord)) { + // This is indeed an expected situation because of the asynchronous nature of + // input method framework in Android. Note that composingText is notified from the + // application, while mWaitingWord.mWord is obtained directly from the InputLogic. + cancelLayoutInternalExpectedly( + "Composing text doesn't match the one we are waiting for."); + return; + } + } else { + if (!TextUtils.isEmpty(composingText)) { + // This is an unexpected case. + // TODO: Document this. + mUiOperator.hideUi(); + return; + } + // In MODE_ADD_TO_DICTIONARY, we cannot retrieve the character position at all because + // of the lack of composing text. We will use the insertion marker position instead. + if (info.isInsertionMarkerClipped()) { + mUiOperator.hideUi(); + return; + } + final float insertionMarkerHolizontal = info.getInsertionMarkerHorizontal(); + final float insertionMarkerTop = info.getInsertionMarkerTop(); + mLocalOrigin.set(insertionMarkerHolizontal, insertionMarkerTop); + } + + final RectF indicatorBounds = new RectF(mRelativeIndicatorBounds); + final RectF composingTextBounds = new RectF(mRelativeComposingTextBounds); + indicatorBounds.offset(mLocalOrigin.x, mLocalOrigin.y); + composingTextBounds.offset(mLocalOrigin.x, mLocalOrigin.y); + mUiOperator.layoutUi(mMode == MODE_COMMIT, matrix, indicatorBounds, composingTextBounds); + } + + private void onClickIndicator() { + if (mWaitingWord == null || TextUtils.isEmpty(mWaitingWord.mWord)) { + return; + } + switch (mMode) { + case MODE_COMMIT: + mListener.onClickComposingTextToCommit(mWaitingWord); + break; + case MODE_ADD_TO_DICTIONARY: + mListener.onClickComposingTextToAddToDictionary(mWaitingWord); + break; + } + } + + private final LayoutInvalidator mLayoutInvalidator = new LayoutInvalidator(this); + + /** + * Used for managing pending layout tasks for {@link TextDecorator#layoutLater()}. + */ + private static final class LayoutInvalidator { + private final HandlerImpl mHandler; + public LayoutInvalidator(final TextDecorator ownerInstance) { + mHandler = new HandlerImpl(ownerInstance); + } + + private static final int MSG_LAYOUT = 0; + + private static final class HandlerImpl + extends LeakGuardHandlerWrapper<TextDecorator> { + public HandlerImpl(final TextDecorator ownerInstance) { + super(ownerInstance); + } + + @Override + public void handleMessage(final Message msg) { + final TextDecorator owner = getOwnerInstance(); + if (owner == null) { + return; + } + switch (msg.what) { + case MSG_LAYOUT: + owner.layoutMain(); + break; + } + } + } + + /** + * Puts a layout task into the scheduler. Does nothing if one or more layout tasks are + * already scheduled. + */ + public void invalidateLayout() { + if (!mHandler.hasMessages(MSG_LAYOUT)) { + mHandler.obtainMessage(MSG_LAYOUT).sendToTarget(); + } + } + + /** + * Clears the pending layout tasks. + */ + public void cancelInvalidateLayout() { + mHandler.removeMessages(MSG_LAYOUT); + } + } + + private final static Listener EMPTY_LISTENER = new Listener() { + @Override + public void onClickComposingTextToCommit(SuggestedWordInfo wordInfo) { + } + @Override + public void onClickComposingTextToAddToDictionary(SuggestedWordInfo wordInfo) { + } + }; + + private final static TextDecoratorUiOperator EMPTY_UI_OPERATOR = new TextDecoratorUiOperator() { + @Override + public void disposeUi() { + } + @Override + public void hideUi() { + } + @Override + public void setOnClickListener(Runnable listener) { + } + @Override + public void layoutUi(boolean isCommitMode, Matrix matrix, RectF indicatorBounds, + RectF composingTextBounds) { + } + }; +} diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java new file mode 100644 index 000000000..6e215a9ca --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; +import android.graphics.drawable.ColorDrawable; +import android.inputmethodservice.InputMethodService; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewParent; +import android.widget.PopupWindow; +import android.widget.RelativeLayout; + +import com.android.inputmethod.latin.R; + +/** + * Used as the UI component of {@link TextDecorator}. + */ +public final class TextDecoratorUi implements TextDecoratorUiOperator { + private static final boolean VISUAL_DEBUG = false; + private static final int VISUAL_DEBUG_HIT_AREA_COLOR = 0x80ff8000; + + private final RelativeLayout mLocalRootView; + private final CommitIndicatorView mCommitIndicatorView; + private final AddToDictionaryIndicatorView mAddToDictionaryIndicatorView; + private final PopupWindow mTouchEventWindow; + private final View mTouchEventWindowClickListenerView; + private final float mHitAreaMarginInPixels; + + /** + * This constructor is designed to be called from {@link InputMethodService#setInputView(View)}. + * Other usages are not supported. + * + * @param context the context of the input method. + * @param inputView the view that is passed to {@link InputMethodService#setInputView(View)}. + */ + public TextDecoratorUi(final Context context, final View inputView) { + final Resources resources = context.getResources(); + final int hitAreaMarginInDP = resources.getInteger( + R.integer.text_decorator_hit_area_margin_in_dp); + mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + hitAreaMarginInDP, resources.getDisplayMetrics()); + + mLocalRootView = new RelativeLayout(context); + mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + // TODO: Use #setBackground(null) for API Level >= 16. + mLocalRootView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + final ViewGroup contentView = getContentView(inputView); + mCommitIndicatorView = new CommitIndicatorView(context); + mAddToDictionaryIndicatorView = new AddToDictionaryIndicatorView(context); + mLocalRootView.addView(mCommitIndicatorView); + mLocalRootView.addView(mAddToDictionaryIndicatorView); + if (contentView != null) { + contentView.addView(mLocalRootView); + } + + // This popup window is used to avoid the limitation that the input method is not able to + // observe the touch events happening outside of InputMethodService.Insets#touchableRegion. + // We don't use this popup window for rendering the UI for performance reasons though. + mTouchEventWindow = new PopupWindow(context); + if (VISUAL_DEBUG) { + mTouchEventWindow.setBackgroundDrawable(new ColorDrawable(VISUAL_DEBUG_HIT_AREA_COLOR)); + } else { + mTouchEventWindow.setBackgroundDrawable(null); + } + mTouchEventWindowClickListenerView = new View(context); + mTouchEventWindow.setContentView(mTouchEventWindowClickListenerView); + } + + @Override + public void disposeUi() { + if (mLocalRootView != null) { + final ViewParent parent = mLocalRootView.getParent(); + if (parent != null && parent instanceof ViewGroup) { + ((ViewGroup) parent).removeView(mLocalRootView); + } + mLocalRootView.removeAllViews(); + } + if (mTouchEventWindow != null) { + mTouchEventWindow.dismiss(); + } + } + + @Override + public void hideUi() { + mCommitIndicatorView.setVisibility(View.GONE); + mAddToDictionaryIndicatorView.setVisibility(View.GONE); + mTouchEventWindow.dismiss(); + } + + @Override + public void layoutUi(final boolean isCommitMode, final Matrix matrix, + final RectF indicatorBounds, final RectF composingTextBounds) { + final RectF indicatorBoundsInScreenCoordinates = new RectF(); + matrix.mapRect(indicatorBoundsInScreenCoordinates, indicatorBounds); + mCommitIndicatorView.setBounds(indicatorBoundsInScreenCoordinates); + mAddToDictionaryIndicatorView.setBounds(indicatorBoundsInScreenCoordinates); + + final RectF hitAreaBounds = new RectF(composingTextBounds); + hitAreaBounds.union(indicatorBounds); + final RectF hitAreaBoundsInScreenCoordinates = new RectF(); + matrix.mapRect(hitAreaBoundsInScreenCoordinates, hitAreaBounds); + hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels); + + final int[] originScreen = new int[2]; + mLocalRootView.getLocationOnScreen(originScreen); + final int viewOriginX = originScreen[0]; + final int viewOriginY = originScreen[1]; + + final View toBeShown; + final View toBeHidden; + if (isCommitMode) { + toBeShown = mCommitIndicatorView; + toBeHidden = mAddToDictionaryIndicatorView; + } else { + toBeShown = mAddToDictionaryIndicatorView; + toBeHidden = mCommitIndicatorView; + } + toBeShown.setX(indicatorBoundsInScreenCoordinates.left - viewOriginX); + toBeShown.setY(indicatorBoundsInScreenCoordinates.top - viewOriginY); + toBeShown.setVisibility(View.VISIBLE); + toBeHidden.setVisibility(View.GONE); + + if (mTouchEventWindow.isShowing()) { + mTouchEventWindow.update((int)hitAreaBoundsInScreenCoordinates.left - viewOriginX, + (int)hitAreaBoundsInScreenCoordinates.top - viewOriginY, + (int)hitAreaBoundsInScreenCoordinates.width(), + (int)hitAreaBoundsInScreenCoordinates.height()); + } else { + mTouchEventWindow.setWidth((int)hitAreaBoundsInScreenCoordinates.width()); + mTouchEventWindow.setHeight((int)hitAreaBoundsInScreenCoordinates.height()); + mTouchEventWindow.showAtLocation(mLocalRootView, Gravity.NO_GRAVITY, + (int)hitAreaBoundsInScreenCoordinates.left - viewOriginX, + (int)hitAreaBoundsInScreenCoordinates.top - viewOriginY); + } + } + + @Override + public void setOnClickListener(final Runnable listener) { + mTouchEventWindowClickListenerView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(final View arg0) { + listener.run(); + } + }); + } + + private static class IndicatorView extends View { + private final Path mPath; + private final Path mTmpPath = new Path(); + private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private final Matrix mMatrix = new Matrix(); + private final int mBackgroundColor; + private final int mForegroundColor; + private final RectF mBounds = new RectF(); + public IndicatorView(Context context, final int pathResourceId, + final int sizeResourceId, final int backgroundColorResourceId, + final int foregroundColroResourceId) { + super(context); + final Resources resources = context.getResources(); + mPath = createPath(resources, pathResourceId, sizeResourceId); + mBackgroundColor = resources.getColor(backgroundColorResourceId); + mForegroundColor = resources.getColor(foregroundColroResourceId); + } + + public void setBounds(final RectF rect) { + mBounds.set(rect); + } + + @Override + protected void onDraw(Canvas canvas) { + mPaint.setColor(mBackgroundColor); + mPaint.setStyle(Paint.Style.FILL); + canvas.drawRect(0.0f, 0.0f, mBounds.width(), mBounds.height(), mPaint); + + mMatrix.reset(); + mMatrix.postScale(mBounds.width(), mBounds.height()); + mPath.transform(mMatrix, mTmpPath); + mPaint.setColor(mForegroundColor); + canvas.drawPath(mTmpPath, mPaint); + } + + private static Path createPath(final Resources resources, final int pathResourceId, + final int sizeResourceId) { + final int size = resources.getInteger(sizeResourceId); + final float normalizationFactor = 1.0f / size; + final int[] array = resources.getIntArray(pathResourceId); + + final Path path = new Path(); + for (int i = 0; i < array.length; i += 2) { + if (i == 0) { + path.moveTo(array[i] * normalizationFactor, array[i + 1] * normalizationFactor); + } else { + path.lineTo(array[i] * normalizationFactor, array[i + 1] * normalizationFactor); + } + } + path.close(); + return path; + } + } + + private static ViewGroup getContentView(final View view) { + final View rootView = view.getRootView(); + if (rootView == null) { + return null; + } + + final ViewGroup windowContentView = (ViewGroup)rootView.findViewById(android.R.id.content); + if (windowContentView == null) { + return null; + } + return windowContentView; + } + + private static final class CommitIndicatorView extends TextDecoratorUi.IndicatorView { + public CommitIndicatorView(final Context context) { + super(context, R.array.text_decorator_commit_indicator_path, + R.integer.text_decorator_commit_indicator_path_size, + R.color.text_decorator_commit_indicator_background_color, + R.color.text_decorator_commit_indicator_foreground_color); + } + } + + private static final class AddToDictionaryIndicatorView extends TextDecoratorUi.IndicatorView { + public AddToDictionaryIndicatorView(final Context context) { + super(context, R.array.text_decorator_add_to_dictionary_indicator_path, + R.integer.text_decorator_add_to_dictionary_indicator_path_size, + R.color.text_decorator_add_to_dictionary_indicator_background_color, + R.color.text_decorator_add_to_dictionary_indicator_foreground_color); + } + } +}
\ No newline at end of file diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java new file mode 100644 index 000000000..f84e12d8c --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard; + +import android.graphics.Matrix; +import android.graphics.PointF; +import android.graphics.RectF; + +/** + * This interface defines how UI operations required for {@link TextDecorator} are delegated to + * the actual UI implementation class. + */ +public interface TextDecoratorUiOperator { + /** + * Called to notify that the UI is ready to be disposed. + */ + void disposeUi(); + + /** + * Called when the UI should become invisible. + */ + void hideUi(); + + /** + * Called to set the new click handler. + * @param onClickListener the callback object whose {@link Runnable#run()} should be called when + * the indicator is clicked. + */ + void setOnClickListener(final Runnable onClickListener); + + /** + * Called when the layout should be updated. + * @param isCommitMode {@code true} if the commit indicator should be shown. Show the + * add-to-dictionary indicator otherwise. + * @param matrix The matrix that transforms the local coordinates into the screen coordinates. + * @param indicatorBounds The bounding box of the indicator, in local coordinates. + * @param composingTextBounds The bounding box of the composing text, in local coordinates. + */ + void layoutUi(final boolean isCommitMode, final Matrix matrix, final RectF indicatorBounds, + final RectF composingTextBounds); +} diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java index e9e12f09f..7fa935413 100644 --- a/java/src/com/android/inputmethod/latin/InputView.java +++ b/java/src/com/android/inputmethod/latin/InputView.java @@ -21,14 +21,14 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; -import android.widget.LinearLayout; +import android.widget.FrameLayout; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.keyboard.MainKeyboardView; import com.android.inputmethod.latin.suggestions.MoreSuggestionsView; import com.android.inputmethod.latin.suggestions.SuggestionStripView; -public final class InputView extends LinearLayout { +public final class InputView extends FrameLayout { private final Rect mInputViewRect = new Rect(); private MainKeyboardView mMainKeyboardView; private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 9a3927c4f..ee0ff5c0a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -29,7 +29,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.Rect; import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.net.ConnectivityManager; @@ -43,6 +42,7 @@ import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.SparseArray; +import android.view.Gravity; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup.LayoutParams; @@ -57,7 +57,6 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper; -import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.compat.InputMethodServiceCompatUtils; import com.android.inputmethod.dictionarypack.DictionaryPackConstants; import com.android.inputmethod.event.Event; @@ -69,6 +68,7 @@ import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.MainKeyboardView; +import com.android.inputmethod.keyboard.TextDecoratorUi; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.define.DebugFlags; @@ -94,6 +94,7 @@ import com.android.inputmethod.latin.utils.JniUtils; import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; import com.android.inputmethod.latin.utils.StatsUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; +import com.android.inputmethod.latin.utils.ViewLayoutUtils; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -150,8 +151,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // TODO: Move these {@link View}s to {@link KeyboardSwitcher}. private View mInputView; - private View mExtractArea; - private View mKeyPreviewBackingView; private SuggestionStripView mSuggestionStripView; private RichInputMethodManager mRichImm; @@ -183,8 +182,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6; private static final int MSG_RESET_CACHES = 7; private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8; + private static final int MSG_SHOW_COMMIT_INDICATOR = 9; // Update this when adding new messages - private static final int MSG_LAST = MSG_WAIT_FOR_DICTIONARY_LOAD; + private static final int MSG_LAST = MSG_SHOW_COMMIT_INDICATOR; private static final int ARG1_NOT_GESTURE_INPUT = 0; private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1; @@ -195,6 +195,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private int mDelayInMillisecondsToUpdateSuggestions; private int mDelayInMillisecondsToUpdateShiftState; + private int mDelayInMillisecondsToShowCommitIndicator; public UIHandler(final LatinIME ownerInstance) { super(ownerInstance); @@ -206,10 +207,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } final Resources res = latinIme.getResources(); - mDelayInMillisecondsToUpdateSuggestions = - res.getInteger(R.integer.config_delay_in_milliseconds_to_update_suggestions); - mDelayInMillisecondsToUpdateShiftState = - res.getInteger(R.integer.config_delay_in_milliseconds_to_update_shift_state); + mDelayInMillisecondsToUpdateSuggestions = res.getInteger( + R.integer.config_delay_in_milliseconds_to_update_suggestions); + mDelayInMillisecondsToUpdateShiftState = res.getInteger( + R.integer.config_delay_in_milliseconds_to_update_shift_state); + mDelayInMillisecondsToShowCommitIndicator = res.getInteger( + R.integer.text_decorator_delay_in_milliseconds_to_show_commit_indicator); } @Override @@ -258,7 +261,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen case MSG_RESET_CACHES: final SettingsValues settingsValues = latinIme.mSettings.getCurrent(); if (latinIme.mInputLogic.retryResetCachesAndReturnSuccess( - msg.arg1 == 1 /* tryResumeSuggestions */, + msg.arg1 == ARG1_TRUE /* tryResumeSuggestions */, msg.arg2 /* remainingTries */, this /* handler */)) { // If we were able to reset the caches, then we can reload the keyboard. // Otherwise, we'll do it when we can. @@ -267,6 +270,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen latinIme.getCurrentRecapitalizeState()); } break; + case MSG_SHOW_COMMIT_INDICATOR: + // Protocol of MSG_SET_COMMIT_INDICATOR_ENABLED: + // - what: MSG_SHOW_COMMIT_INDICATOR + // - arg1: not used. + // - arg2: not used. + // - obj: the Runnable object to be called back. + ((Runnable) msg.obj).run(); + break; case MSG_WAIT_FOR_DICTIONARY_LOAD: Log.i(TAG, "Timeout waiting for dictionary load"); break; @@ -367,6 +378,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen obtainMessage(MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED, suggestedWords).sendToTarget(); } + /** + * Posts a delayed task to show the commit indicator. + * + * <p>Only one task can exist in the queue. When this method is called, any prior task that + * has not yet fired will be canceled.</p> + * @param task the runnable object that will be fired when the delayed task is dispatched. + */ + public void postShowCommitIndicatorTask(final Runnable task) { + removeMessages(MSG_SHOW_COMMIT_INDICATOR); + sendMessageDelayed(obtainMessage(MSG_SHOW_COMMIT_INDICATOR, task), + mDelayInMillisecondsToShowCommitIndicator); + } + // Working variables for the following methods. private boolean mIsOrientationChanging; private boolean mPendingSuccessiveImsCallback; @@ -710,13 +734,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void setInputView(final View view) { super.setInputView(view); mInputView = view; - mExtractArea = getWindow().getWindow().getDecorView() - .findViewById(android.R.id.extractArea); - mKeyPreviewBackingView = view.findViewById(R.id.key_preview_backing); mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view); if (hasSuggestionStripView()) { mSuggestionStripView.setListener(this, view); } + mInputLogic.setTextDecoratorUi(new TextDecoratorUi(this, view)); } @Override @@ -751,20 +773,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // is not guaranteed. It may even be called at the same time on a different thread. final RichInputMethodSubtype richSubtype = new RichInputMethodSubtype(subtype); mSubtypeSwitcher.onSubtypeChanged(richSubtype); - mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype)); + mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype), + mSettings.getCurrent()); loadKeyboard(); } private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInput(editorInfo, restarting); - if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) { - // AcceptTypedWord feature relies on CursorAnchorInfo. - if (mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) { - InputConnectionCompatUtils.requestUpdateCursorAnchorInfo( - getCurrentInputConnection(), true /* enableMonitor */, - true /* requestImmediateCallback */); - } - } } @SuppressWarnings("deprecation") @@ -833,7 +848,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // span, so we should reset our state unconditionally, even if restarting is true. // We also tell the input logic about the combining rules for the current subtype, so // it can adjust its combiners if needed. - mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype()); + mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(), + currentSettingsValues); // Note: the following does a round-trip IPC on the main thread: be careful final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); @@ -973,9 +989,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // @Override public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) { if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) { - final CursorAnchorInfoCompatWrapper wrapper = - CursorAnchorInfoCompatWrapper.fromObject(info); - // TODO: Implement here + mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info)); } } @@ -1058,36 +1072,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen setSuggestedWords(suggestedWords); } - private int getAdjustedBackingViewHeight() { - final int currentHeight = mKeyPreviewBackingView.getHeight(); - if (currentHeight > 0) { - return currentHeight; - } - - final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView(); - if (visibleKeyboardView == null) { - return 0; - } - // TODO: !!!!!!!!!!!!!!!!!!!! Handle different backing view heights between the main !!! - // keyboard and the emoji keyboard. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - final int keyboardHeight = visibleKeyboardView.getHeight(); - final int suggestionsHeight = mSuggestionStripView.getHeight(); - final int displayHeight = getResources().getDisplayMetrics().heightPixels; - final Rect rect = new Rect(); - mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect); - final int notificationBarHeight = rect.top; - final int remainingHeight = displayHeight - notificationBarHeight - suggestionsHeight - - keyboardHeight; - - final LayoutParams params = mKeyPreviewBackingView.getLayoutParams(); - mSuggestionStripView.setMoreSuggestionsHeight(remainingHeight); - - // Let the backing cover the remaining region entirely. - params.height = remainingHeight; - mKeyPreviewBackingView.setLayoutParams(params); - return params.height; - } - @Override public void onComputeInsets(final InputMethodService.Insets outInsets) { super.onComputeInsets(outInsets); @@ -1095,40 +1079,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (visibleKeyboardView == null || !hasSuggestionStripView()) { return; } + final int inputHeight = mInputView.getHeight(); final boolean hasHardwareKeyboard = mKeyboardSwitcher.hasHardwareKeyboard(); if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) { // If there is a hardware keyboard and a visible software keyboard view has been hidden, // no visual element will be shown on the screen. - outInsets.touchableInsets = mInputView.getHeight(); - outInsets.visibleTopInsets = mInputView.getHeight(); + outInsets.touchableInsets = inputHeight; + outInsets.visibleTopInsets = inputHeight; return; } - final int adjustedBackingHeight = getAdjustedBackingViewHeight(); - final boolean backingGone = (mKeyPreviewBackingView.getVisibility() == View.GONE); - final int backingHeight = backingGone ? 0 : adjustedBackingHeight; - // In fullscreen mode, the height of the extract area managed by InputMethodService should - // be considered. - // See {@link android.inputmethodservice.InputMethodService#onComputeInsets}. - final int extractHeight = isFullscreenMode() ? mExtractArea.getHeight() : 0; - final int suggestionsHeight = (mSuggestionStripView.getVisibility() == View.GONE) ? 0 - : mSuggestionStripView.getHeight(); - final int extraHeight = extractHeight + backingHeight + suggestionsHeight; - int visibleTopY = extraHeight; - // Need to set touchable region only if input view is being shown + final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes() + && mSuggestionStripView.getVisibility() == View.VISIBLE) + ? mSuggestionStripView.getHeight() : 0; + final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight; + mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY); + // Need to set touchable region only if a keyboard view is being shown. if (visibleKeyboardView.isShown()) { - // Note that the height of Emoji layout is the same as the height of the main keyboard - // and the suggestion strip - if (mKeyboardSwitcher.isShowingEmojiPalettes() - || mSuggestionStripView.getVisibility() == View.VISIBLE) { - visibleTopY -= suggestionsHeight; - } - final int touchY = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY; - final int touchWidth = visibleKeyboardView.getWidth(); - final int touchHeight = visibleKeyboardView.getHeight() + extraHeight + final int touchLeft = 0; + final int touchTop = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY; + final int touchRight = visibleKeyboardView.getWidth(); + final int touchBottom = inputHeight // Extend touchable region below the keyboard. + EXTENDED_TOUCHABLE_REGION_HEIGHT; outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; - outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight); + outInsets.touchableRegion.set(touchLeft, touchTop, touchRight, touchBottom); } outInsets.contentTopInsets = visibleTopY; outInsets.visibleTopInsets = visibleTopY; @@ -1173,12 +1147,28 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void updateFullscreenMode() { + // Override layout parameters to expand {@link SoftInputWindow} to the entire screen. + // See {@link InputMethodService#setinputView(View) and + // {@link SoftInputWindow#updateWidthHeight(WindowManager.LayoutParams)}. + final Window window = getWindow().getWindow(); + ViewLayoutUtils.updateLayoutHeightOf(window, LayoutParams.MATCH_PARENT); + // This method may be called before {@link #setInputView(View)}. + if (mInputView != null) { + // In non-fullscreen mode, {@link InputView} and its parent inputArea should expand to + // the entire screen and be placed at the bottom of {@link SoftInputWindow}. + // In fullscreen mode, these shouldn't expand to the entire screen and should be + // coexistent with {@link #mExtractedArea} above. + // See {@link InputMethodService#setInputView(View) and + // com.android.internal.R.layout.input_method.xml. + final int layoutHeight = isFullscreenMode() + ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT; + final View inputArea = window.findViewById(android.R.id.inputArea); + ViewLayoutUtils.updateLayoutHeightOf(inputArea, layoutHeight); + ViewLayoutUtils.updateLayoutGravityOf(inputArea, Gravity.BOTTOM); + ViewLayoutUtils.updateLayoutHeightOf(mInputView, layoutHeight); + } super.updateFullscreenMode(); - - if (mKeyPreviewBackingView == null) return; - // In fullscreen mode, no need to have extra space to show the key preview. - // If not, we should have extra space above the keyboard to show the key preview. - mKeyPreviewBackingView.setVisibility(isFullscreenMode() ? View.GONE : View.VISIBLE); + mInputLogic.onUpdateFullscreenMode(isFullscreenMode()); } private int getCurrentAutoCapsState() { @@ -1216,6 +1206,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } mDictionaryFacilitator.addWordToUserDictionary(this /* context */, word); + mInputLogic.onAddWordToUserDictionary(); } // Callback for the {@link SuggestionStripView}, to call when the important notice strip is @@ -1412,7 +1403,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private void setSuggestedWords(final SuggestedWords suggestedWords) { - mInputLogic.setSuggestedWords(suggestedWords); + final SettingsValues currentSettingsValues = mSettings.getCurrent(); + mInputLogic.setSuggestedWords(suggestedWords, currentSettingsValues, mHandler); // TODO: Modify this when we support suggestions with hard keyboard if (!hasSuggestionStripView()) { return; @@ -1421,7 +1413,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } - final SettingsValues currentSettingsValues = mSettings.getCurrent(); final boolean shouldShowImportantNotice = ImportantNoticeUtils.shouldShowImportantNotice(this); final boolean shouldShowSuggestionCandidates = diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 035557610..497823aeb 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -30,7 +30,9 @@ import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.DebugLogUtils; @@ -906,4 +908,33 @@ public final class RichInputConnection { mIC.setSelection(mExpectedSelStart, mExpectedSelEnd); } } + + private boolean mCursorAnchorInfoMonitorEnabled = false; + + /** + * Requests the editor to call back {@link InputMethodManager#updateCursorAnchorInfo}. + * @param enableMonitor {@code true} to request the editor to call back the method whenever the + * cursor/anchor position is changed. + * @param requestImmediateCallback {@code true} to request the editor to call back the method + * as soon as possible to notify the current cursor/anchor position to the input method. + * @return {@code true} if the request is accepted. Returns {@code false} otherwise, which + * includes "not implemented" or "rejected" or "temporarily unavailable" or whatever which + * prevents the application from fulfilling the request. (TODO: Improve the API when it turns + * out that we actually need more detailed error codes) + */ + public boolean requestUpdateCursorAnchorInfo(final boolean enableMonitor, + final boolean requestImmediateCallback) { + final boolean scheduled = InputConnectionCompatUtils.requestUpdateCursorAnchorInfo(mIC, + enableMonitor, requestImmediateCallback); + mCursorAnchorInfoMonitorEnabled = (scheduled && enableMonitor); + return scheduled; + } + + /** + * @return {@code true} if the application reported that the monitor mode of + * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is currently enabled. + */ + public boolean isCursorAnchorInfoMonitorEnabled() { + return mCursorAnchorInfoMonitorEnabled; + } } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 790f72e79..4b5edb076 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -17,9 +17,12 @@ package com.android.inputmethod.latin.inputlogic; import android.graphics.Color; +import android.inputmethodservice.InputMethodService; import android.os.SystemClock; import android.text.SpannableString; +import android.text.Spanned; import android.text.TextUtils; +import android.text.style.BackgroundColorSpan; import android.text.style.SuggestionSpan; import android.util.Log; import android.view.KeyCharacterMap; @@ -27,11 +30,14 @@ import android.view.KeyEvent; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; +import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.event.Event; import com.android.inputmethod.event.InputTransaction; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.keyboard.TextDecorator; +import com.android.inputmethod.keyboard.TextDecoratorUiOperator; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.DictionaryFacilitator; @@ -46,6 +52,7 @@ import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.define.DebugFlags; +import com.android.inputmethod.latin.define.ProductionFlags; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; @@ -81,6 +88,18 @@ public final class InputLogic { public final Suggest mSuggest; private final DictionaryFacilitator mDictionaryFacilitator; + private final TextDecorator mTextDecorator = new TextDecorator(new TextDecorator.Listener() { + @Override + public void onClickComposingTextToCommit(SuggestedWordInfo wordInfo) { + mLatinIME.pickSuggestionManually(wordInfo); + } + @Override + public void onClickComposingTextToAddToDictionary(SuggestedWordInfo wordInfo) { + mLatinIME.addWordToUserDictionary(wordInfo.mWord); + mLatinIME.dismissAddToDictionaryHint(); + } + }); + public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; // This has package visibility so it can be accessed from InputLogicHandler. /* package */ final WordComposer mWordComposer; @@ -124,8 +143,9 @@ public final class InputLogic { * Call this when input starts or restarts in some editor (typically, in onStartInputView). * * @param combiningSpec the combining spec string for this subtype + * @param settingsValues the current settings values */ - public void startInput(final String combiningSpec) { + public void startInput(final String combiningSpec, final SettingsValues settingsValues) { mEnteredText = null; mWordComposer.restartCombining(combiningSpec); resetComposingState(true /* alsoResetLastComposedWord */); @@ -143,15 +163,24 @@ public final class InputLogic { } else { mInputLogicHandler.reset(); } + + if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) { + // AcceptTypedWord feature relies on CursorAnchorInfo. + if (settingsValues.mShouldShowUiToAcceptTypedWord) { + mConnection.requestUpdateCursorAnchorInfo(true /* enableMonitor */, + true /* requestImmediateCallback */); + } + } } /** * Call this when the subtype changes. * @param combiningSpec the spec string for the combining rules + * @param settingsValues the current settings values */ - public void onSubtypeChanged(final String combiningSpec) { + public void onSubtypeChanged(final String combiningSpec, final SettingsValues settingsValues) { finishInput(); - startInput(combiningSpec); + startInput(combiningSpec, settingsValues); } /** @@ -303,8 +332,18 @@ public final class InputLogic { return inputTransaction; } - commitChosenWord(settingsValues, suggestion, - LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR); + final boolean shouldShowAddToDictionaryHint = shouldShowAddToDictionaryHint(suggestionInfo); + final boolean shouldShowAddToDictionaryIndicator = + shouldShowAddToDictionaryHint && settingsValues.mShouldShowUiToAcceptTypedWord; + final int backgroundColor; + if (shouldShowAddToDictionaryIndicator) { + backgroundColor = settingsValues.mTextHighlightColorForAddToDictionaryIndicator; + } else { + backgroundColor = Color.TRANSPARENT; + } + commitChosenWordWithBackgroundColor(settingsValues, suggestion, + LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR, + backgroundColor); mConnection.endBatchEdit(); // Don't allow cancellation of manual pick mLastComposedWord.deactivate(); @@ -312,13 +351,16 @@ public final class InputLogic { mSpaceState = SpaceState.PHANTOM; inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); - if (shouldShowAddToDictionaryHint(suggestionInfo)) { + if (shouldShowAddToDictionaryHint) { mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion); } else { // If we're not showing the "Touch again to save", then update the suggestion strip. // That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE. handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE); } + if (shouldShowAddToDictionaryIndicator) { + mTextDecorator.showAddToDictionaryIndicator(suggestionInfo); + } return inputTransaction; } @@ -386,6 +428,8 @@ public final class InputLogic { // The cursor has been moved : we now accept to perform recapitalization mRecapitalizeStatus.enable(); + // We moved the cursor and need to invalidate the indicator right now. + mTextDecorator.reset(); // We moved the cursor. If we are touching a word, we need to resume suggestion. mLatinIME.mHandler.postResumeSuggestions(false /* shouldIncludeResumedWordInSuggestions */, true /* shouldDelay */); @@ -561,7 +605,8 @@ public final class InputLogic { // TODO: on the long term, this method should become private, but it will be difficult. // Especially, how do we deal with InputMethodService.onDisplayCompletions? - public void setSuggestedWords(final SuggestedWords suggestedWords) { + public void setSuggestedWords(final SuggestedWords suggestedWords, + final SettingsValues settingsValues, final LatinIME.UIHandler handler) { if (SuggestedWords.EMPTY != suggestedWords) { final String autoCorrection; if (suggestedWords.mWillAutoCorrect) { @@ -575,6 +620,43 @@ public final class InputLogic { } mSuggestedWords = suggestedWords; final boolean newAutoCorrectionIndicator = suggestedWords.mWillAutoCorrect; + if (shouldShowCommitIndicator(suggestedWords, settingsValues)) { + // typedWordInfo is never null here. + final int textBackgroundColor = settingsValues.mTextHighlightColorForCommitIndicator; + final SuggestedWordInfo typedWordInfo = suggestedWords.getTypedWordInfoOrNull(); + handler.postShowCommitIndicatorTask(new Runnable() { + @Override + public void run() { + // TODO: This needs to be refactored to ensure that mWordComposer is accessed + // only from the UI thread. + if (!mWordComposer.isComposingWord()) { + mTextDecorator.reset(); + return; + } + final SuggestedWordInfo currentTypedWordInfo = + mSuggestedWords.getTypedWordInfoOrNull(); + if (currentTypedWordInfo == null) { + mTextDecorator.reset(); + return; + } + if (!currentTypedWordInfo.equals(typedWordInfo)) { + // Suggested word has been changed. This task is obsolete. + mTextDecorator.reset(); + return; + } + // TODO: As with the above TODO comment, this operation must be performed only + // on the UI thread too. Needs to be refactored. + setComposingTextInternalWithBackgroundColor(typedWordInfo.mWord, + 1 /* newCursorPosition */, textBackgroundColor); + mTextDecorator.showCommitIndicator(typedWordInfo); + } + }); + } else { + // Note: It is OK to not cancel previous postShowCommitIndicatorTask() here. Having a + // cancellation mechanism could improve performance a bit though. + mTextDecorator.reset(); + } + // Put a blue underline to a word in TextView which will be auto-corrected. if (mIsAutoCorrectionIndicatorOn != newAutoCorrectionIndicator && mWordComposer.isComposingWord()) { @@ -585,7 +667,7 @@ public final class InputLogic { // message, this is called outside any batch edit. Potentially, this may result in some // janky flickering of the screen, although the display speed makes it unlikely in // the practice. - mConnection.setComposingText(textWithUnderline, 1); + setComposingTextInternal(textWithUnderline, 1); } } @@ -608,7 +690,7 @@ public final class InputLogic { inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { - mConnection.setComposingText(mWordComposer.getTypedWord(), 1); + setComposingTextInternal(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } @@ -756,6 +838,8 @@ public final class InputLogic { if (!mWordComposer.isComposingWord() && mSuggestionStripViewAccessor.isShowingAddToDictionaryHint()) { mSuggestionStripViewAccessor.dismissAddToDictionaryHint(); + mConnection.removeBackgroundColorFromHighlightedTextIfNecessary(); + mTextDecorator.reset(); } final int codePoint = event.mCodePoint; @@ -842,8 +926,7 @@ public final class InputLogic { if (mWordComposer.isSingleLetter()) { mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState); } - mConnection.setComposingText(getTextWithUnderline( - mWordComposer.getTypedWord()), 1); + setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1); } else { final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event, inputTransaction); @@ -1006,7 +1089,7 @@ public final class InputLogic { mWordComposer.applyProcessedEvent(event); } if (mWordComposer.isComposingWord()) { - mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1); + setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1); } else { mConnection.commitText("", 1); } @@ -1574,7 +1657,7 @@ public final class InputLogic { final int[] codePoints = StringUtils.toCodePointArray(stringToCommit); mWordComposer.setComposingWord(codePoints, mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)); - mConnection.setComposingText(textToCommit, 1); + setComposingTextInternal(textToCommit, 1); } // Don't restart suggestion yet. We'll restart if the user deletes the separator. mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; @@ -1907,10 +1990,10 @@ public final class InputLogic { } final String lastWord = batchInputText.substring(indexOfLastSpace); mWordComposer.setBatchInputWord(lastWord); - mConnection.setComposingText(lastWord, 1); + setComposingTextInternal(lastWord, 1); } else { mWordComposer.setBatchInputWord(batchInputText); - mConnection.setComposingText(batchInputText, 1); + setComposingTextInternal(batchInputText, 1); } mConnection.endBatchEdit(); // Space state must be updated before calling updateShiftState @@ -2108,4 +2191,126 @@ public final class InputLogic { settingsValues.mAutoCorrectionEnabledPerUserSettings, inputStyle, sequenceNumber, callback); } + + /** + * Used as an injection point for each call of + * {@link RichInputConnection#setComposingText(CharSequence, int)}. + * + * <p>Currently using this method is optional and you can still directly call + * {@link RichInputConnection#setComposingText(CharSequence, int)}, but it is recommended to + * use this method whenever possible to optimize the behavior of {@link TextDecorator}.<p> + * <p>TODO: Should we move this mechanism to {@link RichInputConnection}?</p> + * + * @param newComposingText the composing text to be set + * @param newCursorPosition the new cursor position + */ + private void setComposingTextInternal(final CharSequence newComposingText, + final int newCursorPosition) { + setComposingTextInternalWithBackgroundColor(newComposingText, newCursorPosition, + Color.TRANSPARENT); + } + + /** + * Equivalent to {@link #setComposingTextInternal(CharSequence, int)} except that this method + * allows to set {@link BackgroundColorSpan} to the composing text with the given color. + * + * <p>TODO: Currently the background color is exclusive with the black underline, which is + * automatically added by the framework. We need to change the framework if we need to have both + * of them at the same time.</p> + * <p>TODO: Should we move this method to {@link RichInputConnection}?</p> + * + * @param newComposingText the composing text to be set + * @param newCursorPosition the new cursor position + * @param backgroundColor the background color to be set to the composing text. Set + * {@link Color#TRANSPARENT} to disable the background color. + */ + private void setComposingTextInternalWithBackgroundColor(final CharSequence newComposingText, + final int newCursorPosition, final int backgroundColor) { + final CharSequence composingTextToBeSet; + if (backgroundColor == Color.TRANSPARENT) { + composingTextToBeSet = newComposingText; + } else { + final SpannableString spannable = new SpannableString(newComposingText); + final BackgroundColorSpan backgroundColorSpan = + new BackgroundColorSpan(backgroundColor); + spannable.setSpan(backgroundColorSpan, 0, spannable.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); + composingTextToBeSet = spannable; + } + mConnection.setComposingText(composingTextToBeSet, newCursorPosition); + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + // Following methods are tentatively placed in this class for the integration with + // TextDecorator. + // TODO: Decouple things that are not related to the input logic. + ////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Sets the UI operator for {@link TextDecorator}. + * @param uiOperator the UI operator which should be associated with {@link TextDecorator}. + */ + public void setTextDecoratorUi(final TextDecoratorUiOperator uiOperator) { + mTextDecorator.setUiOperator(uiOperator); + } + + /** + * Must be called from {@link InputMethodService#onUpdateCursorAnchorInfo} is called. + * @param info The wrapper object with which we can access cursor/anchor info. + */ + public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) { + mTextDecorator.onUpdateCursorAnchorInfo(info); + } + + /** + * Must be called when {@link InputMethodService#updateFullscreenMode} is called. + * @param isFullscreen {@code true} if the input method is in full-screen mode. + */ + public void onUpdateFullscreenMode(final boolean isFullscreen) { + mTextDecorator.notifyFullScreenMode(isFullscreen); + } + + /** + * Must be called from {@link LatinIME#addWordToUserDictionary(String)}. + */ + public void onAddWordToUserDictionary() { + mConnection.removeBackgroundColorFromHighlightedTextIfNecessary(); + mTextDecorator.reset(); + } + + /** + * Returns whether the commit indicator should be shown or not. + * @param suggestedWords the suggested word that is being displayed. + * @param settingsValues the current settings value. + * @return {@code true} if the commit indicator should be shown. + */ + private boolean shouldShowCommitIndicator(final SuggestedWords suggestedWords, + final SettingsValues settingsValues) { + if (!mConnection.isCursorAnchorInfoMonitorEnabled()) { + // We cannot help in this case because we are heavily relying on this new API. + return false; + } + if (!settingsValues.mShouldShowUiToAcceptTypedWord) { + return false; + } + final SuggestedWordInfo typedWordInfo = suggestedWords.getTypedWordInfoOrNull(); + if (typedWordInfo == null) { + return false; + } + if (suggestedWords.mInputStyle != SuggestedWords.INPUT_STYLE_TYPING){ + return false; + } + if (settingsValues.mShowCommitIndicatorOnlyForAutoCorrection + && !suggestedWords.mWillAutoCorrect) { + return false; + } + // TODO: Calling shouldShowAddToDictionaryHint(typedWordInfo) multiple times should be fine + // in terms of performance, but we can do better. One idea is to make SuggestedWords include + // a boolean that tells whether the word is a dictionary word or not. + if (settingsValues.mShowCommitIndicatorOnlyForOutOfVocabulary + && !shouldShowAddToDictionaryHint(typedWordInfo)) { + return false; + } + return true; + } } diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index a9789d888..91a2b6776 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -96,6 +96,12 @@ public class SettingsValues { public final int[] mAdditionalFeaturesSettingValues = new int[AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE]; + // TextDecorator + public final int mTextHighlightColorForCommitIndicator; + public final int mTextHighlightColorForAddToDictionaryIndicator; + public final boolean mShowCommitIndicatorOnlyForAutoCorrection; + public final boolean mShowCommitIndicatorOnlyForOutOfVocabulary; + // Debug settings public final boolean mIsInternal; public final int mKeyPreviewShowUpDuration; @@ -164,6 +170,14 @@ public class SettingsValues { mSuggestionsEnabledPerUserSettings = readSuggestionsEnabled(prefs); AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray( prefs, mAdditionalFeaturesSettingValues); + mShowCommitIndicatorOnlyForAutoCorrection = res.getBoolean( + R.bool.text_decorator_only_for_auto_correction); + mShowCommitIndicatorOnlyForOutOfVocabulary = res.getBoolean( + R.bool.text_decorator_only_for_out_of_vocabulary); + mTextHighlightColorForCommitIndicator = res.getColor( + R.color.text_decorator_commit_indicator_text_highlight_color); + mTextHighlightColorForAddToDictionaryIndicator = res.getColor( + R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color); mIsInternal = Settings.isInternal(prefs); mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration( prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION, @@ -401,6 +415,14 @@ public class SettingsValues { sb.append("" + (null == awu ? "null" : awu.toString())); sb.append("\n mAdditionalFeaturesSettingValues = "); sb.append("" + Arrays.toString(mAdditionalFeaturesSettingValues)); + sb.append("\n mShowCommitIndicatorOnlyForAutoCorrection = "); + sb.append("" + mShowCommitIndicatorOnlyForAutoCorrection); + sb.append("\n mShowCommitIndicatorOnlyForOutOfVocabulary = "); + sb.append("" + mShowCommitIndicatorOnlyForOutOfVocabulary); + sb.append("\n mTextHighlightColorForCommitIndicator = "); + sb.append("" + mTextHighlightColorForCommitIndicator); + sb.append("\n mTextHighlightColorForAddToDictionaryIndicator = "); + sb.append("" + mTextHighlightColorForAddToDictionaryIndicator); sb.append("\n mIsInternal = "); sb.append("" + mIsInternal); sb.append("\n mKeyPreviewShowUpDuration = "); diff --git a/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java b/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java index f9d853493..dd122b634 100644 --- a/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java @@ -19,7 +19,10 @@ package com.android.inputmethod.latin.utils; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; +import android.view.Window; +import android.view.WindowManager; import android.widget.FrameLayout; +import android.widget.LinearLayout; import android.widget.RelativeLayout; public final class ViewLayoutUtils { @@ -51,4 +54,40 @@ public final class ViewLayoutUtils { marginLayoutParams.setMargins(x, y, 0, 0); } } + + public static void updateLayoutHeightOf(final Window window, final int layoutHeight) { + final WindowManager.LayoutParams params = window.getAttributes(); + if (params.height != layoutHeight) { + params.height = layoutHeight; + window.setAttributes(params); + } + } + + public static void updateLayoutHeightOf(final View view, final int layoutHeight) { + final ViewGroup.LayoutParams params = view.getLayoutParams(); + if (params.height != layoutHeight) { + params.height = layoutHeight; + view.setLayoutParams(params); + } + } + + public static void updateLayoutGravityOf(final View view, final int layoutGravity) { + final ViewGroup.LayoutParams lp = view.getLayoutParams(); + if (lp instanceof LinearLayout.LayoutParams) { + final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)lp; + if (params.gravity != layoutGravity) { + params.gravity = layoutGravity; + view.setLayoutParams(params); + } + } else if (lp instanceof FrameLayout.LayoutParams) { + final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)lp; + if (params.gravity != layoutGravity) { + params.gravity = layoutGravity; + view.setLayoutParams(params); + } + } else { + throw new IllegalArgumentException("Layout parameter doesn't have gravity: " + + lp.getClass().getName()); + } + } } diff --git a/native/jni/NativeFileList.mk b/native/jni/NativeFileList.mk index 5e662543e..018a34d18 100644 --- a/native/jni/NativeFileList.mk +++ b/native/jni/NativeFileList.mk @@ -61,7 +61,6 @@ LATIN_IME_CORE_SRC_FILES := \ ver2_patricia_trie_node_reader.cpp \ ver2_pt_node_array_reader.cpp) \ $(addprefix suggest/policyimpl/dictionary/structure/v4/, \ - bigram/ver4_bigram_list_policy.cpp \ ver4_dict_buffers.cpp \ ver4_dict_constants.cpp \ ver4_patricia_trie_node_reader.cpp \ @@ -71,7 +70,6 @@ LATIN_IME_CORE_SRC_FILES := \ ver4_patricia_trie_writing_helper.cpp \ ver4_pt_node_array_reader.cpp) \ $(addprefix suggest/policyimpl/dictionary/structure/v4/content/, \ - bigram_dict_content.cpp \ language_model_dict_content.cpp \ shortcut_dict_content.cpp \ sparse_table_dict_content.cpp \ @@ -132,4 +130,5 @@ LATIN_IME_CORE_TEST_FILES := \ suggest/policyimpl/dictionary/utils/sparse_table_test.cpp \ suggest/policyimpl/dictionary/utils/trie_map_test.cpp \ utils/autocorrection_threshold_utils_test.cpp \ - utils/int_array_view_test.cpp + utils/int_array_view_test.cpp \ + utils/time_keeper_test.cpp diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index 22ad2d0ab..81e2ff548 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -32,6 +32,7 @@ #include "suggest/core/suggest_options.h" #include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h" #include "utils/char_utils.h" +#include "utils/int_array_view.h" #include "utils/jni_data_utils.h" #include "utils/log_utils.h" #include "utils/time_keeper.h" @@ -581,8 +582,9 @@ static bool latinime_BinaryDictionary_migrateNative(JNIEnv *env, jclass clazz, j return false; } } - if (!dictionaryStructureWithBufferPolicy->addUnigramEntry(wordCodePoints, - wordCodePointCount, wordProperty.getUnigramProperty())) { + if (!dictionaryStructureWithBufferPolicy->addUnigramEntry( + CodePointArrayView(wordCodePoints, wordCodePointCount), + wordProperty.getUnigramProperty())) { LogUtils::logToJava(env, "Cannot add unigram to the new dict."); return false; } diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index 24d04e51f..57e18884d 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -299,6 +299,7 @@ static inline void prof_out(void) { #define NOT_AN_INDEX (-1) #define NOT_A_PROBABILITY (-1) #define NOT_A_DICT_POS (S_INT_MIN) +#define NOT_A_WORD_ID (S_INT_MIN) #define NOT_A_TIMESTAMP (-1) #define NOT_A_LANGUAGE_WEIGHT (-1.0f) diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h index d1b2c87be..214cdfca6 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node.h +++ b/native/jni/src/suggest/core/dicnode/dic_node.h @@ -136,7 +136,7 @@ class DicNode { } void initAsChild(const DicNode *const dicNode, const int ptNodePos, - const int childrenPtNodeArrayPos, const int probability, const bool isTerminal, + const int childrenPtNodeArrayPos, const int probability, const int wordId, const bool hasChildren, const bool isBlacklistedOrNotAWord, const uint16_t mergedNodeCodePointCount, const int *const mergedNodeCodePoints) { uint16_t newDepth = static_cast<uint16_t>(dicNode->getNodeCodePointCount() + 1); @@ -144,7 +144,7 @@ class DicNode { const uint16_t newLeavingDepth = static_cast<uint16_t>( dicNode->mDicNodeProperties.getLeavingDepth() + mergedNodeCodePointCount); mDicNodeProperties.init(ptNodePos, childrenPtNodeArrayPos, mergedNodeCodePoints[0], - probability, isTerminal, hasChildren, isBlacklistedOrNotAWord, newDepth, + probability, wordId, hasChildren, isBlacklistedOrNotAWord, newDepth, newLeavingDepth, dicNode->mDicNodeProperties.getPrevWordsTerminalPtNodePos()); mDicNodeState.init(&dicNode->mDicNodeState, mergedNodeCodePointCount, mergedNodeCodePoints); diff --git a/native/jni/src/suggest/core/dicnode/dic_node_vector.h b/native/jni/src/suggest/core/dicnode/dic_node_vector.h index 54cde1988..f01640a93 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node_vector.h +++ b/native/jni/src/suggest/core/dicnode/dic_node_vector.h @@ -59,13 +59,13 @@ class DicNodeVector { } void pushLeavingChild(const DicNode *const dicNode, const int ptNodePos, - const int childrenPtNodeArrayPos, const int probability, const bool isTerminal, + const int childrenPtNodeArrayPos, const int probability, const int wordId, const bool hasChildren, const bool isBlacklistedOrNotAWord, const uint16_t mergedNodeCodePointCount, const int *const mergedNodeCodePoints) { ASSERT(!mLock); mDicNodes.emplace_back(); mDicNodes.back().initAsChild(dicNode, ptNodePos, childrenPtNodeArrayPos, probability, - isTerminal, hasChildren, isBlacklistedOrNotAWord, mergedNodeCodePointCount, + wordId, hasChildren, isBlacklistedOrNotAWord, mergedNodeCodePointCount, mergedNodeCodePoints); } diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h index 8202176f7..fc242a92b 100644 --- a/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h +++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h @@ -31,20 +31,20 @@ class DicNodeProperties { AK_FORCE_INLINE DicNodeProperties() : mPtNodePos(NOT_A_DICT_POS), mChildrenPtNodeArrayPos(NOT_A_DICT_POS), mProbability(NOT_A_PROBABILITY), mDicNodeCodePoint(NOT_A_CODE_POINT), - mIsTerminal(false), mHasChildrenPtNodes(false), + mWordId(NOT_A_WORD_ID), mHasChildrenPtNodes(false), mIsBlacklistedOrNotAWord(false), mDepth(0), mLeavingDepth(0) {} ~DicNodeProperties() {} // Should be called only once per DicNode is initialized. void init(const int pos, const int childrenPos, const int nodeCodePoint, const int probability, - const bool isTerminal, const bool hasChildren, const bool isBlacklistedOrNotAWord, + const int wordId, const bool hasChildren, const bool isBlacklistedOrNotAWord, const uint16_t depth, const uint16_t leavingDepth, const int *const prevWordsNodePos) { mPtNodePos = pos; mChildrenPtNodeArrayPos = childrenPos; mDicNodeCodePoint = nodeCodePoint; mProbability = probability; - mIsTerminal = isTerminal; + mWordId = wordId; mHasChildrenPtNodes = hasChildren; mIsBlacklistedOrNotAWord = isBlacklistedOrNotAWord; mDepth = depth; @@ -58,7 +58,7 @@ class DicNodeProperties { mChildrenPtNodeArrayPos = rootPtNodeArrayPos; mDicNodeCodePoint = NOT_A_CODE_POINT; mProbability = NOT_A_PROBABILITY; - mIsTerminal = false; + mWordId = NOT_A_WORD_ID; mHasChildrenPtNodes = true; mIsBlacklistedOrNotAWord = false; mDepth = 0; @@ -71,7 +71,7 @@ class DicNodeProperties { mChildrenPtNodeArrayPos = dicNodeProp->mChildrenPtNodeArrayPos; mDicNodeCodePoint = dicNodeProp->mDicNodeCodePoint; mProbability = dicNodeProp->mProbability; - mIsTerminal = dicNodeProp->mIsTerminal; + mWordId = dicNodeProp->mWordId; mHasChildrenPtNodes = dicNodeProp->mHasChildrenPtNodes; mIsBlacklistedOrNotAWord = dicNodeProp->mIsBlacklistedOrNotAWord; mDepth = dicNodeProp->mDepth; @@ -86,7 +86,7 @@ class DicNodeProperties { mChildrenPtNodeArrayPos = dicNodeProp->mChildrenPtNodeArrayPos; mDicNodeCodePoint = codePoint; // Overwrite the node char of a passing child mProbability = dicNodeProp->mProbability; - mIsTerminal = dicNodeProp->mIsTerminal; + mWordId = dicNodeProp->mWordId; mHasChildrenPtNodes = dicNodeProp->mHasChildrenPtNodes; mIsBlacklistedOrNotAWord = dicNodeProp->mIsBlacklistedOrNotAWord; mDepth = dicNodeProp->mDepth + 1; // Increment the depth of a passing child @@ -121,7 +121,7 @@ class DicNodeProperties { } bool isTerminal() const { - return mIsTerminal; + return mWordId != NOT_A_WORD_ID; } bool hasChildren() const { @@ -144,7 +144,7 @@ class DicNodeProperties { int mChildrenPtNodeArrayPos; int mProbability; int mDicNodeCodePoint; - bool mIsTerminal; + int mWordId; bool mHasChildrenPtNodes; bool mIsBlacklistedOrNotAWord; uint16_t mDepth; diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp index d62573970..c025bfcf5 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp @@ -28,6 +28,7 @@ #include "suggest/core/suggest_options.h" #include "suggest/policyimpl/gesture/gesture_suggest_policy_factory.h" #include "suggest/policyimpl/typing/typing_suggest_policy_factory.h" +#include "utils/int_array_view.h" #include "utils/log_utils.h" #include "utils/time_keeper.h" @@ -112,8 +113,8 @@ int Dictionary::getMaxProbabilityOfExactMatches(const int *word, int length) con int Dictionary::getNgramProbability(const PrevWordsInfo *const prevWordsInfo, const int *word, int length) const { TimeKeeper::setCurrentTime(); - int nextWordPos = mDictionaryStructureWithBufferPolicy->getTerminalPtNodePositionOfWord(word, - length, false /* forceLowerCaseSearch */); + int nextWordPos = mDictionaryStructureWithBufferPolicy->getTerminalPtNodePositionOfWord( + CodePointArrayView(word, length), false /* forceLowerCaseSearch */); if (NOT_A_DICT_POS == nextWordPos) return NOT_A_PROBABILITY; if (!prevWordsInfo) { return getDictionaryStructurePolicy()->getProbabilityOfPtNode( @@ -135,12 +136,14 @@ bool Dictionary::addUnigramEntry(const int *const word, const int length, return false; } TimeKeeper::setCurrentTime(); - return mDictionaryStructureWithBufferPolicy->addUnigramEntry(word, length, unigramProperty); + return mDictionaryStructureWithBufferPolicy->addUnigramEntry(CodePointArrayView(word, length), + unigramProperty); } bool Dictionary::removeUnigramEntry(const int *const codePoints, const int codePointCount) { TimeKeeper::setCurrentTime(); - return mDictionaryStructureWithBufferPolicy->removeUnigramEntry(codePoints, codePointCount); + return mDictionaryStructureWithBufferPolicy->removeUnigramEntry( + CodePointArrayView(codePoints, codePointCount)); } bool Dictionary::addNgramEntry(const PrevWordsInfo *const prevWordsInfo, @@ -152,7 +155,8 @@ bool Dictionary::addNgramEntry(const PrevWordsInfo *const prevWordsInfo, bool Dictionary::removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, const int *const word, const int length) { TimeKeeper::setCurrentTime(); - return mDictionaryStructureWithBufferPolicy->removeNgramEntry(prevWordsInfo, word, length); + return mDictionaryStructureWithBufferPolicy->removeNgramEntry(prevWordsInfo, + CodePointArrayView(word, length)); } bool Dictionary::flush(const char *const filePath) { @@ -181,7 +185,7 @@ const WordProperty Dictionary::getWordProperty(const int *const codePoints, const int codePointCount) { TimeKeeper::setCurrentTime(); return mDictionaryStructureWithBufferPolicy->getWordProperty( - codePoints, codePointCount); + CodePointArrayView(codePoints, codePointCount)); } int Dictionary::getNextWordAndNextToken(const int token, int *const outCodePoints, diff --git a/native/jni/src/suggest/core/dictionary/property/word_property.cpp b/native/jni/src/suggest/core/dictionary/property/word_property.cpp index 5bdd5606b..66daf3e3f 100644 --- a/native/jni/src/suggest/core/dictionary/property/word_property.cpp +++ b/native/jni/src/suggest/core/dictionary/property/word_property.cpp @@ -65,8 +65,6 @@ void WordProperty::outputProperties(JNIEnv *const env, jintArray outCodePoints, for (const auto &shortcut : mUnigramProperty.getShortcuts()) { const std::vector<int> *const targetCodePoints = shortcut.getTargetCodePoints(); jintArray shortcutTargetCodePointArray = env->NewIntArray(targetCodePoints->size()); - env->SetIntArrayRegion(shortcutTargetCodePointArray, 0 /* start */, - targetCodePoints->size(), targetCodePoints->data()); JniDataUtils::outputCodePoints(env, shortcutTargetCodePointArray, 0 /* start */, targetCodePoints->size(), targetCodePoints->data(), targetCodePoints->size(), false /* needsNullTermination */); diff --git a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h index e91f07682..0faf00003 100644 --- a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h +++ b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h @@ -21,6 +21,7 @@ #include "defines.h" #include "suggest/core/dictionary/property/word_property.h" +#include "utils/int_array_view.h" namespace latinime { @@ -36,6 +37,7 @@ class UnigramProperty; * This class abstracts the structure of dictionaries. * Implement this policy to support additional dictionaries. */ +// TODO: Use word id instead of terminal PtNode position. class DictionaryStructureWithBufferPolicy { public: typedef std::unique_ptr<DictionaryStructureWithBufferPolicy> StructurePolicyPtr; @@ -48,33 +50,32 @@ class DictionaryStructureWithBufferPolicy { DicNodeVector *const childDicNodes) const = 0; virtual int getCodePointsAndProbabilityAndReturnCodePointCount( - const int nodePos, const int maxCodePointCount, int *const outCodePoints, + const int ptNodePos, const int maxCodePointCount, int *const outCodePoints, int *const outUnigramProbability) const = 0; - virtual int getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const = 0; + virtual int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const = 0; - virtual int getProbability(const int unigramProbability, - const int bigramProbability) const = 0; + virtual int getProbability(const int unigramProbability, const int bigramProbability) const = 0; virtual int getProbabilityOfPtNode(const int *const prevWordsPtNodePos, - const int nodePos) const = 0; + const int ptNodePos) const = 0; virtual void iterateNgramEntries(const int *const prevWordsPtNodePos, NgramListener *const listener) const = 0; - virtual int getShortcutPositionOfPtNode(const int nodePos) const = 0; + virtual int getShortcutPositionOfPtNode(const int ptNodePos) const = 0; virtual const DictionaryHeaderStructurePolicy *getHeaderStructurePolicy() const = 0; virtual const DictionaryShortcutsStructurePolicy *getShortcutsStructurePolicy() const = 0; // Returns whether the update was success or not. - virtual bool addUnigramEntry(const int *const word, const int length, + virtual bool addUnigramEntry(const CodePointArrayView wordCodePoints, const UnigramProperty *const unigramProperty) = 0; // Returns whether the update was success or not. - virtual bool removeUnigramEntry(const int *const word, const int length) = 0; + virtual bool removeUnigramEntry(const CodePointArrayView wordCodePoints) = 0; // Returns whether the update was success or not. virtual bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo, @@ -82,7 +83,7 @@ class DictionaryStructureWithBufferPolicy { // Returns whether the update was success or not. virtual bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, - const int *const word, const int length) = 0; + const CodePointArrayView wordCodePoints) = 0; // Returns whether the flush was success or not. virtual bool flush(const char *const filePath) = 0; @@ -98,8 +99,7 @@ class DictionaryStructureWithBufferPolicy { const int maxResultLength) = 0; // Used for testing. - virtual const WordProperty getWordProperty(const int *const codePonts, - const int codePointCount) const = 0; + virtual const WordProperty getWordProperty(const CodePointArrayView wordCodePoints) const = 0; // Method to iterate all words in the dictionary. // The returned token has to be used to get the next word. If token is 0, this method newly diff --git a/native/jni/src/suggest/core/session/prev_words_info.h b/native/jni/src/suggest/core/session/prev_words_info.h index e44e876e9..9b3a7d468 100644 --- a/native/jni/src/suggest/core/session/prev_words_info.h +++ b/native/jni/src/suggest/core/session/prev_words_info.h @@ -21,6 +21,7 @@ #include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h" #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h" #include "utils/char_utils.h" +#include "utils/int_array_view.h" namespace latinime { @@ -91,19 +92,11 @@ class PrevWordsInfo { } // n is 1-indexed. - const int *getNthPrevWordCodePoints(const int n) const { + const CodePointArrayView getNthPrevWordCodePoints(const int n) const { if (n <= 0 || n > MAX_PREV_WORD_COUNT_FOR_N_GRAM) { - return nullptr; + return CodePointArrayView(); } - return mPrevWordCodePoints[n - 1]; - } - - // n is 1-indexed. - int getNthPrevWordCodePointCount(const int n) const { - if (n <= 0 || n > MAX_PREV_WORD_COUNT_FOR_N_GRAM) { - return 0; - } - return mPrevWordCodePointCount[n - 1]; + return CodePointArrayView(mPrevWordCodePoints[n - 1], mPrevWordCodePointCount[n - 1]); } // n is 1-indexed. @@ -134,8 +127,9 @@ class PrevWordsInfo { return NOT_A_DICT_POS; } } + const CodePointArrayView codePointArrayView(codePoints, codePointCount); const int wordPtNodePos = dictStructurePolicy->getTerminalPtNodePositionOfWord( - codePoints, codePointCount, false /* forceLowerCaseSearch */); + codePointArrayView, false /* forceLowerCaseSearch */); if (wordPtNodePos != NOT_A_DICT_POS || !tryLowerCaseSearch) { // Return the position when when the word was found or doesn't try lower case // search. @@ -144,7 +138,7 @@ class PrevWordsInfo { // Check bigrams for lower-cased previous word if original was not found. Useful for // auto-capitalized words like "The [current_word]". return dictStructurePolicy->getTerminalPtNodePositionOfWord( - codePoints, codePointCount, true /* forceLowerCaseSearch */); + codePointArrayView, true /* forceLowerCaseSearch */); } void clear() { diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp index 9c6452e40..9f6ae114d 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp @@ -76,8 +76,9 @@ void Ver4PatriciaTriePolicy::createAndGetAllChildDicNodes(const DicNode *const d // Skip PtNodes that represent non-word information. continue; } + const int wordId = isTerminal ? ptNodeParams.getHeadPos() : NOT_A_WORD_ID; childDicNodes->pushLeavingChild(dicNode, ptNodeParams.getHeadPos(), - ptNodeParams.getChildrenPos(), ptNodeParams.getProbability(), isTerminal, + ptNodeParams.getChildrenPos(), ptNodeParams.getProbability(), wordId, ptNodeParams.hasChildren(), ptNodeParams.isBlacklisted() || ptNodeParams.isNotAWord() /* isBlacklistedOrNotAWord */, @@ -103,12 +104,12 @@ int Ver4PatriciaTriePolicy::getCodePointsAndProbabilityAndReturnCodePointCount( return codePointCount; } -int Ver4PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const { +int Ver4PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const { DynamicPtReadingHelper readingHelper(&mNodeReader, &mPtNodeArrayReader); readingHelper.initWithPtNodeArrayPos(getRootPosition()); - const int ptNodePos = - readingHelper.getTerminalPtNodePositionOfWord(inWord, length, forceLowerCaseSearch); + const int ptNodePos = readingHelper.getTerminalPtNodePositionOfWord(wordCodePoints.data(), + wordCodePoints.size(), forceLowerCaseSearch); if (readingHelper.isError()) { mIsCorrupted = true; AKLOGE("Dictionary reading error in createAndGetAllChildDicNodes()."); @@ -193,7 +194,7 @@ int Ver4PatriciaTriePolicy::getBigramsPositionOfPtNode(const int ptNodePos) cons ptNodeParams.getTerminalId()); } -bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int length, +bool Ver4PatriciaTriePolicy::addUnigramEntry(const CodePointArrayView wordCodePoints, const UnigramProperty *const unigramProperty) { if (!mBuffers->isUpdatable()) { AKLOGI("Warning: addUnigramEntry() is called for non-updatable dictionary."); @@ -204,8 +205,9 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le mDictBuffer->getTailPosition()); return false; } - if (length > MAX_WORD_LENGTH) { - AKLOGE("The word is too long to insert to the dictionary, length: %d", length); + if (wordCodePoints.size() > MAX_WORD_LENGTH) { + AKLOGE("The word is too long to insert to the dictionary, length: %zd", + wordCodePoints.size()); return false; } for (const auto &shortcut : unigramProperty->getShortcuts()) { @@ -219,8 +221,8 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le readingHelper.initWithPtNodeArrayPos(getRootPosition()); bool addedNewUnigram = false; int codePointsToAdd[MAX_WORD_LENGTH]; - int codePointCountToAdd = length; - memmove(codePointsToAdd, word, sizeof(int) * length); + int codePointCountToAdd = wordCodePoints.size(); + memmove(codePointsToAdd, wordCodePoints.data(), sizeof(int) * codePointCountToAdd); if (unigramProperty->representsBeginningOfSentence()) { codePointCountToAdd = CharUtils::attachBeginningOfSentenceMarker(codePointsToAdd, codePointCountToAdd, MAX_WORD_LENGTH); @@ -228,14 +230,15 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le if (codePointCountToAdd <= 0) { return false; } - if (mUpdatingHelper.addUnigramWord(&readingHelper, codePointsToAdd, codePointCountToAdd, - unigramProperty, &addedNewUnigram)) { + const CodePointArrayView codePointArrayView(codePointsToAdd, codePointCountToAdd); + if (mUpdatingHelper.addUnigramWord(&readingHelper, codePointArrayView.data(), + codePointArrayView.size(), unigramProperty, &addedNewUnigram)) { if (addedNewUnigram && !unigramProperty->representsBeginningOfSentence()) { mUnigramCount++; } if (unigramProperty->getShortcuts().size() > 0) { // Add shortcut target. - const int wordPos = getTerminalPtNodePositionOfWord(word, length, + const int wordPos = getTerminalPtNodePositionOfWord(codePointArrayView, false /* forceLowerCaseSearch */); if (wordPos == NOT_A_DICT_POS) { AKLOGE("Cannot find terminal PtNode position to add shortcut target."); @@ -258,12 +261,12 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le } } -bool Ver4PatriciaTriePolicy::removeUnigramEntry(const int *const word, const int length) { +bool Ver4PatriciaTriePolicy::removeUnigramEntry(const CodePointArrayView wordCodePoints) { if (!mBuffers->isUpdatable()) { AKLOGI("Warning: removeUnigramEntry() is called for non-updatable dictionary."); return false; } - const int ptNodePos = getTerminalPtNodePositionOfWord(word, length, + const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (ptNodePos == NOT_A_DICT_POS) { return false; @@ -304,7 +307,6 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI false /* isBlacklisted */, MAX_PROBABILITY /* probability */, NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */, &shortcuts); if (!addUnigramEntry(prevWordsInfo->getNthPrevWordCodePoints(1 /* n */), - prevWordsInfo->getNthPrevWordCodePointCount(1 /* n */), &beginningOfSentenceUnigramProperty)) { AKLOGE("Cannot add unigram entry for the beginning-of-sentence."); return false; @@ -317,8 +319,8 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI } } const int word1Pos = getTerminalPtNodePositionOfWord( - bigramProperty->getTargetCodePoints()->data(), - bigramProperty->getTargetCodePoints()->size(), false /* forceLowerCaseSearch */); + CodePointArrayView(*bigramProperty->getTargetCodePoints()), + false /* forceLowerCaseSearch */); if (word1Pos == NOT_A_DICT_POS) { return false; } @@ -335,7 +337,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI } bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, - const int *const word, const int length) { + const CodePointArrayView wordCodePoints) { if (!mBuffers->isUpdatable()) { AKLOGI("Warning: removeNgramEntry() is called for non-updatable dictionary."); return false; @@ -349,8 +351,9 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor AKLOGE("prev words info is not valid for removing n-gram entry form the dictionary."); return false; } - if (length > MAX_WORD_LENGTH) { - AKLOGE("word is too long to remove n-gram entry form the dictionary. length: %d", length); + if (wordCodePoints.size() > MAX_WORD_LENGTH) { + AKLOGE("word is too long to remove n-gram entry form the dictionary. length: %zd", + wordCodePoints.size()); } int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM]; prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos, @@ -359,7 +362,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) { return false; } - const int wordPos = getTerminalPtNodePositionOfWord(word, length, + const int wordPos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (wordPos == NOT_A_DICT_POS) { return false; @@ -444,9 +447,9 @@ void Ver4PatriciaTriePolicy::getProperty(const char *const query, const int quer } } -const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const codePoints, - const int codePointCount) const { - const int ptNodePos = getTerminalPtNodePositionOfWord(codePoints, codePointCount, +const WordProperty Ver4PatriciaTriePolicy::getWordProperty( + const CodePointArrayView wordCodePoints) const { + const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (ptNodePos == NOT_A_DICT_POS) { AKLOGE("getWordProperty is called for invalid word."); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h index d77499636..df119e3a1 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h @@ -39,6 +39,7 @@ #include "suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_writing_helper.h" #include "suggest/policyimpl/dictionary/structure/backward/v402/ver4_pt_node_array_reader.h" #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" +#include "utils/int_array_view.h" namespace latinime { namespace backward { @@ -55,6 +56,7 @@ class DicNodeVector; namespace backward { namespace v402 { +// Word id = Position of a PtNode that represents the word. class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { public: Ver4PatriciaTriePolicy(Ver4DictBuffers::Ver4DictBuffersPtr buffers) @@ -74,7 +76,7 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { mBigramCount(mHeaderPolicy->getBigramCount()), mTerminalPtNodePositionsForIteratingWords(), mIsCorrupted(false) {}; - AK_FORCE_INLINE int getRootPosition() const { + virtual int getRootPosition() const { return 0; } @@ -85,8 +87,8 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { const int terminalPtNodePos, const int maxCodePointCount, int *const outCodePoints, int *const outUnigramProbability) const; - int getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const; + int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const; int getProbability(const int unigramProbability, const int bigramProbability) const; @@ -105,16 +107,16 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { return &mShortcutPolicy; } - bool addUnigramEntry(const int *const word, const int length, + bool addUnigramEntry(const CodePointArrayView wordCodePoints, const UnigramProperty *const unigramProperty); - bool removeUnigramEntry(const int *const word, const int length); + bool removeUnigramEntry(const CodePointArrayView wordCodePoints); bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo, const BigramProperty *const bigramProperty); - bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, const int *const word1, - const int length1); + bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, + const CodePointArrayView wordCodePoints); bool flush(const char *const filePath); @@ -125,8 +127,7 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { void getProperty(const char *const query, const int queryLength, char *const outResult, const int maxResultLength); - const WordProperty getWordProperty(const int *const codePoints, - const int codePointCount) const; + const WordProperty getWordProperty(const CodePointArrayView wordCodePoints) const; int getNextWordAndNextToken(const int token, int *const outCodePoints, int *const outCodePointCount); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp index ea32eb2a9..4ac366e07 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp @@ -268,12 +268,12 @@ int PatriciaTriePolicy::getCodePointsAndProbabilityAndReturnCodePointCount( // This function gets the position of the terminal PtNode of the exact matching word in the // dictionary. If no match is found, it returns NOT_A_DICT_POS. -int PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const { +int PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const { DynamicPtReadingHelper readingHelper(&mPtNodeReader, &mPtNodeArrayReader); readingHelper.initWithPtNodeArrayPos(getRootPosition()); - const int ptNodePos = - readingHelper.getTerminalPtNodePositionOfWord(inWord, length, forceLowerCaseSearch); + const int ptNodePos = readingHelper.getTerminalPtNodePositionOfWord(wordCodePoints.data(), + wordCodePoints.size(), forceLowerCaseSearch); if (readingHelper.isError()) { mIsCorrupted = true; AKLOGE("Dictionary reading error in createAndGetAllChildDicNodes()."); @@ -367,8 +367,8 @@ int PatriciaTriePolicy::createAndGetLeavingChildNode(const DicNode *const dicNod &probability, &childrenPos, &shortcutPos, &bigramPos, &siblingPos); // Skip PtNodes don't start with Unicode code point because they represent non-word information. if (CharUtils::isInUnicodeSpace(mergedNodeCodePoints[0])) { - childDicNodes->pushLeavingChild(dicNode, ptNodePos, childrenPos, probability, - PatriciaTrieReadingUtils::isTerminal(flags), + const int wordId = PatriciaTrieReadingUtils::isTerminal(flags) ? ptNodePos : NOT_A_WORD_ID; + childDicNodes->pushLeavingChild(dicNode, ptNodePos, childrenPos, probability, wordId, PatriciaTrieReadingUtils::hasChildrenInFlags(flags), PatriciaTrieReadingUtils::isBlacklisted(flags) || PatriciaTrieReadingUtils::isNotAWord(flags), @@ -377,9 +377,9 @@ int PatriciaTriePolicy::createAndGetLeavingChildNode(const DicNode *const dicNod return siblingPos; } -const WordProperty PatriciaTriePolicy::getWordProperty(const int *const codePoints, - const int codePointCount) const { - const int ptNodePos = getTerminalPtNodePositionOfWord(codePoints, codePointCount, +const WordProperty PatriciaTriePolicy::getWordProperty( + const CodePointArrayView wordCodePoints) const { + const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (ptNodePos == NOT_A_DICT_POS) { AKLOGE("getWordProperty was called for invalid word."); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h index 70351d147..4d9af2877 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h @@ -30,12 +30,14 @@ #include "suggest/policyimpl/dictionary/utils/format_utils.h" #include "suggest/policyimpl/dictionary/utils/mmapped_buffer.h" #include "utils/byte_array_view.h" +#include "utils/int_array_view.h" namespace latinime { class DicNode; class DicNodeVector; +// Word id = Position of a PtNode that represents the word. class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { public: PatriciaTriePolicy(MmappedBuffer::MmappedBufferPtr mmappedBuffer) @@ -62,8 +64,8 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { const int terminalNodePos, const int maxCodePointCount, int *const outCodePoints, int *const outUnigramProbability) const; - int getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const; + int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const; int getProbability(const int unigramProbability, const int bigramProbability) const; @@ -82,14 +84,14 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { return &mShortcutListPolicy; } - bool addUnigramEntry(const int *const word, const int length, + bool addUnigramEntry(const CodePointArrayView wordCodePoints, const UnigramProperty *const unigramProperty) { // This method should not be called for non-updatable dictionary. AKLOGI("Warning: addUnigramEntry() is called for non-updatable dictionary."); return false; } - bool removeUnigramEntry(const int *const word, const int length) { + bool removeUnigramEntry(const CodePointArrayView wordCodePoints) { // This method should not be called for non-updatable dictionary. AKLOGI("Warning: removeUnigramEntry() is called for non-updatable dictionary."); return false; @@ -102,8 +104,8 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { return false; } - bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, const int *const word, - const int length) { + bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, + const CodePointArrayView wordCodePoints) { // This method should not be called for non-updatable dictionary. AKLOGI("Warning: removeNgramEntry() is called for non-updatable dictionary."); return false; @@ -135,8 +137,7 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { } } - const WordProperty getWordProperty(const int *const codePoints, - const int codePointCount) const; + const WordProperty getWordProperty(const CodePointArrayView wordCodePoints) const; int getNextWordAndNextToken(const int token, int *const outCodePoints, int *const outCodePointCount); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.cpp deleted file mode 100644 index 08dc107ab..000000000 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h" - -#include "suggest/core/dictionary/property/bigram_property.h" -#include "suggest/policyimpl/dictionary/header/header_policy.h" -#include "suggest/policyimpl/dictionary/structure/pt_common/bigram/bigram_list_read_write_utils.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h" -#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" -#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h" - -namespace latinime { - -void Ver4BigramListPolicy::getNextBigram(int *const outBigramPos, int *const outProbability, - bool *const outHasNext, int *const bigramEntryPos) const { - const BigramEntry bigramEntry = - mBigramDictContent->getBigramEntryAndAdvancePosition(bigramEntryPos); - if (outBigramPos) { - // Lookup target PtNode position. - *outBigramPos = mTerminalPositionLookupTable->getTerminalPtNodePosition( - bigramEntry.getTargetTerminalId()); - } - if (outProbability) { - if (bigramEntry.hasHistoricalInfo()) { - *outProbability = - ForgettingCurveUtils::decodeProbability(bigramEntry.getHistoricalInfo(), - mHeaderPolicy); - } else { - *outProbability = bigramEntry.getProbability(); - } - } - if (outHasNext) { - *outHasNext = bigramEntry.hasNext(); - } -} - -bool Ver4BigramListPolicy::addNewEntry(const int terminalId, const int newTargetTerminalId, - const BigramProperty *const bigramProperty, bool *const outAddedNewEntry) { - // 1. The word has no bigrams yet. - // 2. The word has bigrams, and there is the target in the list. - // 3. The word has bigrams, and there is an invalid entry that can be reclaimed. - // 4. The word has bigrams. We have to append new bigram entry to the list. - // 5. Same as 4, but the list is the last entry of the content file. - if (outAddedNewEntry) { - *outAddedNewEntry = false; - } - const int bigramListPos = mBigramDictContent->getBigramListHeadPos(terminalId); - if (bigramListPos == NOT_A_DICT_POS) { - // Case 1. PtNode that doesn't have a bigram list. - // Create new bigram list. - if (!mBigramDictContent->createNewBigramList(terminalId)) { - return false; - } - const BigramEntry newBigramEntry(false /* hasNext */, NOT_A_PROBABILITY, - newTargetTerminalId); - const BigramEntry bigramEntryToWrite = createUpdatedBigramEntryFrom(&newBigramEntry, - bigramProperty); - // Write an entry. - int writingPos = mBigramDictContent->getBigramListHeadPos(terminalId); - if (!mBigramDictContent->writeBigramEntryAndAdvancePosition(&bigramEntryToWrite, - &writingPos)) { - AKLOGE("Cannot write bigram entry. pos: %d.", writingPos); - return false; - } - if (!mBigramDictContent->writeTerminator(writingPos)) { - AKLOGE("Cannot write bigram list terminator. pos: %d.", writingPos); - return false; - } - if (outAddedNewEntry) { - *outAddedNewEntry = true; - } - return true; - } - - int tailEntryPos = NOT_A_DICT_POS; - const int entryPosToUpdate = getEntryPosToUpdate(newTargetTerminalId, bigramListPos, - &tailEntryPos); - if (entryPosToUpdate == NOT_A_DICT_POS) { - // Case 4, 5. Add new entry to the bigram list. - const int contentTailPos = mBigramDictContent->getContentTailPos(); - // If the tail entry is at the tail of content buffer, the new entry can be written without - // link (Case 5). - const bool canAppendEntry = - contentTailPos == tailEntryPos + mBigramDictContent->getBigramEntrySize(); - const int newEntryPos = canAppendEntry ? tailEntryPos : contentTailPos; - int writingPos = newEntryPos; - // Write new entry at the tail position of the bigram content. - const BigramEntry newBigramEntry(false /* hasNext */, NOT_A_PROBABILITY, - newTargetTerminalId); - const BigramEntry bigramEntryToWrite = createUpdatedBigramEntryFrom( - &newBigramEntry, bigramProperty); - if (!mBigramDictContent->writeBigramEntryAndAdvancePosition(&bigramEntryToWrite, - &writingPos)) { - AKLOGE("Cannot write bigram entry. pos: %d.", writingPos); - return false; - } - if (!mBigramDictContent->writeTerminator(writingPos)) { - AKLOGE("Cannot write bigram list terminator. pos: %d.", writingPos); - return false; - } - if (!canAppendEntry) { - // Update link of the current tail entry. - if (!mBigramDictContent->writeLink(newEntryPos, tailEntryPos)) { - AKLOGE("Cannot update bigram entry link. pos: %d, linked entry pos: %d.", - tailEntryPos, newEntryPos); - return false; - } - } - if (outAddedNewEntry) { - *outAddedNewEntry = true; - } - return true; - } - - // Case 2. Overwrite the existing entry. Case 3. Reclaim and reuse the existing invalid entry. - const BigramEntry originalBigramEntry = mBigramDictContent->getBigramEntry(entryPosToUpdate); - if (!originalBigramEntry.isValid()) { - // Case 3. Reuse the existing invalid entry. outAddedNewEntry is false when an existing - // entry is updated. - if (outAddedNewEntry) { - *outAddedNewEntry = true; - } - } - const BigramEntry updatedBigramEntry = - originalBigramEntry.updateTargetTerminalIdAndGetEntry(newTargetTerminalId); - const BigramEntry bigramEntryToWrite = createUpdatedBigramEntryFrom( - &updatedBigramEntry, bigramProperty); - return mBigramDictContent->writeBigramEntry(&bigramEntryToWrite, entryPosToUpdate); -} - -bool Ver4BigramListPolicy::removeEntry(const int terminalId, const int targetTerminalId) { - const int bigramListPos = mBigramDictContent->getBigramListHeadPos(terminalId); - if (bigramListPos == NOT_A_DICT_POS) { - // Bigram list doesn't exist. - return false; - } - const int entryPosToUpdate = getEntryPosToUpdate(targetTerminalId, bigramListPos, - nullptr /* outTailEntryPos */); - if (entryPosToUpdate == NOT_A_DICT_POS) { - // Bigram entry doesn't exist. - return false; - } - const BigramEntry bigramEntry = mBigramDictContent->getBigramEntry(entryPosToUpdate); - if (targetTerminalId != bigramEntry.getTargetTerminalId()) { - // Bigram entry doesn't exist. - return false; - } - // Remove bigram entry by marking it as invalid entry and overwriting the original entry. - const BigramEntry updatedBigramEntry = bigramEntry.getInvalidatedEntry(); - return mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPosToUpdate); -} - -bool Ver4BigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(const int terminalId, - int *const outBigramCount) { - const int bigramListPos = mBigramDictContent->getBigramListHeadPos(terminalId); - if (bigramListPos == NOT_A_DICT_POS) { - // Bigram list doesn't exist. - return true; - } - bool hasNext = true; - int readingPos = bigramListPos; - while (hasNext) { - const BigramEntry bigramEntry = - mBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); - const int entryPos = readingPos - mBigramDictContent->getBigramEntrySize(); - hasNext = bigramEntry.hasNext(); - if (!bigramEntry.isValid()) { - continue; - } - const int targetPtNodePos = mTerminalPositionLookupTable->getTerminalPtNodePosition( - bigramEntry.getTargetTerminalId()); - if (targetPtNodePos == NOT_A_DICT_POS) { - // Invalidate bigram entry. - const BigramEntry updatedBigramEntry = bigramEntry.getInvalidatedEntry(); - if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) { - return false; - } - } else if (bigramEntry.hasHistoricalInfo()) { - const HistoricalInfo historicalInfo = ForgettingCurveUtils::createHistoricalInfoToSave( - bigramEntry.getHistoricalInfo(), mHeaderPolicy); - if (ForgettingCurveUtils::needsToKeep(&historicalInfo, mHeaderPolicy)) { - const BigramEntry updatedBigramEntry = - bigramEntry.updateHistoricalInfoAndGetEntry(&historicalInfo); - if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) { - return false; - } - *outBigramCount += 1; - } else { - // Remove entry. - const BigramEntry updatedBigramEntry = bigramEntry.getInvalidatedEntry(); - if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) { - return false; - } - } - } else { - *outBigramCount += 1; - } - } - return true; -} - -int Ver4BigramListPolicy::getBigramEntryConut(const int terminalId) { - const int bigramListPos = mBigramDictContent->getBigramListHeadPos(terminalId); - if (bigramListPos == NOT_A_DICT_POS) { - // Bigram list doesn't exist. - return 0; - } - int bigramCount = 0; - bool hasNext = true; - int readingPos = bigramListPos; - while (hasNext) { - const BigramEntry bigramEntry = - mBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); - hasNext = bigramEntry.hasNext(); - if (bigramEntry.isValid()) { - bigramCount++; - } - } - return bigramCount; -} - -int Ver4BigramListPolicy::getEntryPosToUpdate(const int targetTerminalIdToFind, - const int bigramListPos, int *const outTailEntryPos) const { - if (outTailEntryPos) { - *outTailEntryPos = NOT_A_DICT_POS; - } - int invalidEntryPos = NOT_A_DICT_POS; - int readingPos = bigramListPos; - while (true) { - const BigramEntry bigramEntry = - mBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); - const int entryPos = readingPos - mBigramDictContent->getBigramEntrySize(); - if (!bigramEntry.hasNext()) { - if (outTailEntryPos) { - *outTailEntryPos = entryPos; - } - break; - } - if (bigramEntry.getTargetTerminalId() == targetTerminalIdToFind) { - // Entry with same target is found. - return entryPos; - } else if (!bigramEntry.isValid()) { - // Invalid entry that can be reused is found. - invalidEntryPos = entryPos; - } - } - return invalidEntryPos; -} - -const BigramEntry Ver4BigramListPolicy::createUpdatedBigramEntryFrom( - const BigramEntry *const originalBigramEntry, - const BigramProperty *const bigramProperty) const { - // TODO: Consolidate historical info and probability. - if (mHeaderPolicy->hasHistoricalInfoOfWords()) { - const HistoricalInfo historicalInfoForUpdate(bigramProperty->getTimestamp(), - bigramProperty->getLevel(), bigramProperty->getCount()); - const HistoricalInfo updatedHistoricalInfo = - ForgettingCurveUtils::createUpdatedHistoricalInfo( - originalBigramEntry->getHistoricalInfo(), bigramProperty->getProbability(), - &historicalInfoForUpdate, mHeaderPolicy); - return originalBigramEntry->updateHistoricalInfoAndGetEntry(&updatedHistoricalInfo); - } else { - return originalBigramEntry->updateProbabilityAndGetEntry(bigramProperty->getProbability()); - } -} - -} // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h deleted file mode 100644 index 4b3bb3725..000000000 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LATINIME_VER4_BIGRAM_LIST_POLICY_H -#define LATINIME_VER4_BIGRAM_LIST_POLICY_H - -#include "defines.h" -#include "suggest/core/policy/dictionary_bigrams_structure_policy.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h" - -namespace latinime { - -class BigramDictContent; -class BigramProperty; -class HeaderPolicy; -class TerminalPositionLookupTable; - -class Ver4BigramListPolicy : public DictionaryBigramsStructurePolicy { - public: - Ver4BigramListPolicy(BigramDictContent *const bigramDictContent, - const TerminalPositionLookupTable *const terminalPositionLookupTable, - const HeaderPolicy *const headerPolicy) - : mBigramDictContent(bigramDictContent), - mTerminalPositionLookupTable(terminalPositionLookupTable), - mHeaderPolicy(headerPolicy) {} - - void getNextBigram(int *const outBigramPos, int *const outProbability, - bool *const outHasNext, int *const bigramEntryPos) const; - - bool skipAllBigrams(int *const pos) const { - // Do nothing because we don't need to skip bigram lists in ver4 dictionaries. - return true; - } - - bool addNewEntry(const int terminalId, const int newTargetTerminalId, - const BigramProperty *const bigramProperty, bool *const outAddedNewEntry); - - bool removeEntry(const int terminalId, const int targetTerminalId); - - bool updateAllBigramEntriesAndDeleteUselessEntries(const int terminalId, - int *const outBigramCount); - - int getBigramEntryConut(const int terminalId); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(Ver4BigramListPolicy); - - int getEntryPosToUpdate(const int targetTerminalIdToFind, const int bigramListPos, - int *const outTailEntryPos) const; - - const BigramEntry createUpdatedBigramEntryFrom(const BigramEntry *const originalBigramEntry, - const BigramProperty *const bigramProperty) const; - - BigramDictContent *const mBigramDictContent; - const TerminalPositionLookupTable *const mTerminalPositionLookupTable; - const HeaderPolicy *const mHeaderPolicy; -}; -} // namespace latinime -#endif /* LATINIME_VER4_BIGRAM_LIST_POLICY_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp deleted file mode 100644 index d7e1952b5..000000000 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h" - -#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" - -namespace latinime { - -const int BigramDictContent::INVALID_LINKED_ENTRY_POS = Ver4DictConstants::NOT_A_TERMINAL_ID; - -const BigramEntry BigramDictContent::getBigramEntryAndAdvancePosition( - int *const bigramEntryPos) const { - const BufferWithExtendableBuffer *const bigramListBuffer = getContentBuffer(); - const int bigramEntryTailPos = (*bigramEntryPos) + getBigramEntrySize(); - if (*bigramEntryPos < 0 || bigramEntryTailPos > bigramListBuffer->getTailPosition()) { - AKLOGE("Invalid bigram entry position. bigramEntryPos: %d, bigramEntryTailPos: %d, " - "bufSize: %d", *bigramEntryPos, bigramEntryTailPos, - bigramListBuffer->getTailPosition()); - ASSERT(false); - return BigramEntry(false /* hasNext */, NOT_A_PROBABILITY, - Ver4DictConstants::NOT_A_TERMINAL_ID); - } - const int bigramFlags = bigramListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, bigramEntryPos); - const bool isLink = (bigramFlags & Ver4DictConstants::BIGRAM_IS_LINK_MASK) != 0; - int probability = NOT_A_PROBABILITY; - int timestamp = NOT_A_TIMESTAMP; - int level = 0; - int count = 0; - if (mHasHistoricalInfo) { - timestamp = bigramListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::TIME_STAMP_FIELD_SIZE, bigramEntryPos); - level = bigramListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, bigramEntryPos); - count = bigramListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::WORD_COUNT_FIELD_SIZE, bigramEntryPos); - } else { - probability = bigramListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::PROBABILITY_SIZE, bigramEntryPos); - } - const int encodedTargetTerminalId = bigramListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, bigramEntryPos); - const int targetTerminalId = - (encodedTargetTerminalId == Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID) ? - Ver4DictConstants::NOT_A_TERMINAL_ID : encodedTargetTerminalId; - if (isLink) { - const int linkedEntryPos = targetTerminalId; - if (linkedEntryPos == INVALID_LINKED_ENTRY_POS) { - // Bigram list terminator is found. - return BigramEntry(false /* hasNext */, NOT_A_PROBABILITY, - Ver4DictConstants::NOT_A_TERMINAL_ID); - } - *bigramEntryPos = linkedEntryPos; - return getBigramEntryAndAdvancePosition(bigramEntryPos); - } - // hasNext is always true because we should continue to read the next entry until the terminator - // is found. - if (mHasHistoricalInfo) { - const HistoricalInfo historicalInfo(timestamp, level, count); - return BigramEntry(true /* hasNext */, probability, &historicalInfo, targetTerminalId); - } else { - return BigramEntry(true /* hasNext */, probability, targetTerminalId); - } -} - -bool BigramDictContent::writeBigramEntryAndAdvancePosition( - const BigramEntry *const bigramEntryToWrite, int *const entryWritingPos) { - return writeBigramEntryAttributesAndAdvancePosition(false /* isLink */, - bigramEntryToWrite->getProbability(), bigramEntryToWrite->getTargetTerminalId(), - bigramEntryToWrite->getHistoricalInfo()->getTimeStamp(), - bigramEntryToWrite->getHistoricalInfo()->getLevel(), - bigramEntryToWrite->getHistoricalInfo()->getCount(), - entryWritingPos); -} - -bool BigramDictContent::writeBigramEntryAttributesAndAdvancePosition( - const bool isLink, const int probability, const int targetTerminalId, - const int timestamp, const int level, const int count, int *const entryWritingPos) { - BufferWithExtendableBuffer *const bigramListBuffer = getWritableContentBuffer(); - const int bigramFlags = isLink ? Ver4DictConstants::BIGRAM_IS_LINK_MASK : 0; - if (!bigramListBuffer->writeUintAndAdvancePosition(bigramFlags, - Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, entryWritingPos)) { - AKLOGE("Cannot write bigram flags. pos: %d, flags: %x", *entryWritingPos, bigramFlags); - return false; - } - if (mHasHistoricalInfo) { - if (!bigramListBuffer->writeUintAndAdvancePosition(timestamp, - Ver4DictConstants::TIME_STAMP_FIELD_SIZE, entryWritingPos)) { - AKLOGE("Cannot write bigram timestamps. pos: %d, timestamp: %d", *entryWritingPos, - timestamp); - return false; - } - if (!bigramListBuffer->writeUintAndAdvancePosition(level, - Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, entryWritingPos)) { - AKLOGE("Cannot write bigram level. pos: %d, level: %d", *entryWritingPos, - level); - return false; - } - if (!bigramListBuffer->writeUintAndAdvancePosition(count, - Ver4DictConstants::WORD_COUNT_FIELD_SIZE, entryWritingPos)) { - AKLOGE("Cannot write bigram count. pos: %d, count: %d", *entryWritingPos, - count); - return false; - } - } else { - if (!bigramListBuffer->writeUintAndAdvancePosition(probability, - Ver4DictConstants::PROBABILITY_SIZE, entryWritingPos)) { - AKLOGE("Cannot write bigram probability. pos: %d, probability: %d", *entryWritingPos, - probability); - return false; - } - } - const int targetTerminalIdToWrite = (targetTerminalId == Ver4DictConstants::NOT_A_TERMINAL_ID) ? - Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID : targetTerminalId; - if (!bigramListBuffer->writeUintAndAdvancePosition(targetTerminalIdToWrite, - Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, entryWritingPos)) { - AKLOGE("Cannot write bigram target terminal id. pos: %d, target terminal id: %d", - *entryWritingPos, targetTerminalId); - return false; - } - return true; -} - -bool BigramDictContent::writeLink(const int linkedEntryPos, const int writingPos) { - const int targetTerminalId = linkedEntryPos; - int pos = writingPos; - return writeBigramEntryAttributesAndAdvancePosition(true /* isLink */, - NOT_A_PROBABILITY /* probability */, targetTerminalId, NOT_A_TIMESTAMP, 0 /* level */, - 0 /* count */, &pos); -} - -bool BigramDictContent::runGC(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, - const BigramDictContent *const originalBigramDictContent, - int *const outBigramEntryCount) { - for (TerminalPositionLookupTable::TerminalIdMap::const_iterator it = terminalIdMap->begin(); - it != terminalIdMap->end(); ++it) { - const int originalBigramListPos = - originalBigramDictContent->getBigramListHeadPos(it->first); - if (originalBigramListPos == NOT_A_DICT_POS) { - // This terminal does not have a bigram list. - continue; - } - const int bigramListPos = getContentBuffer()->getTailPosition(); - int bigramEntryCount = 0; - // Copy bigram list with GC from original content. - if (!runGCBigramList(originalBigramListPos, originalBigramDictContent, bigramListPos, - terminalIdMap, &bigramEntryCount)) { - AKLOGE("Cannot complete GC for the bigram list. original pos: %d, pos: %d", - originalBigramListPos, bigramListPos); - return false; - } - if (bigramEntryCount == 0) { - // All bigram entries are useless. This terminal does not have a bigram list. - continue; - } - *outBigramEntryCount += bigramEntryCount; - // Set bigram list position to the lookup table. - if (!getUpdatableAddressLookupTable()->set(it->second, bigramListPos)) { - AKLOGE("Cannot set bigram list position. terminal id: %d, pos: %d", - it->second, bigramListPos); - return false; - } - } - return true; -} - -// Returns whether GC for the bigram list was succeeded or not. -bool BigramDictContent::runGCBigramList(const int bigramListPos, - const BigramDictContent *const sourceBigramDictContent, const int toPos, - const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, - int *const outEntryCount) { - bool hasNext = true; - int readingPos = bigramListPos; - int writingPos = toPos; - while (hasNext) { - const BigramEntry originalBigramEntry = - sourceBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); - hasNext = originalBigramEntry.hasNext(); - if (!originalBigramEntry.isValid()) { - continue; - } - TerminalPositionLookupTable::TerminalIdMap::const_iterator it = - terminalIdMap->find(originalBigramEntry.getTargetTerminalId()); - if (it == terminalIdMap->end()) { - // Target word has been removed. - continue; - } - const BigramEntry updatedBigramEntry = - originalBigramEntry.updateTargetTerminalIdAndGetEntry(it->second); - if (!writeBigramEntryAndAdvancePosition(&updatedBigramEntry, &writingPos)) { - AKLOGE("Cannot write bigram entry to run GC. pos: %d", writingPos); - return false; - } - *outEntryCount += 1; - } - if (*outEntryCount > 0) { - if (!writeTerminator(writingPos)) { - AKLOGE("Cannot write terminator to run GC. pos: %d", writingPos); - return false; - } - } - return true; -} - -} // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h deleted file mode 100644 index 20bae5943..000000000 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2013, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LATINIME_BIGRAM_DICT_CONTENT_H -#define LATINIME_BIGRAM_DICT_CONTENT_H - -#include <cstdio> - -#include "defines.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h" -#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" - -namespace latinime { - -class ReadWriteByteArrayView; - -class BigramDictContent : public SparseTableDictContent { - public: - BigramDictContent(const ReadWriteByteArrayView *const buffers, const bool hasHistoricalInfo) - : SparseTableDictContent(buffers, Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE, - Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE), - mHasHistoricalInfo(hasHistoricalInfo) {} - - BigramDictContent(const bool hasHistoricalInfo) - : SparseTableDictContent(Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE, - Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE), - mHasHistoricalInfo(hasHistoricalInfo) {} - - int getContentTailPos() const { - return getContentBuffer()->getTailPosition(); - } - - const BigramEntry getBigramEntry(const int bigramEntryPos) const { - int readingPos = bigramEntryPos; - return getBigramEntryAndAdvancePosition(&readingPos); - } - - const BigramEntry getBigramEntryAndAdvancePosition(int *const bigramEntryPos) const; - - // Returns head position of bigram list for a PtNode specified by terminalId. - int getBigramListHeadPos(const int terminalId) const { - const SparseTable *const addressLookupTable = getAddressLookupTable(); - if (!addressLookupTable->contains(terminalId)) { - return NOT_A_DICT_POS; - } - return addressLookupTable->get(terminalId); - } - - bool writeBigramEntryAtTail(const BigramEntry *const bigramEntryToWrite) { - int writingPos = getContentBuffer()->getTailPosition(); - return writeBigramEntryAndAdvancePosition(bigramEntryToWrite, &writingPos); - } - - bool writeBigramEntry(const BigramEntry *const bigramEntryToWrite, const int entryWritingPos) { - int writingPos = entryWritingPos; - return writeBigramEntryAndAdvancePosition(bigramEntryToWrite, &writingPos); - } - - bool writeBigramEntryAndAdvancePosition(const BigramEntry *const bigramEntryToWrite, - int *const entryWritingPos); - - bool writeTerminator(const int writingPos) { - // Terminator is a link to the invalid position. - return writeLink(INVALID_LINKED_ENTRY_POS, writingPos); - } - - bool writeLink(const int linkedPos, const int writingPos); - - bool createNewBigramList(const int terminalId) { - const int bigramListPos = getContentBuffer()->getTailPosition(); - return getUpdatableAddressLookupTable()->set(terminalId, bigramListPos); - } - - bool flushToFile(FILE *const file) const { - return flush(file); - } - - bool runGC(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, - const BigramDictContent *const originalBigramDictContent, - int *const outBigramEntryCount); - - int getBigramEntrySize() const { - if (mHasHistoricalInfo) { - return Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE - + Ver4DictConstants::TIME_STAMP_FIELD_SIZE - + Ver4DictConstants::WORD_LEVEL_FIELD_SIZE - + Ver4DictConstants::WORD_COUNT_FIELD_SIZE - + Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE; - } else { - return Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE - + Ver4DictConstants::PROBABILITY_SIZE - + Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE; - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(BigramDictContent); - - static const int INVALID_LINKED_ENTRY_POS; - - bool writeBigramEntryAttributesAndAdvancePosition( - const bool isLink, const int probability, const int targetTerminalId, - const int timestamp, const int level, const int count, int *const entryWritingPos); - - bool runGCBigramList(const int bigramListPos, - const BigramDictContent *const sourceBigramDictContent, const int toPos, - const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, - int *const outEntryCount); - - bool mHasHistoricalInfo; -}; -} // namespace latinime -#endif /* LATINIME_BIGRAM_DICT_CONTENT_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h deleted file mode 100644 index 2b0cbd93b..000000000 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2013, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LATINIME_BIGRAM_ENTRY_H -#define LATINIME_BIGRAM_ENTRY_H - -#include "defines.h" -#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" -#include "suggest/policyimpl/dictionary/utils/historical_info.h" - -namespace latinime { - -class BigramEntry { - public: - BigramEntry(const BigramEntry& bigramEntry) - : mHasNext(bigramEntry.mHasNext), mProbability(bigramEntry.mProbability), - mHistoricalInfo(), mTargetTerminalId(bigramEntry.mTargetTerminalId) {} - - // Entry with historical information. - BigramEntry(const bool hasNext, const int probability, const int targetTerminalId) - : mHasNext(hasNext), mProbability(probability), mHistoricalInfo(), - mTargetTerminalId(targetTerminalId) {} - - // Entry with historical information. - BigramEntry(const bool hasNext, const int probability, - const HistoricalInfo *const historicalInfo, const int targetTerminalId) - : mHasNext(hasNext), mProbability(probability), mHistoricalInfo(*historicalInfo), - mTargetTerminalId(targetTerminalId) {} - - const BigramEntry getInvalidatedEntry() const { - return updateTargetTerminalIdAndGetEntry(Ver4DictConstants::NOT_A_TERMINAL_ID); - } - - const BigramEntry updateHasNextAndGetEntry(const bool hasNext) const { - return BigramEntry(hasNext, mProbability, &mHistoricalInfo, mTargetTerminalId); - } - - const BigramEntry updateTargetTerminalIdAndGetEntry(const int newTargetTerminalId) const { - return BigramEntry(mHasNext, mProbability, &mHistoricalInfo, newTargetTerminalId); - } - - const BigramEntry updateProbabilityAndGetEntry(const int probability) const { - return BigramEntry(mHasNext, probability, &mHistoricalInfo, mTargetTerminalId); - } - - const BigramEntry updateHistoricalInfoAndGetEntry( - const HistoricalInfo *const historicalInfo) const { - return BigramEntry(mHasNext, mProbability, historicalInfo, mTargetTerminalId); - } - - bool isValid() const { - return mTargetTerminalId != Ver4DictConstants::NOT_A_TERMINAL_ID; - } - - bool hasNext() const { - return mHasNext; - } - - int getProbability() const { - return mProbability; - } - - bool hasHistoricalInfo() const { - return mHistoricalInfo.isValid(); - } - - const HistoricalInfo *getHistoricalInfo() const { - return &mHistoricalInfo; - } - - int getTargetTerminalId() const { - return mTargetTerminalId; - } - - private: - // Copy constructor is public to use this class as a type of return value. - DISALLOW_DEFAULT_CONSTRUCTOR(BigramEntry); - DISALLOW_ASSIGNMENT_OPERATOR(BigramEntry); - - const bool mHasNext; - const int mProbability; - const HistoricalInfo mHistoricalInfo; - const int mTargetTerminalId; -}; -} // namespace latinime -#endif /* LATINIME_BIGRAM_ENTRY_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp index ea2d24e67..d5749e9eb 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp @@ -23,6 +23,9 @@ namespace latinime { +const int LanguageModelDictContent::UNIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE = 0; +const int LanguageModelDictContent::BIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE = 1; + bool LanguageModelDictContent::save(FILE *const file) const { return mTrieMap.save(file); } @@ -71,13 +74,22 @@ bool LanguageModelDictContent::removeNgramProbabilityEntry(const WordIdArrayView return mTrieMap.remove(wordId, bitmapEntryIndex); } +LanguageModelDictContent::EntryRange LanguageModelDictContent::getProbabilityEntries( + const WordIdArrayView prevWordIds) const { + const int bitmapEntryIndex = getBitmapEntryIndex(prevWordIds); + return EntryRange(mTrieMap.getEntriesInSpecifiedLevel(bitmapEntryIndex), mHasHistoricalInfo); +} + bool LanguageModelDictContent::truncateEntries(const int *const entryCounts, - const int *const maxEntryCounts, const HeaderPolicy *const headerPolicy) { + const int *const maxEntryCounts, const HeaderPolicy *const headerPolicy, + int *const outEntryCounts) { for (int i = 0; i <= MAX_PREV_WORD_COUNT_FOR_N_GRAM; ++i) { if (entryCounts[i] <= maxEntryCounts[i]) { + outEntryCounts[i] = entryCounts[i]; continue; } - if (!turncateEntriesInSpecifiedLevel(headerPolicy, maxEntryCounts[i], i)) { + if (!turncateEntriesInSpecifiedLevel(headerPolicy, maxEntryCounts[i], i, + &outEntryCounts[i])) { return false; } } @@ -179,7 +191,8 @@ bool LanguageModelDictContent::updateAllProbabilityEntriesInner(const int bitmap } bool LanguageModelDictContent::turncateEntriesInSpecifiedLevel( - const HeaderPolicy *const headerPolicy, const int maxEntryCount, const int targetLevel) { + const HeaderPolicy *const headerPolicy, const int maxEntryCount, const int targetLevel, + int *const outEntryCount) { std::vector<int> prevWordIds; std::vector<EntryInfoToTurncate> entryInfoVector; if (!getEntryInfo(headerPolicy, targetLevel, mTrieMap.getRootBitmapEntryIndex(), @@ -187,8 +200,10 @@ bool LanguageModelDictContent::turncateEntriesInSpecifiedLevel( return false; } if (static_cast<int>(entryInfoVector.size()) <= maxEntryCount) { + *outEntryCount = static_cast<int>(entryInfoVector.size()); return true; } + *outEntryCount = maxEntryCount; const int entryCountToRemove = static_cast<int>(entryInfoVector.size()) - maxEntryCount; std::partial_sort(entryInfoVector.begin(), entryInfoVector.begin() + entryCountToRemove, entryInfoVector.end(), diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h index 43b2aab66..aa612e35a 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h @@ -39,6 +39,78 @@ class HeaderPolicy; */ class LanguageModelDictContent { public: + static const int UNIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE; + static const int BIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE; + + // Pair of word id and probability entry used for iteration. + class WordIdAndProbabilityEntry { + public: + WordIdAndProbabilityEntry(const int wordId, const ProbabilityEntry &probabilityEntry) + : mWordId(wordId), mProbabilityEntry(probabilityEntry) {} + + int getWordId() const { return mWordId; } + const ProbabilityEntry getProbabilityEntry() const { return mProbabilityEntry; } + + private: + DISALLOW_DEFAULT_CONSTRUCTOR(WordIdAndProbabilityEntry); + DISALLOW_ASSIGNMENT_OPERATOR(WordIdAndProbabilityEntry); + + const int mWordId; + const ProbabilityEntry mProbabilityEntry; + }; + + // Iterator. + class EntryIterator { + public: + EntryIterator(const TrieMap::TrieMapIterator &trieMapIterator, + const bool hasHistoricalInfo) + : mTrieMapIterator(trieMapIterator), mHasHistoricalInfo(hasHistoricalInfo) {} + + const WordIdAndProbabilityEntry operator*() const { + const TrieMap::TrieMapIterator::IterationResult &result = *mTrieMapIterator; + return WordIdAndProbabilityEntry( + result.key(), ProbabilityEntry::decode(result.value(), mHasHistoricalInfo)); + } + + bool operator!=(const EntryIterator &other) const { + return mTrieMapIterator != other.mTrieMapIterator; + } + + const EntryIterator &operator++() { + ++mTrieMapIterator; + return *this; + } + + private: + DISALLOW_DEFAULT_CONSTRUCTOR(EntryIterator); + DISALLOW_ASSIGNMENT_OPERATOR(EntryIterator); + + TrieMap::TrieMapIterator mTrieMapIterator; + const bool mHasHistoricalInfo; + }; + + // Class represents range to use range base for loops. + class EntryRange { + public: + EntryRange(const TrieMap::TrieMapRange trieMapRange, const bool hasHistoricalInfo) + : mTrieMapRange(trieMapRange), mHasHistoricalInfo(hasHistoricalInfo) {} + + EntryIterator begin() const { + return EntryIterator(mTrieMapRange.begin(), mHasHistoricalInfo); + } + + EntryIterator end() const { + return EntryIterator(mTrieMapRange.end(), mHasHistoricalInfo); + } + + private: + DISALLOW_DEFAULT_CONSTRUCTOR(EntryRange); + DISALLOW_ASSIGNMENT_OPERATOR(EntryRange); + + const TrieMap::TrieMapRange mTrieMapRange; + const bool mHasHistoricalInfo; + }; + LanguageModelDictContent(const ReadWriteByteArrayView trieMapBuffer, const bool hasHistoricalInfo) : mTrieMap(trieMapBuffer), mHasHistoricalInfo(hasHistoricalInfo) {} @@ -76,6 +148,8 @@ class LanguageModelDictContent { bool removeNgramProbabilityEntry(const WordIdArrayView prevWordIds, const int wordId); + EntryRange getProbabilityEntries(const WordIdArrayView prevWordIds) const; + bool updateAllProbabilityEntries(const HeaderPolicy *const headerPolicy, int *const outEntryCounts) { for (int i = 0; i <= MAX_PREV_WORD_COUNT_FOR_N_GRAM; ++i) { @@ -87,7 +161,7 @@ class LanguageModelDictContent { // entryCounts should be created by updateAllProbabilityEntries. bool truncateEntries(const int *const entryCounts, const int *const maxEntryCounts, - const HeaderPolicy *const headerPolicy); + const HeaderPolicy *const headerPolicy, int *const outEntryCounts); private: DISALLOW_COPY_AND_ASSIGN(LanguageModelDictContent); @@ -126,7 +200,7 @@ class LanguageModelDictContent { bool updateAllProbabilityEntriesInner(const int bitmapEntryIndex, const int level, const HeaderPolicy *const headerPolicy, int *const outEntryCounts); bool turncateEntriesInSpecifiedLevel(const HeaderPolicy *const headerPolicy, - const int maxEntryCount, const int targetLevel); + const int maxEntryCount, const int targetLevel, int *const outEntryCount); bool getEntryInfo(const HeaderPolicy *const headerPolicy, const int targetLevel, const int bitmapEntryIndex, std::vector<int> *const prevWordIds, std::vector<EntryInfoToTurncate> *const outEntryInfo) const; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp index 1f40e3dd2..45f88e9b2 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp @@ -159,11 +159,6 @@ bool Ver4DictBuffers::flushDictBuffers(FILE *const file) const { AKLOGE("Language model dict content cannot be written."); return false; } - // Write bigram dict content. - if (!mBigramDictContent.flushToFile(file)) { - AKLOGE("Bigram dict content cannot be written."); - return false; - } // Write shortcut dict content. if (!mShortcutDictContent.flushToFile(file)) { AKLOGE("Shortcut dict content cannot be written."); @@ -186,8 +181,6 @@ Ver4DictBuffers::Ver4DictBuffers(MmappedBuffer::MmappedBufferPtr &&headerBuffer, contentBuffers[Ver4DictConstants::TERMINAL_ADDRESS_LOOKUP_TABLE_BUFFER_INDEX]), mLanguageModelDictContent(contentBuffers[Ver4DictConstants::LANGUAGE_MODEL_BUFFER_INDEX], mHeaderPolicy.hasHistoricalInfoOfWords()), - mBigramDictContent(&contentBuffers[Ver4DictConstants::BIGRAM_BUFFERS_INDEX], - mHeaderPolicy.hasHistoricalInfoOfWords()), mShortcutDictContent(&contentBuffers[Ver4DictConstants::SHORTCUT_BUFFERS_INDEX]), mIsUpdatable(mDictBuffer->isUpdatable()) {} @@ -196,7 +189,6 @@ Ver4DictBuffers::Ver4DictBuffers(const HeaderPolicy *const headerPolicy, const i mExpandableHeaderBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE), mExpandableTrieBuffer(maxTrieSize), mTerminalPositionLookupTable(), mLanguageModelDictContent(headerPolicy->hasHistoricalInfoOfWords()), - mBigramDictContent(headerPolicy->hasHistoricalInfoOfWords()), mShortcutDictContent(), - mIsUpdatable(true) {} + mShortcutDictContent(), mIsUpdatable(true) {} } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h index 70a7983f1..5407525af 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h @@ -22,7 +22,6 @@ #include "defines.h" #include "suggest/policyimpl/dictionary/header/header_policy.h" -#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h" #include "suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h" #include "suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h" #include "suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h" @@ -53,7 +52,6 @@ class Ver4DictBuffers { return mExpandableTrieBuffer.isNearSizeLimit() || mTerminalPositionLookupTable.isNearSizeLimit() || mLanguageModelDictContent.isNearSizeLimit() - || mBigramDictContent.isNearSizeLimit() || mShortcutDictContent.isNearSizeLimit(); } @@ -89,14 +87,6 @@ class Ver4DictBuffers { return &mLanguageModelDictContent; } - AK_FORCE_INLINE BigramDictContent *getMutableBigramDictContent() { - return &mBigramDictContent; - } - - AK_FORCE_INLINE const BigramDictContent *getBigramDictContent() const { - return &mBigramDictContent; - } - AK_FORCE_INLINE ShortcutDictContent *getMutableShortcutDictContent() { return &mShortcutDictContent; } @@ -135,7 +125,6 @@ class Ver4DictBuffers { BufferWithExtendableBuffer mExpandableTrieBuffer; TerminalPositionLookupTable mTerminalPositionLookupTable; LanguageModelDictContent mLanguageModelDictContent; - BigramDictContent mBigramDictContent; ShortcutDictContent mShortcutDictContent; const int mIsUpdatable; }; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp index b085a6661..9acf2d44f 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp @@ -29,20 +29,18 @@ const int Ver4DictConstants::MAX_DICT_EXTENDED_REGION_SIZE = 1 * 1024 * 1024; // NUM_OF_BUFFERS_FOR_SINGLE_DICT_CONTENT for Trie and TerminalAddressLookupTable. // NUM_OF_BUFFERS_FOR_LANGUAGE_MODEL_DICT_CONTENT for language model. -// NUM_OF_BUFFERS_FOR_SPARSE_TABLE_DICT_CONTENT for bigram and shortcut. +// NUM_OF_BUFFERS_FOR_SPARSE_TABLE_DICT_CONTENT for shortcut. const size_t Ver4DictConstants::NUM_OF_CONTENT_BUFFERS_IN_BODY_FILE = NUM_OF_BUFFERS_FOR_SINGLE_DICT_CONTENT * 2 + NUM_OF_BUFFERS_FOR_LANGUAGE_MODEL_DICT_CONTENT - + NUM_OF_BUFFERS_FOR_SPARSE_TABLE_DICT_CONTENT * 2; + + NUM_OF_BUFFERS_FOR_SPARSE_TABLE_DICT_CONTENT; const int Ver4DictConstants::TRIE_BUFFER_INDEX = 0; const int Ver4DictConstants::TERMINAL_ADDRESS_LOOKUP_TABLE_BUFFER_INDEX = TRIE_BUFFER_INDEX + NUM_OF_BUFFERS_FOR_SINGLE_DICT_CONTENT; const int Ver4DictConstants::LANGUAGE_MODEL_BUFFER_INDEX = TERMINAL_ADDRESS_LOOKUP_TABLE_BUFFER_INDEX + NUM_OF_BUFFERS_FOR_SINGLE_DICT_CONTENT; -const int Ver4DictConstants::BIGRAM_BUFFERS_INDEX = - LANGUAGE_MODEL_BUFFER_INDEX + NUM_OF_BUFFERS_FOR_LANGUAGE_MODEL_DICT_CONTENT; const int Ver4DictConstants::SHORTCUT_BUFFERS_INDEX = - BIGRAM_BUFFERS_INDEX + NUM_OF_BUFFERS_FOR_SPARSE_TABLE_DICT_CONTENT; + LANGUAGE_MODEL_BUFFER_INDEX + NUM_OF_BUFFERS_FOR_LANGUAGE_MODEL_DICT_CONTENT; const int Ver4DictConstants::NOT_A_TERMINAL_ID = -1; const int Ver4DictConstants::PROBABILITY_SIZE = 1; @@ -56,21 +54,9 @@ const int Ver4DictConstants::WORD_COUNT_FIELD_SIZE = 1; const uint8_t Ver4DictConstants::FLAG_REPRESENTS_BEGINNING_OF_SENTENCE = 0x1; -const int Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE = 16; -const int Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE = 4; const int Ver4DictConstants::SHORTCUT_ADDRESS_TABLE_BLOCK_SIZE = 64; const int Ver4DictConstants::SHORTCUT_ADDRESS_TABLE_DATA_SIZE = 4; -const int Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE = 3; -// Unsigned int max value of BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE-byte is used for representing -// invalid terminal ID in bigram lists. -const int Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID = - (1 << (BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE * 8)) - 1; -const int Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE = 1; -const int Ver4DictConstants::BIGRAM_PROBABILITY_MASK = 0x0F; -const int Ver4DictConstants::BIGRAM_IS_LINK_MASK = 0x80; -const int Ver4DictConstants::BIGRAM_LARGE_PROBABILITY_FIELD_SIZE = 1; - const int Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE = 1; const int Ver4DictConstants::SHORTCUT_PROBABILITY_MASK = 0x0F; const int Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK = 0x80; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h index 230b3052d..97035311e 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h @@ -52,19 +52,9 @@ class Ver4DictConstants { // Flags in probability entry. static const uint8_t FLAG_REPRESENTS_BEGINNING_OF_SENTENCE; - static const int BIGRAM_ADDRESS_TABLE_BLOCK_SIZE; - static const int BIGRAM_ADDRESS_TABLE_DATA_SIZE; static const int SHORTCUT_ADDRESS_TABLE_BLOCK_SIZE; static const int SHORTCUT_ADDRESS_TABLE_DATA_SIZE; - static const int BIGRAM_FLAGS_FIELD_SIZE; - static const int BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE; - static const int INVALID_BIGRAM_TARGET_TERMINAL_ID; - static const int BIGRAM_IS_LINK_MASK; - static const int BIGRAM_PROBABILITY_MASK; - // Used when bigram list has time stamp. - static const int BIGRAM_LARGE_PROBABILITY_FIELD_SIZE; - static const int SHORTCUT_FLAGS_FIELD_SIZE; static const int SHORTCUT_PROBABILITY_MASK; static const int SHORTCUT_HAS_NEXT_MASK; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp index b7c31bf75..9ca712470 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp @@ -21,7 +21,6 @@ #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h" #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.h" #include "suggest/policyimpl/dictionary/structure/pt_common/patricia_trie_reading_utils.h" -#include "suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h" #include "suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h" #include "suggest/policyimpl/dictionary/structure/v4/shortcut/ver4_shortcut_list_policy.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h" @@ -230,12 +229,6 @@ bool Ver4PatriciaTrieNodeWriter::addNgramEntry(const WordIdArrayView prevWordIds if (!probabilityEntry.isValid() && outAddedNewBigram) { *outAddedNewBigram = true; } - // TODO: Remove. - if (!mBigramPolicy->addNewEntry(prevWordIds[0], wordId, bigramProperty, outAddedNewBigram)) { - AKLOGE("Cannot add new bigram entry. prevWordId: %d, wordId: %d", - prevWordIds[0], wordId); - return false; - } return true; } @@ -244,19 +237,15 @@ bool Ver4PatriciaTrieNodeWriter::removeNgramEntry(const WordIdArrayView prevWord // TODO: Support n-gram. LanguageModelDictContent *const languageModelDictContent = mBuffers->getMutableLanguageModelDictContent(); - if (!languageModelDictContent->removeNgramProbabilityEntry(prevWordIds.limit(1 /* maxSize */), - wordId)) { - // TODO: Uncomment. - // return false; - } - // TODO: Remove. - return mBigramPolicy->removeEntry(prevWordIds[0], wordId); + return languageModelDictContent->removeNgramProbabilityEntry(prevWordIds.limit(1 /* maxSize */), + wordId); } +// TODO: Remove when we stop supporting v402 format. bool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries( const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount) { - return mBigramPolicy->updateAllBigramEntriesAndDeleteUselessEntries( - sourcePtNodeParams->getTerminalId(), outBigramEntryCount); + // Do nothing. + return true; } bool Ver4PatriciaTrieNodeWriter::updateAllPositionFields( @@ -291,12 +280,6 @@ bool Ver4PatriciaTrieNodeWriter::updateAllPositionFields( if (!updateChildrenPosition(toBeUpdatedPtNodeParams, childrenPos)) { return false; } - - // Counts bigram entries. - if (outBigramEntryCount) { - *outBigramEntryCount = mBigramPolicy->getBigramEntryConut( - toBeUpdatedPtNodeParams->getTerminalId()); - } return true; } diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h index 5d73b6ea3..08b7d3825 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h @@ -27,7 +27,6 @@ namespace latinime { class BufferWithExtendableBuffer; class HeaderPolicy; -class Ver4BigramListPolicy; class Ver4DictBuffers; class Ver4PatriciaTrieNodeReader; class Ver4PtNodeArrayReader; @@ -42,10 +41,9 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter { Ver4DictBuffers *const buffers, const HeaderPolicy *const headerPolicy, const PtNodeReader *const ptNodeReader, const PtNodeArrayReader *const ptNodeArrayReader, - Ver4BigramListPolicy *const bigramPolicy, Ver4ShortcutListPolicy *const shortcutPolicy) + Ver4ShortcutListPolicy *const shortcutPolicy) : mTrieBuffer(trieBuffer), mBuffers(buffers), mHeaderPolicy(headerPolicy), - mReadingHelper(ptNodeReader, ptNodeArrayReader), mBigramPolicy(bigramPolicy), - mShortcutPolicy(shortcutPolicy) {} + mReadingHelper(ptNodeReader, ptNodeArrayReader), mShortcutPolicy(shortcutPolicy) {} virtual ~Ver4PatriciaTrieNodeWriter() {} @@ -114,7 +112,6 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter { Ver4DictBuffers *const mBuffers; const HeaderPolicy *const mHeaderPolicy; DynamicPtReadingHelper mReadingHelper; - Ver4BigramListPolicy *const mBigramPolicy; Ver4ShortcutListPolicy *const mShortcutPolicy; }; } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp index 2ea248e86..619cdb59b 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp @@ -66,8 +66,9 @@ void Ver4PatriciaTriePolicy::createAndGetAllChildDicNodes(const DicNode *const d // Skip PtNodes that represent non-word information. continue; } + const int wordId = isTerminal ? ptNodeParams.getTerminalId() : NOT_A_WORD_ID; childDicNodes->pushLeavingChild(dicNode, ptNodeParams.getHeadPos(), - ptNodeParams.getChildrenPos(), ptNodeParams.getProbability(), isTerminal, + ptNodeParams.getChildrenPos(), ptNodeParams.getProbability(), wordId, ptNodeParams.hasChildren(), ptNodeParams.isBlacklisted() || ptNodeParams.isNotAWord() /* isBlacklistedOrNotAWord */, @@ -93,12 +94,12 @@ int Ver4PatriciaTriePolicy::getCodePointsAndProbabilityAndReturnCodePointCount( return codePointCount; } -int Ver4PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const { +int Ver4PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const { DynamicPtReadingHelper readingHelper(&mNodeReader, &mPtNodeArrayReader); readingHelper.initWithPtNodeArrayPos(getRootPosition()); - const int ptNodePos = - readingHelper.getTerminalPtNodePositionOfWord(inWord, length, forceLowerCaseSearch); + const int ptNodePos = readingHelper.getTerminalPtNodePositionOfWord(wordCodePoints.data(), + wordCodePoints.size(), forceLowerCaseSearch); if (readingHelper.isError()) { mIsCorrupted = true; AKLOGE("Dictionary reading error in createAndGetAllChildDicNodes()."); @@ -158,11 +159,21 @@ void Ver4PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordsPtNod if (!prevWordsPtNodePos) { return; } - const int bigramsPosition = getBigramsPositionOfPtNode(prevWordsPtNodePos[0]); - BinaryDictionaryBigramsIterator bigramsIt(&mBigramPolicy, bigramsPosition); - while (bigramsIt.hasNext()) { - bigramsIt.next(); - listener->onVisitEntry(bigramsIt.getProbability(), bigramsIt.getBigramPos()); + // TODO: Support n-gram. + const PtNodeParams ptNodeParams = + mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(prevWordsPtNodePos[0]); + const int prevWordId = ptNodeParams.getTerminalId(); + const WordIdArrayView prevWordIds = WordIdArrayView::fromObject(&prevWordId); + const auto languageModelDictContent = mBuffers->getLanguageModelDictContent(); + for (const auto entry : languageModelDictContent->getProbabilityEntries(prevWordIds)) { + const ProbabilityEntry &probabilityEntry = entry.getProbabilityEntry(); + const int probability = probabilityEntry.hasHistoricalInfo() ? + ForgettingCurveUtils::decodeProbability( + probabilityEntry.getHistoricalInfo(), mHeaderPolicy) : + probabilityEntry.getProbability(); + const int ptNodePos = mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition( + entry.getWordId()); + listener->onVisitEntry(probability, ptNodePos); } } @@ -178,19 +189,7 @@ int Ver4PatriciaTriePolicy::getShortcutPositionOfPtNode(const int ptNodePos) con ptNodeParams.getTerminalId()); } -int Ver4PatriciaTriePolicy::getBigramsPositionOfPtNode(const int ptNodePos) const { - if (ptNodePos == NOT_A_DICT_POS) { - return NOT_A_DICT_POS; - } - const PtNodeParams ptNodeParams(mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos)); - if (ptNodeParams.isDeleted()) { - return NOT_A_DICT_POS; - } - return mBuffers->getBigramDictContent()->getBigramListHeadPos( - ptNodeParams.getTerminalId()); -} - -bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int length, +bool Ver4PatriciaTriePolicy::addUnigramEntry(const CodePointArrayView wordCodePoints, const UnigramProperty *const unigramProperty) { if (!mBuffers->isUpdatable()) { AKLOGI("Warning: addUnigramEntry() is called for non-updatable dictionary."); @@ -201,8 +200,9 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le mDictBuffer->getTailPosition()); return false; } - if (length > MAX_WORD_LENGTH) { - AKLOGE("The word is too long to insert to the dictionary, length: %d", length); + if (wordCodePoints.size() > MAX_WORD_LENGTH) { + AKLOGE("The word is too long to insert to the dictionary, length: %zd", + wordCodePoints.size()); return false; } for (const auto &shortcut : unigramProperty->getShortcuts()) { @@ -216,8 +216,8 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le readingHelper.initWithPtNodeArrayPos(getRootPosition()); bool addedNewUnigram = false; int codePointsToAdd[MAX_WORD_LENGTH]; - int codePointCountToAdd = length; - memmove(codePointsToAdd, word, sizeof(int) * length); + int codePointCountToAdd = wordCodePoints.size(); + memmove(codePointsToAdd, wordCodePoints.data(), sizeof(int) * codePointCountToAdd); if (unigramProperty->representsBeginningOfSentence()) { codePointCountToAdd = CharUtils::attachBeginningOfSentenceMarker(codePointsToAdd, codePointCountToAdd, MAX_WORD_LENGTH); @@ -225,14 +225,15 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le if (codePointCountToAdd <= 0) { return false; } - if (mUpdatingHelper.addUnigramWord(&readingHelper, codePointsToAdd, codePointCountToAdd, - unigramProperty, &addedNewUnigram)) { + const CodePointArrayView codePointArrayView(codePointsToAdd, codePointCountToAdd); + if (mUpdatingHelper.addUnigramWord(&readingHelper, codePointArrayView.data(), + codePointArrayView.size(), unigramProperty, &addedNewUnigram)) { if (addedNewUnigram && !unigramProperty->representsBeginningOfSentence()) { mUnigramCount++; } if (unigramProperty->getShortcuts().size() > 0) { // Add shortcut target. - const int wordPos = getTerminalPtNodePositionOfWord(word, length, + const int wordPos = getTerminalPtNodePositionOfWord(codePointArrayView, false /* forceLowerCaseSearch */); if (wordPos == NOT_A_DICT_POS) { AKLOGE("Cannot find terminal PtNode position to add shortcut target."); @@ -255,12 +256,12 @@ bool Ver4PatriciaTriePolicy::addUnigramEntry(const int *const word, const int le } } -bool Ver4PatriciaTriePolicy::removeUnigramEntry(const int *const word, const int length) { +bool Ver4PatriciaTriePolicy::removeUnigramEntry(const CodePointArrayView wordCodePoints) { if (!mBuffers->isUpdatable()) { AKLOGI("Warning: removeUnigramEntry() is called for non-updatable dictionary."); return false; } - const int ptNodePos = getTerminalPtNodePositionOfWord(word, length, + const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (ptNodePos == NOT_A_DICT_POS) { return false; @@ -314,7 +315,6 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI false /* isBlacklisted */, MAX_PROBABILITY /* probability */, NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */, &shortcuts); if (!addUnigramEntry(prevWordsInfo->getNthPrevWordCodePoints(1 /* n */), - prevWordsInfo->getNthPrevWordCodePointCount(1 /* n */), &beginningOfSentenceUnigramProperty)) { AKLOGE("Cannot add unigram entry for the beginning-of-sentence."); return false; @@ -327,8 +327,8 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI } } const int word1Pos = getTerminalPtNodePositionOfWord( - bigramProperty->getTargetCodePoints()->data(), - bigramProperty->getTargetCodePoints()->size(), false /* forceLowerCaseSearch */); + CodePointArrayView(*bigramProperty->getTargetCodePoints()), + false /* forceLowerCaseSearch */); if (word1Pos == NOT_A_DICT_POS) { return false; } @@ -345,7 +345,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI } bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, - const int *const word, const int length) { + const CodePointArrayView wordCodePoints) { if (!mBuffers->isUpdatable()) { AKLOGI("Warning: removeNgramEntry() is called for non-updatable dictionary."); return false; @@ -359,8 +359,9 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor AKLOGE("prev words info is not valid for removing n-gram entry form the dictionary."); return false; } - if (length > MAX_WORD_LENGTH) { - AKLOGE("word is too long to remove n-gram entry form the dictionary. length: %d", length); + if (wordCodePoints.size() > MAX_WORD_LENGTH) { + AKLOGE("word is too long to remove n-gram entry form the dictionary. length: %zd", + wordCodePoints.size()); } int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM]; prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos, @@ -370,7 +371,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) { return false; } - const int wordPos = getTerminalPtNodePositionOfWord(word, length, + const int wordPos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (wordPos == NOT_A_DICT_POS) { return false; @@ -454,9 +455,9 @@ void Ver4PatriciaTriePolicy::getProperty(const char *const query, const int quer } } -const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const codePoints, - const int codePointCount) const { - const int ptNodePos = getTerminalPtNodePositionOfWord(codePoints, codePointCount, +const WordProperty Ver4PatriciaTriePolicy::getWordProperty( + const CodePointArrayView wordCodePoints) const { + const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints, false /* forceLowerCaseSearch */); if (ptNodePos == NOT_A_DICT_POS) { AKLOGE("getWordProperty is called for invalid word."); @@ -470,41 +471,32 @@ const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const code ptNodeParams.getTerminalId()); const HistoricalInfo *const historicalInfo = probabilityEntry.getHistoricalInfo(); // Fetch bigram information. + // TODO: Support n-gram. std::vector<BigramProperty> bigrams; - const int bigramListPos = getBigramsPositionOfPtNode(ptNodePos); - if (bigramListPos != NOT_A_DICT_POS) { - int bigramWord1CodePoints[MAX_WORD_LENGTH]; - const BigramDictContent *const bigramDictContent = mBuffers->getBigramDictContent(); - const TerminalPositionLookupTable *const terminalPositionLookupTable = - mBuffers->getTerminalPositionLookupTable(); - bool hasNext = true; - int readingPos = bigramListPos; - while (hasNext) { - const BigramEntry bigramEntry = - bigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); - hasNext = bigramEntry.hasNext(); - const int word1TerminalId = bigramEntry.getTargetTerminalId(); - const int word1TerminalPtNodePos = - terminalPositionLookupTable->getTerminalPtNodePosition(word1TerminalId); - if (word1TerminalPtNodePos == NOT_A_DICT_POS) { - continue; - } - // Word (unigram) probability - int word1Probability = NOT_A_PROBABILITY; - const int codePointCount = getCodePointsAndProbabilityAndReturnCodePointCount( - word1TerminalPtNodePos, MAX_WORD_LENGTH, bigramWord1CodePoints, - &word1Probability); - const std::vector<int> word1(bigramWord1CodePoints, - bigramWord1CodePoints + codePointCount); - const HistoricalInfo *const historicalInfo = bigramEntry.getHistoricalInfo(); - const int probability = bigramEntry.hasHistoricalInfo() ? - ForgettingCurveUtils::decodeProbability( - bigramEntry.getHistoricalInfo(), mHeaderPolicy) : - bigramEntry.getProbability(); - bigrams.emplace_back(&word1, probability, - historicalInfo->getTimeStamp(), historicalInfo->getLevel(), - historicalInfo->getCount()); - } + const int wordId = ptNodeParams.getTerminalId(); + const WordIdArrayView prevWordIds = WordIdArrayView::fromObject(&wordId); + const TerminalPositionLookupTable *const terminalPositionLookupTable = + mBuffers->getTerminalPositionLookupTable(); + int bigramWord1CodePoints[MAX_WORD_LENGTH]; + for (const auto entry : mBuffers->getLanguageModelDictContent()->getProbabilityEntries( + prevWordIds)) { + const int word1TerminalPtNodePos = + terminalPositionLookupTable->getTerminalPtNodePosition(entry.getWordId()); + // Word (unigram) probability + int word1Probability = NOT_A_PROBABILITY; + const int codePointCount = getCodePointsAndProbabilityAndReturnCodePointCount( + word1TerminalPtNodePos, MAX_WORD_LENGTH, bigramWord1CodePoints, + &word1Probability); + const std::vector<int> word1(bigramWord1CodePoints, + bigramWord1CodePoints + codePointCount); + const ProbabilityEntry probabilityEntry = entry.getProbabilityEntry(); + const HistoricalInfo *const historicalInfo = probabilityEntry.getHistoricalInfo(); + const int probability = probabilityEntry.hasHistoricalInfo() ? + ForgettingCurveUtils::decodeProbability(historicalInfo, mHeaderPolicy) : + probabilityEntry.getProbability(); + bigrams.emplace_back(&word1, probability, + historicalInfo->getTimeStamp(), historicalInfo->getLevel(), + historicalInfo->getCount()); } // Fetch shortcut information. std::vector<UnigramProperty::ShortcutProperty> shortcuts; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h index faad4290d..24f92a4aa 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h @@ -23,7 +23,6 @@ #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h" #include "suggest/policyimpl/dictionary/header/header_policy.h" #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h" -#include "suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h" #include "suggest/policyimpl/dictionary/structure/v4/shortcut/ver4_shortcut_list_policy.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h" @@ -31,25 +30,25 @@ #include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_pt_node_array_reader.h" #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" +#include "utils/int_array_view.h" namespace latinime { class DicNode; class DicNodeVector; +// Word id = Artificial id that is stored in the PtNode looked up by the word. class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { public: Ver4PatriciaTriePolicy(Ver4DictBuffers::Ver4DictBuffersPtr buffers) : mBuffers(std::move(buffers)), mHeaderPolicy(mBuffers->getHeaderPolicy()), mDictBuffer(mBuffers->getWritableTrieBuffer()), - mBigramPolicy(mBuffers->getMutableBigramDictContent(), - mBuffers->getTerminalPositionLookupTable(), mHeaderPolicy), mShortcutPolicy(mBuffers->getMutableShortcutDictContent(), mBuffers->getTerminalPositionLookupTable()), mNodeReader(mDictBuffer, mBuffers->getLanguageModelDictContent(), mHeaderPolicy), mPtNodeArrayReader(mDictBuffer), mNodeWriter(mDictBuffer, mBuffers.get(), mHeaderPolicy, &mNodeReader, - &mPtNodeArrayReader, &mBigramPolicy, &mShortcutPolicy), + &mPtNodeArrayReader, &mShortcutPolicy), mUpdatingHelper(mDictBuffer, &mNodeReader, &mNodeWriter), mWritingHelper(mBuffers.get()), mUnigramCount(mHeaderPolicy->getUnigramCount()), @@ -67,8 +66,8 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { const int terminalPtNodePos, const int maxCodePointCount, int *const outCodePoints, int *const outUnigramProbability) const; - int getTerminalPtNodePositionOfWord(const int *const inWord, - const int length, const bool forceLowerCaseSearch) const; + int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints, + const bool forceLowerCaseSearch) const; int getProbability(const int unigramProbability, const int bigramProbability) const; @@ -87,16 +86,16 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { return &mShortcutPolicy; } - bool addUnigramEntry(const int *const word, const int length, + bool addUnigramEntry(const CodePointArrayView wordCodePoints, const UnigramProperty *const unigramProperty); - bool removeUnigramEntry(const int *const word, const int length); + bool removeUnigramEntry(const CodePointArrayView wordCodePoints); bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo, const BigramProperty *const bigramProperty); - bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, const int *const word1, - const int length1); + bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo, + const CodePointArrayView wordCodePoints); bool flush(const char *const filePath); @@ -107,8 +106,7 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { void getProperty(const char *const query, const int queryLength, char *const outResult, const int maxResultLength); - const WordProperty getWordProperty(const int *const codePoints, - const int codePointCount) const; + const WordProperty getWordProperty(const CodePointArrayView wordCodePoints) const; int getNextWordAndNextToken(const int token, int *const outCodePoints, int *const outCodePointCount); @@ -132,7 +130,6 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { const Ver4DictBuffers::Ver4DictBuffersPtr mBuffers; const HeaderPolicy *const mHeaderPolicy; BufferWithExtendableBuffer *const mDictBuffer; - Ver4BigramListPolicy mBigramPolicy; Ver4ShortcutListPolicy mShortcutPolicy; Ver4PatriciaTrieNodeReader mNodeReader; Ver4PtNodeArrayReader mPtNodeArrayReader; @@ -143,8 +140,6 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { int mBigramCount; std::vector<int> mTerminalPtNodePositionsForIteratingWords; mutable bool mIsCorrupted; - - int getBigramsPositionOfPtNode(const int ptNodePos) const; }; } // namespace latinime #endif // LATINIME_VER4_PATRICIA_TRIE_POLICY_H diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp index d53575aa7..63e43a544 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp @@ -20,7 +20,6 @@ #include <queue> #include "suggest/policyimpl/dictionary/header/header_policy.h" -#include "suggest/policyimpl/dictionary/structure/v4/bigram/ver4_bigram_list_policy.h" #include "suggest/policyimpl/dictionary/structure/v4/shortcut/ver4_shortcut_list_policy.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" @@ -77,13 +76,10 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, Ver4PatriciaTrieNodeReader ptNodeReader(mBuffers->getTrieBuffer(), mBuffers->getLanguageModelDictContent(), headerPolicy); Ver4PtNodeArrayReader ptNodeArrayReader(mBuffers->getTrieBuffer()); - Ver4BigramListPolicy bigramPolicy(mBuffers->getMutableBigramDictContent(), - mBuffers->getTerminalPositionLookupTable(), headerPolicy); Ver4ShortcutListPolicy shortcutPolicy(mBuffers->getMutableShortcutDictContent(), mBuffers->getTerminalPositionLookupTable()); Ver4PatriciaTrieNodeWriter ptNodeWriter(mBuffers->getWritableTrieBuffer(), - mBuffers, headerPolicy, &ptNodeReader, &ptNodeArrayReader, &bigramPolicy, - &shortcutPolicy); + mBuffers, headerPolicy, &ptNodeReader, &ptNodeArrayReader, &shortcutPolicy); int entryCountTable[MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1]; if (!mBuffers->getMutableLanguageModelDictContent()->updateAllProbabilityEntries(headerPolicy, @@ -93,14 +89,16 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, } if (headerPolicy->isDecayingDict()) { int maxEntryCountTable[MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1]; - maxEntryCountTable[0] = headerPolicy->getMaxUnigramCount(); - maxEntryCountTable[1] = headerPolicy->getMaxBigramCount(); + maxEntryCountTable[LanguageModelDictContent::UNIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE] = + headerPolicy->getMaxUnigramCount(); + maxEntryCountTable[LanguageModelDictContent::BIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE] = + headerPolicy->getMaxBigramCount(); for (size_t i = 2; i < NELEMS(maxEntryCountTable); ++i) { // TODO: Have max n-gram count. maxEntryCountTable[i] = headerPolicy->getMaxBigramCount(); } if (!mBuffers->getMutableLanguageModelDictContent()->truncateEntries(entryCountTable, - maxEntryCountTable, headerPolicy)) { + maxEntryCountTable, headerPolicy, entryCountTable)) { AKLOGE("Failed to truncate entries in language model dict content."); return false; } @@ -116,16 +114,6 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, &traversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted)) { return false; } - const int unigramCount = traversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted - .getValidUnigramCount(); - const int maxUnigramCount = headerPolicy->getMaxUnigramCount(); - if (headerPolicy->isDecayingDict() && unigramCount > maxUnigramCount) { - if (!truncateUnigrams(&ptNodeReader, &ptNodeWriter, maxUnigramCount)) { - AKLOGE("Cannot remove unigrams. current: %d, max: %d", unigramCount, - maxUnigramCount); - return false; - } - } readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos); DynamicPtGcEventListeners::TraversePolicyToUpdateBigramProbability @@ -134,21 +122,12 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, &traversePolicyToUpdateBigramProbability)) { return false; } - const int bigramCount = traversePolicyToUpdateBigramProbability.getValidBigramEntryCount(); - const int maxBigramCount = headerPolicy->getMaxBigramCount(); - if (headerPolicy->isDecayingDict() && bigramCount > maxBigramCount) { - if (!truncateBigrams(maxBigramCount)) { - AKLOGE("Cannot remove bigrams. current: %d, max: %d", bigramCount, maxBigramCount); - return false; - } - } // Mapping from positions in mBuffer to positions in bufferToWrite. PtNodeWriter::DictPositionRelocationMap dictPositionRelocationMap; readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos); Ver4PatriciaTrieNodeWriter ptNodeWriterForNewBuffers(buffersToWrite->getWritableTrieBuffer(), - buffersToWrite, headerPolicy, &ptNodeReader, &ptNodeArrayReader, &bigramPolicy, - &shortcutPolicy); + buffersToWrite, headerPolicy, &ptNodeReader, &ptNodeArrayReader, &shortcutPolicy); DynamicPtGcEventListeners::TraversePolicyToPlaceAndWriteValidPtNodesToBuffer traversePolicyToPlaceAndWriteValidPtNodesToBuffer(&ptNodeWriterForNewBuffers, buffersToWrite->getWritableTrieBuffer(), &dictPositionRelocationMap); @@ -161,12 +140,10 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, Ver4PatriciaTrieNodeReader newPtNodeReader(buffersToWrite->getTrieBuffer(), buffersToWrite->getLanguageModelDictContent(), headerPolicy); Ver4PtNodeArrayReader newPtNodeArrayreader(buffersToWrite->getTrieBuffer()); - Ver4BigramListPolicy newBigramPolicy(buffersToWrite->getMutableBigramDictContent(), - buffersToWrite->getTerminalPositionLookupTable(), headerPolicy); Ver4ShortcutListPolicy newShortcutPolicy(buffersToWrite->getMutableShortcutDictContent(), buffersToWrite->getTerminalPositionLookupTable()); Ver4PatriciaTrieNodeWriter newPtNodeWriter(buffersToWrite->getWritableTrieBuffer(), - buffersToWrite, headerPolicy, &newPtNodeReader, &newPtNodeArrayreader, &newBigramPolicy, + buffersToWrite, headerPolicy, &newPtNodeReader, &newPtNodeArrayreader, &newShortcutPolicy); // Re-assign terminal IDs for valid terminal PtNodes. TerminalPositionLookupTable::TerminalIdMap terminalIdMap; @@ -179,11 +156,6 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, mBuffers->getLanguageModelDictContent(), nullptr /* outNgramCount */)) { return false; } - // Run GC for bigram dict content. - if(!buffersToWrite->getMutableBigramDictContent()->runGC(&terminalIdMap, - mBuffers->getBigramDictContent(), outBigramCount)) { - return false; - } // Run GC for shortcut dict content. if(!buffersToWrite->getMutableShortcutDictContent()->runGC(&terminalIdMap, mBuffers->getShortcutDictContent())) { @@ -204,94 +176,10 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, &traversePolicyToUpdateAllPtNodeFlagsAndTerminalIds)) { return false; } - *outUnigramCount = traversePolicyToUpdateAllPositionFields.getUnigramCount(); - return true; -} - -// TODO: Remove. -bool Ver4PatriciaTrieWritingHelper::truncateUnigrams( - const Ver4PatriciaTrieNodeReader *const ptNodeReader, - Ver4PatriciaTrieNodeWriter *const ptNodeWriter, const int maxUnigramCount) { - const TerminalPositionLookupTable *const terminalPosLookupTable = - mBuffers->getTerminalPositionLookupTable(); - const int nextTerminalId = terminalPosLookupTable->getNextTerminalId(); - std::priority_queue<DictProbability, std::vector<DictProbability>, DictProbabilityComparator> - priorityQueue; - for (int i = 0; i < nextTerminalId; ++i) { - const int terminalPos = terminalPosLookupTable->getTerminalPtNodePosition(i); - if (terminalPos == NOT_A_DICT_POS) { - continue; - } - const ProbabilityEntry probabilityEntry = - mBuffers->getLanguageModelDictContent()->getProbabilityEntry(i); - const int probability = probabilityEntry.hasHistoricalInfo() ? - ForgettingCurveUtils::decodeProbability( - probabilityEntry.getHistoricalInfo(), mBuffers->getHeaderPolicy()) : - probabilityEntry.getProbability(); - priorityQueue.push(DictProbability(terminalPos, probability, - probabilityEntry.getHistoricalInfo()->getTimeStamp())); - } - - // Delete unigrams. - while (static_cast<int>(priorityQueue.size()) > maxUnigramCount) { - const int ptNodePos = priorityQueue.top().getDictPos(); - priorityQueue.pop(); - const PtNodeParams ptNodeParams = - ptNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos); - if (ptNodeParams.representsNonWordInfo()) { - continue; - } - if (!ptNodeWriter->markPtNodeAsWillBecomeNonTerminal(&ptNodeParams)) { - AKLOGE("Cannot mark PtNode as willBecomeNonterminal. PtNode pos: %d", ptNodePos); - return false; - } - } - return true; -} - -// TODO: Remove. -bool Ver4PatriciaTrieWritingHelper::truncateBigrams(const int maxBigramCount) { - const TerminalPositionLookupTable *const terminalPosLookupTable = - mBuffers->getTerminalPositionLookupTable(); - const int nextTerminalId = terminalPosLookupTable->getNextTerminalId(); - std::priority_queue<DictProbability, std::vector<DictProbability>, DictProbabilityComparator> - priorityQueue; - BigramDictContent *const bigramDictContent = mBuffers->getMutableBigramDictContent(); - for (int i = 0; i < nextTerminalId; ++i) { - const int bigramListPos = bigramDictContent->getBigramListHeadPos(i); - if (bigramListPos == NOT_A_DICT_POS) { - continue; - } - bool hasNext = true; - int readingPos = bigramListPos; - while (hasNext) { - const BigramEntry bigramEntry = - bigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); - const int entryPos = readingPos - bigramDictContent->getBigramEntrySize(); - hasNext = bigramEntry.hasNext(); - if (!bigramEntry.isValid()) { - continue; - } - const int probability = bigramEntry.hasHistoricalInfo() ? - ForgettingCurveUtils::decodeProbability( - bigramEntry.getHistoricalInfo(), mBuffers->getHeaderPolicy()) : - bigramEntry.getProbability(); - priorityQueue.push(DictProbability(entryPos, probability, - bigramEntry.getHistoricalInfo()->getTimeStamp())); - } - } - - // Delete bigrams. - while (static_cast<int>(priorityQueue.size()) > maxBigramCount) { - const int entryPos = priorityQueue.top().getDictPos(); - const BigramEntry bigramEntry = bigramDictContent->getBigramEntry(entryPos); - const BigramEntry invalidatedBigramEntry = bigramEntry.getInvalidatedEntry(); - if (!bigramDictContent->writeBigramEntry(&invalidatedBigramEntry, entryPos)) { - AKLOGE("Cannot write bigram entry to remove. pos: %d", entryPos); - return false; - } - priorityQueue.pop(); - } + *outUnigramCount = + entryCountTable[LanguageModelDictContent::UNIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE]; + *outBigramCount = + entryCountTable[LanguageModelDictContent::BIGRAM_COUNT_INDEX_IN_ENTRY_COUNT_TABLE]; return true; } diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.h index bb464ad28..b6278c4cb 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.h @@ -66,49 +66,6 @@ class Ver4PatriciaTrieWritingHelper { const TerminalPositionLookupTable::TerminalIdMap *const mTerminalIdMap; }; - // For truncateUnigrams() and truncateBigrams(). - class DictProbability { - public: - DictProbability(const int dictPos, const int probability, const int timestamp) - : mDictPos(dictPos), mProbability(probability), mTimestamp(timestamp) {} - - int getDictPos() const { - return mDictPos; - } - - int getProbability() const { - return mProbability; - } - - int getTimestamp() const { - return mTimestamp; - } - - private: - DISALLOW_DEFAULT_CONSTRUCTOR(DictProbability); - - int mDictPos; - int mProbability; - int mTimestamp; - }; - - // For truncateUnigrams() and truncateBigrams(). - class DictProbabilityComparator { - public: - bool operator()(const DictProbability &left, const DictProbability &right) { - if (left.getProbability() != right.getProbability()) { - return left.getProbability() > right.getProbability(); - } - if (left.getTimestamp() != right.getTimestamp()) { - return left.getTimestamp() < right.getTimestamp(); - } - return left.getDictPos() > right.getDictPos(); - } - - private: - DISALLOW_ASSIGNMENT_OPERATOR(DictProbabilityComparator); - }; - bool runGC(const int rootPtNodeArrayPos, const HeaderPolicy *const headerPolicy, Ver4DictBuffers *const buffersToWrite, int *const outUnigramCount, int *const outBigramCount); diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h b/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h index c2aeac211..00765888b 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h +++ b/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h @@ -98,7 +98,7 @@ class TrieMap { TrieMapIterator(const TrieMap *const trieMap, const int bitmapEntryIndex) : mTrieMap(trieMap), mStateStack(), mBaseBitmapEntryIndex(bitmapEntryIndex), mKey(0), mValue(0), mIsValid(false), mNextLevelBitmapEntryIndex(INVALID_INDEX) { - if (!trieMap) { + if (!trieMap || mBaseBitmapEntryIndex == INVALID_INDEX) { return; } const Entry bitmapEntry = mTrieMap->readEntry(mBaseBitmapEntryIndex); diff --git a/native/jni/src/utils/int_array_view.h b/native/jni/src/utils/int_array_view.h index 53f2d2971..8797b5944 100644 --- a/native/jni/src/utils/int_array_view.h +++ b/native/jni/src/utils/int_array_view.h @@ -105,6 +105,7 @@ class IntArrayView { using WordIdArrayView = IntArrayView; using PtNodePosArrayView = IntArrayView; +using CodePointArrayView = IntArrayView; } // namespace latinime #endif // LATINIME_MEMORY_VIEW_H diff --git a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp index 3cacba1c3..ca8d56f27 100644 --- a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp +++ b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp @@ -18,6 +18,8 @@ #include <gtest/gtest.h> +#include <unordered_set> + #include "utils/int_array_view.h" namespace latinime { @@ -69,5 +71,23 @@ TEST(LanguageModelDictContentTest, TestUnigramProbabilityWithHistoricalInfo) { EXPECT_TRUE(LanguageModelDictContent.removeProbabilityEntry(wordId)); } +TEST(LanguageModelDictContentTest, TestIterateProbabilityEntry) { + LanguageModelDictContent languageModelDictContent(false /* useHistoricalInfo */); + + const ProbabilityEntry originalEntry(0xFC, 100); + + const int wordIds[] = { 1, 2, 3, 4, 5 }; + for (const int wordId : wordIds) { + languageModelDictContent.setProbabilityEntry(wordId, &originalEntry); + } + std::unordered_set<int> wordIdSet(std::begin(wordIds), std::end(wordIds)); + for (const auto entry : languageModelDictContent.getProbabilityEntries(WordIdArrayView())) { + EXPECT_EQ(originalEntry.getFlags(), entry.getProbabilityEntry().getFlags()); + EXPECT_EQ(originalEntry.getProbability(), entry.getProbabilityEntry().getProbability()); + wordIdSet.erase(entry.getWordId()); + } + EXPECT_TRUE(wordIdSet.empty()); +} + } // namespace } // namespace latinime diff --git a/native/jni/tests/utils/time_keeper_test.cpp b/native/jni/tests/utils/time_keeper_test.cpp new file mode 100644 index 000000000..3f54b91f1 --- /dev/null +++ b/native/jni/tests/utils/time_keeper_test.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils/time_keeper.h" + +#include <gtest/gtest.h> + +namespace latinime { +namespace { + +TEST(TimeKeeperTest, TestTestMode) { + TimeKeeper::setCurrentTime(); + const int startTime = TimeKeeper::peekCurrentTime(); + static const int TEST_CURRENT_TIME = 100; + TimeKeeper::startTestModeWithForceCurrentTime(TEST_CURRENT_TIME); + EXPECT_EQ(TEST_CURRENT_TIME, TimeKeeper::peekCurrentTime()); + TimeKeeper::setCurrentTime(); + EXPECT_EQ(TEST_CURRENT_TIME, TimeKeeper::peekCurrentTime()); + TimeKeeper::stopTestMode(); + TimeKeeper::setCurrentTime(); + EXPECT_LE(startTime, TimeKeeper::peekCurrentTime()); +} + +} // namespace +} // namespace latinime |