From d3187f0a816c53da1bfce0c00770c4d44add68cd Mon Sep 17 00:00:00 2001 From: Satoshi Kataoka <satok@google.com> Date: Thu, 5 Jul 2012 17:03:19 +0900 Subject: [PATCH] Manual copy everything Change-Id: Ia3f8713f4c854ad12c009f64a38040cf3ac69731 --- dictionaries/en_gb_wordlist.xml | 26 +- dictionaries/en_us_wordlist.xml | 28 +- dictionaries/en_wordlist.xml | 30 +- dictionaries/fr_wordlist.xml | 155 +------ java/proguard.flags | 4 - java/res/raw/main_en.dict | Bin 1068816 -> 1068791 bytes java/res/raw/main_fr.dict | Bin 1328007 -> 1327366 bytes java/res/values-af/strings.xml | 8 +- java/res/values-am/strings.xml | 8 +- java/res/values-ar/strings.xml | 8 +- java/res/values-be/strings.xml | 8 +- java/res/values-bg/strings.xml | 8 +- java/res/values-ca/strings.xml | 8 +- java/res/values-cs/strings.xml | 8 +- java/res/values-da/strings.xml | 8 +- java/res/values-de/strings.xml | 8 +- java/res/values-el/strings.xml | 8 +- java/res/values-en-rGB/strings.xml | 8 +- java/res/values-es-rUS/strings.xml | 8 +- java/res/values-es/strings.xml | 8 +- java/res/values-et/strings.xml | 8 +- java/res/values-fa/strings.xml | 8 +- java/res/values-fi/strings.xml | 8 +- java/res/values-fr/strings.xml | 8 +- java/res/values-hi/strings.xml | 8 +- java/res/values-hr/strings.xml | 8 +- java/res/values-hu/strings.xml | 8 +- java/res/values-in/strings.xml | 8 +- java/res/values-it/strings.xml | 8 +- java/res/values-iw/strings.xml | 8 +- java/res/values-ja/strings.xml | 8 +- java/res/values-ko/strings.xml | 8 +- java/res/values-lt/strings.xml | 8 +- java/res/values-lv/strings.xml | 8 +- java/res/values-ms/strings.xml | 8 +- java/res/values-nb/strings.xml | 10 +- java/res/values-nl/strings.xml | 8 +- java/res/values-pl/strings.xml | 8 +- java/res/values-pt-rPT/strings.xml | 8 +- java/res/values-pt/strings.xml | 8 +- java/res/values-rm/strings.xml | 12 +- java/res/values-ro/strings.xml | 8 +- java/res/values-ru/strings.xml | 12 +- java/res/values-sk/strings.xml | 8 +- java/res/values-sl/strings.xml | 8 +- java/res/values-sr/strings.xml | 8 +- java/res/values-sv/strings.xml | 8 +- java/res/values-sw/strings.xml | 8 +- java/res/values-th/strings.xml | 8 +- java/res/values-tl/strings.xml | 8 +- java/res/values-tr/strings.xml | 8 +- java/res/values-uk/strings.xml | 8 +- java/res/values-vi/strings.xml | 8 +- java/res/values-zh-rCN/strings.xml | 8 +- java/res/values-zh-rTW/strings.xml | 8 +- java/res/values-zu/strings.xml | 8 +- java/res/values/donottranslate.xml | 46 ++ java/res/values/strings.xml | 19 +- java/res/xml/method.xml | 42 +- java/res/xml/prefs.xml | 12 +- .../KeyCodeDescriptionMapper.java | 12 +- .../inputmethod/keyboard/Keyboard.java | 21 +- .../keyboard/KeyboardLayoutSet.java | 7 +- .../inputmethod/keyboard/KeyboardView.java | 16 +- .../keyboard/LatinKeyboardView.java | 26 +- .../inputmethod/keyboard/PointerTracker.java | 26 +- .../inputmethod/keyboard/ProximityInfo.java | 5 - .../keyboard/internal/KeyStyles.java | 27 +- .../keyboard/internal/KeyboardIconsSet.java | 8 +- .../inputmethod/latin/AutoCorrection.java | 88 ++-- .../inputmethod/latin/BinaryDictionary.java | 68 +-- .../inputmethod/latin/BoundedTreeSet.java | 49 ++ .../latin/ContactsBinaryDictionary.java | 18 +- .../android/inputmethod/latin/Dictionary.java | 63 ++- .../latin/DictionaryCollection.java | 51 ++- .../inputmethod/latin/DictionaryFactory.java | 11 +- .../latin/ExpandableBinaryDictionary.java | 39 +- .../latin/ExpandableDictionary.java | 47 +- .../inputmethod/latin/InputPointers.java | 131 ++++++ .../inputmethod/latin/LastComposedWord.java | 14 +- .../android/inputmethod/latin/LatinIME.java | 33 +- .../inputmethod/latin/LatinImeLogger.java | 2 +- .../inputmethod/latin/ResearchLogger.java | 71 ++- .../latin/RichInputConnection.java | 16 +- .../android/inputmethod/latin/Settings.java | 51 ++- .../inputmethod/latin/SettingsValues.java | 4 +- .../inputmethod/latin/StringUtils.java | 3 + .../inputmethod/latin/SubtypeLocale.java | 21 +- .../android/inputmethod/latin/Suggest.java | 424 +++++------------- .../inputmethod/latin/SuggestedWords.java | 50 +-- ...onouslyLoadedContactsBinaryDictionary.java | 11 +- ...nchronouslyLoadedUserBinaryDictionary.java | 10 +- .../latin/UserBinaryDictionary.java | 14 +- .../latin/UserHistoryDictionary.java | 11 +- .../com/android/inputmethod/latin/Utils.java | 10 - .../latin/WhitelistDictionary.java | 2 +- .../inputmethod/latin/WordComposer.java | 32 +- .../AndroidSpellCheckerService.java | 19 +- .../latin/suggestions/SuggestionsView.java | 6 +- native/jni/Android.mk | 16 +- ...oid_inputmethod_latin_BinaryDictionary.cpp | 25 +- native/jni/src/defines.h | 2 + native/jni/src/dictionary.cpp | 5 + native/jni/src/dictionary.h | 32 +- .../src/gesture/gesture_decoder_wrapper.cpp | 22 + .../jni/src/gesture/gesture_decoder_wrapper.h | 91 ++++ .../gesture/incremental_decoder_interface.h | 41 ++ native/jni/src/proximity_info.cpp | 22 + native/jni/src/proximity_info.h | 4 + 109 files changed, 1280 insertions(+), 1261 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/BoundedTreeSet.java create mode 100644 java/src/com/android/inputmethod/latin/InputPointers.java create mode 100644 native/jni/src/gesture/gesture_decoder_wrapper.cpp create mode 100644 native/jni/src/gesture/gesture_decoder_wrapper.h create mode 100644 native/jni/src/gesture/incremental_decoder_interface.h diff --git a/dictionaries/en_gb_wordlist.xml b/dictionaries/en_gb_wordlist.xml index c2af46e1d6..09078ae0b4 100644 --- a/dictionaries/en_gb_wordlist.xml +++ b/dictionaries/en_gb_wordlist.xml @@ -1,4 +1,4 @@ -<wordlist locale="en_GB" description="English (UK)" date="1340038724" version="16"> +<wordlist locale="en_GB" description="English (UK)" date="1340965760" version="17"> <w f="222" flags="">the</w> <w f="214" flags="">of</w> <w f="212" flags="">and</w> @@ -256,7 +256,6 @@ <w f="155" flags="">national</w> <w f="155" flags="">nice</w> <w f="155" flags="">non</w> - <w f="155" flags="">north</w> <w f="155" flags="">period</w> <w f="155" flags="">son</w> <w f="155" flags="">south</w> @@ -283,7 +282,6 @@ <w f="154" flags="">present</w> <w f="154" flags="">produced</w> <w f="154" flags="">record</w> - <w f="154" flags="">role</w> <w f="154" flags="">six</w> <w f="154" flags="">species</w> <w f="154" flags="">started</w> @@ -607,6 +605,7 @@ <w f="145" flags="">move</w> <w f="145" flags="">natural</w> <w f="145" flags="">network</w> + <w f="145" flags="">north</w> <w f="145" flags="">northern</w> <w f="145" flags="">novel</w> <w f="145" flags="">numerous</w> @@ -708,6 +707,7 @@ <w f="144" flags="">rate</w> <w f="144" flags="">recent</w> <w f="144" flags="">remains</w> + <w f="144" flags="">role</w> <w f="144" flags="">seat</w> <w f="144" flags="">self</w> <w f="144" flags="">shown</w> @@ -13520,7 +13520,6 @@ <w f="97" flags="">Kay</w> <w f="97" flags="">Klein</w> <w f="97" flags="">Kuwait</w> - <w f="97" flags="">Lang</w> <w f="97" flags="">Leigh</w> <w f="97" flags="">Leipzig</w> <w f="97" flags="">Lennon</w> @@ -14169,7 +14168,6 @@ <w f="96" flags="">MacLeod</w> <w f="96" flags="">Mafia</w> <w f="96" flags="">Maharashtra</w> - <w f="96" flags="">Marina</w> <w f="96" flags="">McCall</w> <w f="96" flags="">McClellan</w> <w f="96" flags="">McGuire</w> @@ -15902,7 +15900,6 @@ <w f="94" flags="">leakage</w> <w f="94" flags="">leaks</w> <w f="94" flags="">lecturing</w> - <w f="94" flags="">lesbians</w> <w f="94" flags="">licences</w> <w f="94" flags="">life's</w> <w f="94" flags="">lifeboat</w> @@ -16780,7 +16777,6 @@ <w f="93" flags="">sclerosis</w> <w f="93" flags="">scream</w> <w f="93" flags="">screenplays</w> - <w f="93" flags="">screws</w> <w f="93" flags="">seaport</w> <w f="93" flags="">seawater</w> <w f="93" flags="">secretaries</w> @@ -29553,7 +29549,6 @@ <w f="79" flags="">Getty</w> <w f="79" flags="">Gleason</w> <w f="79" flags="">Godwin</w> - <w f="79" flags="">Gotha</w> <w f="79" flags="">Grantham</w> <w f="79" flags="">Greenpeace</w> <w f="79" flags="">Grenoble</w> @@ -32722,7 +32717,6 @@ <w f="77" flags="">leeward</w> <w f="77" flags="">lengthwise</w> <w f="77" flags="">lentils</w> - <w f="77" flags="">lesbianism</w> <w f="77" flags="">leveraging</w> <w f="77" flags="">lib</w> <w f="77" flags="">libertarianism</w> @@ -49865,7 +49859,6 @@ <w f="64" flags="abbreviation">ECW's</w> <w f="64" flags="abbreviation">EEOC</w> <w f="64" flags="abbreviation">EKG</w> - <w f="64" flags="abbreviation">ENS</w> <w f="64" flags="abbreviation">ESOL</w> <w f="64" flags="">Edgeworth</w> <w f="64" flags="">Edirne</w> @@ -54575,7 +54568,6 @@ <w f="61" flags="">Hersey</w> <w f="61" flags="">Hiatt</w> <w f="61" flags="">Himmler's</w> - <w f="61" flags="">Hoke</w> <w f="61" flags="">Hormuz</w> <w f="61" flags="">Hosea</w> <w f="61" flags="">Hubli</w> @@ -89915,7 +89907,6 @@ <w f="38" flags="">Hally</w> <w f="38" flags="">Harpo's</w> <w f="38" flags="">Higbee's</w> - <w f="38" flags="">Hoke's</w> <w f="38" flags="">Honeywell's</w> <w f="38" flags="">Horatian</w> <w f="38" flags="">Iago's</w> @@ -109454,7 +109445,6 @@ <w f="25" flags="">leets</w> <w f="25" flags="">legitimism</w> <w f="25" flags="">leopardskin</w> - <w f="25" flags="">lesbian's</w> <w f="25" flags="">lessee's</w> <w f="25" flags="">lethargically</w> <w f="25" flags="">libber</w> @@ -112568,7 +112558,6 @@ <w f="23" flags="">pickerels</w> <w f="23" flags="">piecers</w> <w f="23" flags="">pigmenting</w> - <w f="23" flags="">pill's</w> <w f="23" flags="">pilled</w> <w f="23" flags="">pillorying</w> <w f="23" flags="">pinked</w> @@ -117332,7 +117321,6 @@ <w f="18" flags="">Hinsdale's</w> <w f="18" flags="">Hispaniola's</w> <w f="18" flags="">Hohenzollern's</w> - <w f="18" flags="">Hokes</w> <w f="18" flags="">Horst's</w> <w f="18" flags="">Housecat's</w> <w f="18" flags="">Hughie's</w> @@ -155568,6 +155556,7 @@ <w f="0" flags="">XP</w> <w f="0" flags="offensive">Yoni's</w> <w f="0" flags="">acct</w> + <w f="0">admin</w> <w f="0" flags="n">adult</w> <w f="0" flags="medical">adulteress</w> <w f="0" flags="medical">adulteresses</w> @@ -156092,6 +156081,9 @@ <w f="0" flags="">lei</w> <w f="0" flags="">lem</w> <w f="0" flags="n">lesbian</w> + <w f="0" flags="">lesbian's</w> + <w f="0" flags="">lesbianism</w> + <w f="0" flags="">lesbians</w> <w f="0" flags="offensive">letch</w> <w f="0" flags="n">libido</w> <w f="0" flags="s">librium</w> @@ -156267,6 +156259,7 @@ <w f="0" flags="medical">phosphaturia</w> <w f="0" flags="medical">phosphaturic</w> <w f="0" flags="s">pill</w> + <w f="0" flags="">pill's</w> <w f="0" flags="s">pills</w> <w f="0" flags="offensive">pimp</w> <w f="0" flags="offensive">pimp's</w> @@ -156428,6 +156421,7 @@ <w f="0" flags="r">screw</w> <w f="0" flags="n">screwed</w> <w f="0" flags="n">screwing</w> + <w f="0" flags="">screws</w> <w f="0" flags="medical">scrota</w> <w f="0" flags="medical">scrotal</w> <w f="0" flags="medical">scrotum</w> @@ -156641,6 +156635,7 @@ <w f="0" flags="babytalk">twat</w> <w f="0" flags="babytalk">twats</w> <w f="0" flags="">twit</w> + <w f="0">ui</w> <w f="0">ull</w> <w f="0" flags="babytalk">underclothing</w> <w f="0" flags="babytalk">underwear</w> @@ -156747,6 +156742,7 @@ <w f="0" flags="medical">uterus</w> <w f="0" flags="medical">uterus's</w> <w f="0" flags="medical">uteruses</w> + <w f="0">ux</w> <w f="0" flags="medical">vagina</w> <w f="0" flags="medical">vagina's</w> <w f="0" flags="medical">vaginae</w> diff --git a/dictionaries/en_us_wordlist.xml b/dictionaries/en_us_wordlist.xml index 3cafbd7863..0b158f5531 100644 --- a/dictionaries/en_us_wordlist.xml +++ b/dictionaries/en_us_wordlist.xml @@ -1,4 +1,4 @@ -<wordlist locale="en_US" description="English (US)" date="1340038693" version="16"> +<wordlist locale="en_US" description="English (US)" date="1340965726" version="17"> <w f="222" flags="">the</w> <w f="214" flags="">of</w> <w f="212" flags="">and</w> @@ -255,7 +255,6 @@ <w f="155" flags="">national</w> <w f="155" flags="">nice</w> <w f="155" flags="">non</w> - <w f="155" flags="">north</w> <w f="155" flags="">period</w> <w f="155" flags="">son</w> <w f="155" flags="">south</w> @@ -282,7 +281,6 @@ <w f="154" flags="">present</w> <w f="154" flags="">produced</w> <w f="154" flags="">record</w> - <w f="154" flags="">role</w> <w f="154" flags="">six</w> <w f="154" flags="">species</w> <w f="154" flags="">started</w> @@ -587,7 +585,6 @@ <w f="145" flags="">July</w> <w f="145" flags="">June</w> <w f="145" flags="">March</w> - <w f="145" flags="">North</w> <w f="145" flags="">October</w> <w f="145" flags="">active</w> <w f="145" flags="">always</w> @@ -614,6 +611,7 @@ <w f="145" flags="">move</w> <w f="145" flags="">natural</w> <w f="145" flags="">network</w> + <w f="145" flags="">north</w> <w f="145" flags="">northern</w> <w f="145" flags="">novel</w> <w f="145" flags="">numerous</w> @@ -717,6 +715,7 @@ <w f="144" flags="">rate</w> <w f="144" flags="">recent</w> <w f="144" flags="">remains</w> + <w f="144" flags="">role</w> <w f="144" flags="">seat</w> <w f="144" flags="">self</w> <w f="144" flags="">shown</w> @@ -12069,6 +12068,7 @@ <w f="100" flags="">Nash</w> <w f="100" flags="">Newark</w> <w f="100" flags="">Norse</w> + <w f="100" flags="">North</w> <w f="100" flags="">Norton</w> <w f="100" flags="">Norwich</w> <w f="100" flags="">Okinawa</w> @@ -13996,7 +13996,6 @@ <w f="97" flags="">Klein</w> <w f="97" flags="">Kuwait</w> <w f="97" flags="">Ladies</w> - <w f="97" flags="">Lang</w> <w f="97" flags="">Leigh</w> <w f="97" flags="">Leipzig</w> <w f="97" flags="">Lennon</w> @@ -14677,7 +14676,6 @@ <w f="96" flags="">Madras</w> <w f="96" flags="">Mafia</w> <w f="96" flags="">Maharashtra</w> - <w f="96" flags="">Marina</w> <w f="96" flags="">Master's</w> <w f="96" flags="">McCall</w> <w f="96" flags="">McClellan</w> @@ -16141,7 +16139,6 @@ <w f="94" flags="">Stratford</w> <w f="94" flags="">Strauss</w> <w f="94" flags="">Stuttgart</w> - <w f="94" flags="">Sunshine</w> <w f="94" flags="">Suzuki</w> <w f="94" flags="">Taiwanese</w> <w f="94" flags="">Talbot</w> @@ -16154,7 +16151,6 @@ <w f="94" flags="">Tyne</w> <w f="94" flags="abbreviation">UNC</w> <w f="94" flags="abbreviation">UNICEF</w> - <w f="94" flags="">UNIX</w> <w f="94" flags="abbreviation">USDA</w> <w f="94" flags="">Unix</w> <w f="94" flags="">Valentine</w> @@ -16488,7 +16484,6 @@ <w f="94" flags="">leakage</w> <w f="94" flags="">leaks</w> <w f="94" flags="">lecturing</w> - <w f="94" flags="">lesbians</w> <w f="94" flags="">leveled</w> <w f="94" flags="">life's</w> <w f="94" flags="">lifeboat</w> @@ -17402,7 +17397,6 @@ <w f="93" flags="">sclerosis</w> <w f="93" flags="">scream</w> <w f="93" flags="">screenplays</w> - <w f="93" flags="">screws</w> <w f="93" flags="">seaport</w> <w f="93" flags="">seawater</w> <w f="93" flags="">secretaries</w> @@ -30682,7 +30676,6 @@ <w f="79" flags="">Ghats</w> <w f="79" flags="">Gleason</w> <w f="79" flags="">Godwin</w> - <w f="79" flags="">Gotha</w> <w f="79" flags="">Grantham</w> <w f="79" flags="">Greenpeace</w> <w f="79" flags="">Grenoble</w> @@ -33954,7 +33947,6 @@ <w f="77" flags="">leeward</w> <w f="77" flags="">lengthwise</w> <w f="77" flags="">lentils</w> - <w f="77" flags="">lesbianism</w> <w f="77" flags="">leveraging</w> <w f="77" flags="">lib</w> <w f="77" flags="">libertarianism</w> @@ -92910,7 +92902,6 @@ <w f="38" flags="">Harpo's</w> <w f="38" flags="">Higbee's</w> <w f="38">Hipparchus</w> - <w f="38" flags="">Hoke's</w> <w f="38" flags="">Honeywell's</w> <w f="38" flags="">Horatian</w> <w f="38" flags="">Iago's</w> @@ -112796,7 +112787,6 @@ <w f="25" flags="">leets</w> <w f="25" flags="">legitimism</w> <w f="25" flags="">leopardskin</w> - <w f="25" flags="">lesbian's</w> <w f="25" flags="">lessee's</w> <w f="25" flags="">lethargically</w> <w f="25" flags="">libber</w> @@ -115952,7 +115942,6 @@ <w f="23" flags="">pickerels</w> <w f="23" flags="">piecers</w> <w f="23" flags="">pigmenting</w> - <w f="23" flags="">pill's</w> <w f="23" flags="">pilled</w> <w f="23" flags="">pillorying</w> <w f="23" flags="">pinked</w> @@ -120765,7 +120754,6 @@ <w f="18" flags="">Hinsdale's</w> <w f="18" flags="">Hispaniola's</w> <w f="18" flags="">Hohenzollern's</w> - <w f="18" flags="">Hokes</w> <w f="18" flags="">Horst's</w> <w f="18" flags="">Housecat's</w> <w f="18" flags="">Hughie's</w> @@ -159318,6 +159306,7 @@ <w f="0" flags="">XP</w> <w f="0" flags="offensive">Yoni's</w> <w f="0" flags="">acct</w> + <w f="0">admin</w> <w f="0" flags="n">adult</w> <w f="0" flags="medical">adulteress</w> <w f="0" flags="medical">adulteresses</w> @@ -159849,6 +159838,9 @@ <w f="0" flags="medical">leching</w> <w f="0" flags="">lei</w> <w f="0" flags="n">lesbian</w> + <w f="0" flags="">lesbian's</w> + <w f="0" flags="">lesbianism</w> + <w f="0" flags="">lesbians</w> <w f="0" flags="offensive">letch</w> <w f="0" flags="n">libido</w> <w f="0" flags="n">lick</w> @@ -160024,6 +160016,7 @@ <w f="0" flags="medical">phosphaturia</w> <w f="0" flags="medical">phosphaturic</w> <w f="0" flags="s">pill</w> + <w f="0" flags="">pill's</w> <w f="0" flags="s">pills</w> <w f="0" flags="offensive">pimp</w> <w f="0" flags="offensive">pimp's</w> @@ -160183,6 +160176,7 @@ <w f="0" flags="r">screw</w> <w f="0" flags="n">screwed</w> <w f="0" flags="n">screwing</w> + <w f="0" flags="">screws</w> <w f="0" flags="medical">scrota</w> <w f="0" flags="medical">scrotal</w> <w f="0" flags="medical">scrotum</w> @@ -160398,6 +160392,7 @@ <w f="0" flags="babytalk">twat</w> <w f="0" flags="babytalk">twats</w> <w f="0" flags="">twit</w> + <w f="0">ui</w> <w f="0">ull</w> <w f="0" flags="">ump</w> <w f="0" flags="babytalk">underclothing</w> @@ -160505,6 +160500,7 @@ <w f="0" flags="medical">uterus</w> <w f="0" flags="medical">uterus's</w> <w f="0" flags="medical">uteruses</w> + <w f="0">ux</w> <w f="0" flags="medical">vagina</w> <w f="0" flags="medical">vagina's</w> <w f="0" flags="medical">vaginae</w> diff --git a/dictionaries/en_wordlist.xml b/dictionaries/en_wordlist.xml index 6f594d5a40..c6b3bdc940 100644 --- a/dictionaries/en_wordlist.xml +++ b/dictionaries/en_wordlist.xml @@ -1,4 +1,4 @@ -<wordlist locale="en" description="English" date="1340038727" version="16"> +<wordlist locale="en" description="English" date="1340965763" version="17"> <w f="222" flags="">the</w> <w f="214" flags="">of</w> <w f="212" flags="">and</w> @@ -255,7 +255,6 @@ <w f="155" flags="">national</w> <w f="155" flags="">nice</w> <w f="155" flags="">non</w> - <w f="155" flags="">north</w> <w f="155" flags="">period</w> <w f="155" flags="">son</w> <w f="155" flags="">south</w> @@ -282,7 +281,6 @@ <w f="154" flags="">present</w> <w f="154" flags="">produced</w> <w f="154" flags="">record</w> - <w f="154" flags="">role</w> <w f="154" flags="">six</w> <w f="154" flags="">species</w> <w f="154" flags="">started</w> @@ -587,7 +585,6 @@ <w f="145" flags="">July</w> <w f="145" flags="">June</w> <w f="145" flags="">March</w> - <w f="145" flags="">North</w> <w f="145" flags="">October</w> <w f="145" flags="">active</w> <w f="145" flags="">always</w> @@ -614,6 +611,7 @@ <w f="145" flags="">move</w> <w f="145" flags="">natural</w> <w f="145" flags="">network</w> + <w f="145" flags="">north</w> <w f="145" flags="">northern</w> <w f="145" flags="">novel</w> <w f="145" flags="">numerous</w> @@ -718,6 +716,7 @@ <w f="144" flags="">rate</w> <w f="144" flags="">recent</w> <w f="144" flags="">remains</w> + <w f="144" flags="">role</w> <w f="144" flags="">seat</w> <w f="144" flags="">self</w> <w f="144" flags="">shown</w> @@ -12162,6 +12161,7 @@ <w f="100" flags="">Nash</w> <w f="100" flags="">Newark</w> <w f="100" flags="">Norse</w> + <w f="100" flags="">North</w> <w f="100" flags="">Norton</w> <w f="100" flags="">Norwich</w> <w f="100" flags="">Okinawa</w> @@ -14103,7 +14103,6 @@ <w f="97" flags="">Klein</w> <w f="97" flags="">Kuwait</w> <w f="97" flags="">Ladies</w> - <w f="97" flags="">Lang</w> <w f="97" flags="">Leigh</w> <w f="97" flags="">Leipzig</w> <w f="97" flags="">Lennon</w> @@ -14792,7 +14791,6 @@ <w f="96" flags="">Madras</w> <w f="96" flags="">Mafia</w> <w f="96" flags="">Maharashtra</w> - <w f="96" flags="">Marina</w> <w f="96" flags="">Master's</w> <w f="96" flags="">McCall</w> <w f="96" flags="">McClellan</w> @@ -16273,7 +16271,6 @@ <w f="94" flags="">Stratford</w> <w f="94" flags="">Strauss</w> <w f="94" flags="">Stuttgart</w> - <w f="94" flags="">Sunshine</w> <w f="94" flags="">Suzuki</w> <w f="94" flags="abbreviation">TBS</w> <w f="94" flags="">Taiwanese</w> @@ -16287,7 +16284,6 @@ <w f="94" flags="">Tyne</w> <w f="94" flags="abbreviation">UNC</w> <w f="94" flags="abbreviation">UNICEF</w> - <w f="94" flags="">UNIX</w> <w f="94" flags="abbreviation">USDA</w> <w f="94" flags="">Unix</w> <w f="94" flags="">Valentine</w> @@ -16624,7 +16620,6 @@ <w f="94" flags="">leakage</w> <w f="94" flags="">leaks</w> <w f="94" flags="">lecturing</w> - <w f="94" flags="">lesbians</w> <w f="94" flags="">leveled</w> <w f="94" flags="">licences</w> <w f="94" flags="">life's</w> @@ -17555,7 +17550,6 @@ <w f="93" flags="">sclerosis</w> <w f="93" flags="">scream</w> <w f="93" flags="">screenplays</w> - <w f="93" flags="">screws</w> <w f="93" flags="">seaport</w> <w f="93" flags="">seawater</w> <w f="93" flags="">secretaries</w> @@ -31073,7 +31067,6 @@ <w f="79" flags="">Ghats</w> <w f="79" flags="">Gleason</w> <w f="79" flags="">Godwin</w> - <w f="79" flags="">Gotha</w> <w f="79" flags="">Grantham</w> <w f="79" flags="">Greenpeace</w> <w f="79" flags="">Grenoble</w> @@ -34402,7 +34395,6 @@ <w f="77" flags="">leeward</w> <w f="77" flags="">lengthwise</w> <w f="77" flags="">lentils</w> - <w f="77" flags="">lesbianism</w> <w f="77" flags="">leveraging</w> <w f="77" flags="">lib</w> <w f="77" flags="">libertarianism</w> @@ -52519,7 +52511,6 @@ <w f="64" flags="abbreviation">ECW's</w> <w f="64" flags="abbreviation">EEOC</w> <w f="64" flags="abbreviation">EKG</w> - <w f="64" flags="abbreviation">ENS</w> <w f="64" flags="abbreviation">ESOL</w> <w f="64" flags="">Edgeworth</w> <w f="64" flags="">Edirne</w> @@ -57486,7 +57477,6 @@ <w f="61" flags="">Hersey</w> <w f="61" flags="">Hiatt</w> <w f="61" flags="">Himmler's</w> - <w f="61" flags="">Hoke</w> <w f="61" flags="">Hormuz</w> <w f="61" flags="">Hosea</w> <w f="61" flags="">Hubli</w> @@ -94993,7 +94983,6 @@ <w f="38" flags="">Harpo's</w> <w f="38" flags="">Higbee's</w> <w f="38">Hipparchus</w> - <w f="38" flags="">Hoke's</w> <w f="38" flags="">Honeywell's</w> <w f="38" flags="">Horatian</w> <w f="38" flags="">Iago's</w> @@ -115756,7 +115745,6 @@ <w f="25" flags="">leets</w> <w f="25" flags="">legitimism</w> <w f="25" flags="">leopardskin</w> - <w f="25" flags="">lesbian's</w> <w f="25" flags="">lessee's</w> <w f="25" flags="">lethargically</w> <w f="25" flags="">libber</w> @@ -119045,7 +119033,6 @@ <w f="23" flags="">pickerels</w> <w f="23" flags="">piecers</w> <w f="23" flags="">pigmenting</w> - <w f="23" flags="">pill's</w> <w f="23" flags="">pilled</w> <w f="23" flags="">pillorying</w> <w f="23" flags="">pinked</w> @@ -124070,7 +124057,6 @@ <w f="18" flags="">Hinsdale's</w> <w f="18" flags="">Hispaniola's</w> <w f="18" flags="">Hohenzollern's</w> - <w f="18" flags="">Hokes</w> <w f="18" flags="">Horst's</w> <w f="18" flags="">Housecat's</w> <w f="18" flags="">Hughie's</w> @@ -164106,6 +164092,7 @@ <w f="0" flags="">XP</w> <w f="0" flags="offensive">Yoni's</w> <w f="0" flags="">acct</w> + <w f="0">admin</w> <w f="0" flags="n">adult</w> <w f="0" flags="medical">adulteress</w> <w f="0" flags="medical">adulteresses</w> @@ -164656,6 +164643,9 @@ <w f="0" flags="">lei</w> <w f="0" flags="">lem</w> <w f="0" flags="n">lesbian</w> + <w f="0" flags="">lesbian's</w> + <w f="0" flags="">lesbianism</w> + <w f="0" flags="">lesbians</w> <w f="0" flags="offensive">letch</w> <w f="0" flags="n">libido</w> <w f="0" flags="s">librium</w> @@ -164842,6 +164832,7 @@ <w f="0" flags="medical">phosphaturia</w> <w f="0" flags="medical">phosphaturic</w> <w f="0" flags="s">pill</w> + <w f="0" flags="">pill's</w> <w f="0" flags="s">pills</w> <w f="0" flags="offensive">pimp</w> <w f="0" flags="offensive">pimp's</w> @@ -165004,6 +164995,7 @@ <w f="0" flags="r">screw</w> <w f="0" flags="n">screwed</w> <w f="0" flags="n">screwing</w> + <w f="0" flags="">screws</w> <w f="0" flags="medical">scrota</w> <w f="0" flags="medical">scrotal</w> <w f="0" flags="medical">scrotum</w> @@ -165226,6 +165218,7 @@ <w f="0" flags="babytalk">twat</w> <w f="0" flags="babytalk">twats</w> <w f="0" flags="">twit</w> + <w f="0">ui</w> <w f="0">ull</w> <w f="0" flags="">ump</w> <w f="0" flags="babytalk">underclothing</w> @@ -165335,6 +165328,7 @@ <w f="0" flags="medical">uterus</w> <w f="0" flags="medical">uterus's</w> <w f="0" flags="medical">uteruses</w> + <w f="0">ux</w> <w f="0" flags="medical">vagina</w> <w f="0" flags="medical">vagina's</w> <w f="0" flags="medical">vaginae</w> diff --git a/dictionaries/fr_wordlist.xml b/dictionaries/fr_wordlist.xml index 39909885c2..6053f4843f 100644 --- a/dictionaries/fr_wordlist.xml +++ b/dictionaries/fr_wordlist.xml @@ -1,4 +1,4 @@ -<wordlist locale="fr" description="Français" date="1339787661" version="15" options="french_ligature_processing"> +<wordlist locale="fr" description="Français" date="1340965148" version="17" options="french_ligature_processing"> <w f="209" flags="">de</w> <w f="200" flags="">la</w> <w f="197" flags="">et</w> @@ -1069,6 +1069,7 @@ <w f="125" flags="">finit</w> <w f="125" flags="">fleuve</w> <w f="125" flags="">fondateur</w> + <w f="125">généralement</w> <w f="125" flags="">hors</w> <w f="125" flags="">ici</w> <w f="125" flags="">importantes</w> @@ -13168,7 +13169,6 @@ <w f="90" flags="">play-offs</w> <w f="90" flags="">plaça</w> <w f="90" flags="">plonger</w> - <w f="90" flags="">pole</w> <w f="90" flags="">polonaises</w> <w f="90" flags="">polymères</w> <w f="90" flags="">popularisé</w> @@ -15098,7 +15098,6 @@ <w f="87" flags="">donneur</w> <w f="87" flags="">dorés</w> <w f="87" flags="">doucement</w> - <w f="87" flags="">doyenné</w> <w f="87" flags="">drames</w> <w f="87" flags="">dualité</w> <w f="87" flags="">ducale</w> @@ -20845,7 +20844,6 @@ <w f="81" flags="">matérialisme</w> <w f="81" flags="">mauve</w> <w f="81" flags="">maximiser</w> - <w f="81" flags="">media</w> <w f="81" flags="">melon</w> <w f="81" flags="">mendiants</w> <w f="81" flags="">menuiserie</w> @@ -21702,7 +21700,6 @@ <w f="80" flags="">gallo-romains</w> <w f="80" flags="">galop</w> <w f="80" flags="">gangster</w> - <w f="80" flags="">general</w> <w f="80" flags="">gentilé</w> <w f="80" flags="">gewurztraminer</w> <w f="80" flags="">gisant</w> @@ -24213,7 +24210,6 @@ <w f="78" flags="">mythologies</w> <w f="78" flags="">mâchicoulis</w> <w f="78" flags="">méconnue</w> - <w f="78" flags="">médina</w> <w f="78" flags="">mésopotamienne</w> <w f="78" flags="">métriques</w> <w f="78" flags="">n'apprécie</w> @@ -26343,7 +26339,6 @@ <w f="76" flags="">graphème</w> <w f="76" flags="">gravitationnelles</w> <w f="76" flags="">greffer</w> - <w f="76" flags="">guérilleros</w> <w f="76" flags="">gèle</w> <w f="76" flags="">génitales</w> <w f="76" flags="">généalogiques</w> @@ -31797,7 +31792,6 @@ <w f="72" flags="">gouvernait</w> <w f="72" flags="">gouvernant</w> <w f="72" flags="">goéland</w> - <w f="72" flags="">grace</w> <w f="72" flags="">groove</w> <w f="72" flags="">gymnastes</w> <w f="72" flags="">génomes</w> @@ -32178,7 +32172,6 @@ <w f="72" flags="">polders</w> <w f="72" flags="">poliomyélite</w> <w f="72" flags="">polychromie</w> - <w f="72" flags="">polynomiale</w> <w f="72" flags="">polyvalents</w> <w f="72" flags="">pondus</w> <w f="72" flags="">pool</w> @@ -33103,7 +33096,6 @@ <w f="71" flags="">d'Austin</w> <w f="71" flags="">d'Avalon</w> <w f="71" flags="">d'Azov</w> - <w f="71" flags="">d'Aïn</w> <w f="71" flags="">d'Emily</w> <w f="71" flags="">d'Esther</w> <w f="71" flags="">d'Halicarnasse</w> @@ -33402,7 +33394,6 @@ <w f="71" flags="">imaginés</w> <w f="71" flags="">immigrant</w> <w f="71" flags="">imparfait</w> - <w f="71" flags="">imperium</w> <w f="71" flags="">implicites</w> <w f="71" flags="">importateur</w> <w f="71" flags="">imposable</w> @@ -33808,7 +33799,6 @@ <w f="71" flags="">rasées</w> <w f="71" flags="">rationaliser</w> <w f="71" flags="">rayés</w> - <w f="71" flags="">real</w> <w f="71" flags="">rebaptiser</w> <w f="71" flags="">rebâti</w> <w f="71" flags="">recensant</w> @@ -34659,7 +34649,6 @@ <w f="70" flags="">cénotaphe</w> <w f="70" flags="">d'Achaïe</w> <w f="70" flags="">d'Agrippa</w> - <w f="70" flags="">d'Al-Qaida</w> <w f="70" flags="">d'Alabama</w> <w f="70" flags="">d'Albon</w> <w f="70" flags="">d'Alessandro</w> @@ -34674,7 +34663,6 @@ <w f="70" flags="">d'Argos</w> <w f="70" flags="">d'Assouan</w> <w f="70" flags="">d'Avaugour</w> - <w f="70" flags="">d'Avila</w> <w f="70" flags="">d'Azincourt</w> <w f="70" flags="">d'East</w> <w f="70" flags="">d'Edmund</w> @@ -34788,7 +34776,6 @@ <w f="70" flags="">diva</w> <w f="70" flags="">diverge</w> <w f="70" flags="">divergents</w> - <w f="70" flags="">djebel</w> <w f="70" flags="">dominical</w> <w f="70" flags="">dopamine</w> <w f="70" flags="">dopé</w> @@ -36252,7 +36239,6 @@ <w f="69" flags="">concevant</w> <w f="69" flags="">concurrencée</w> <w f="69" flags="">condense</w> - <w f="69" flags="">condottiere</w> <w f="69" flags="">confidente</w> <w f="69" flags="">confine</w> <w f="69" flags="">conjonctif</w> @@ -36274,7 +36260,6 @@ <w f="69" flags="">coqueluche</w> <w f="69" flags="">corda</w> <w f="69" flags="">cordiales</w> - <w f="69" flags="">core</w> <w f="69" flags="">corpulence</w> <w f="69" flags="">corrosif</w> <w f="69" flags="">cottage</w> @@ -40119,7 +40104,6 @@ <w f="67" flags="">l'Estrie</w> <w f="67" flags="abbreviation">l'IFK</w> <w f="67" flags="abbreviation">l'INSEP</w> - <w f="67" flags="">l'Imperial</w> <w f="67" flags="">l'Indien</w> <w f="67" flags="">l'Istrie</w> <w f="67" flags="abbreviation">l'OSCE</w> @@ -40246,7 +40230,6 @@ <w f="67" flags="">mayonnaise</w> <w f="67" flags="">maîtrisait</w> <w f="67" flags="">maîtrises</w> - <w f="67" flags="">medium</w> <w f="67" flags="">melons</w> <w f="67" flags="">membranaires</w> <w f="67" flags="">menottes</w> @@ -41573,7 +41556,6 @@ <w f="66" flags="">d'Auxonne</w> <w f="66" flags="">d'Avellino</w> <w f="66" flags="">d'Eddy</w> - <w f="66" flags="">d'Eden</w> <w f="66" flags="">d'Erich</w> <w f="66" flags="">d'Eschyle</w> <w f="66" flags="">d'Essen</w> @@ -42181,7 +42163,6 @@ <w f="66" flags="">mazout</w> <w f="66" flags="">maçonné</w> <w f="66" flags="">mec</w> - <w f="66" flags="">medias</w> <w f="66" flags="">menaçants</w> <w f="66" flags="">mensurations</w> <w f="66" flags="">merchandising</w> @@ -42343,7 +42324,6 @@ <w f="66" flags="">plénipotentiaires</w> <w f="66" flags="">pléthore</w> <w f="66" flags="">poignarder</w> - <w f="66" flags="">polynomial</w> <w f="66" flags="">polynésiens</w> <w f="66" flags="">pont-canal</w> <w f="66" flags="">popularisa</w> @@ -44095,7 +44075,6 @@ <w f="65" flags="">manipulent</w> <w f="65" flags="">manquèrent</w> <w f="65" flags="">manqués</w> - <w f="65" flags="">maqam</w> <w f="65" flags="">marchaient</w> <w f="65" flags="">marginalisé</w> <w f="65" flags="">marre</w> @@ -44231,7 +44210,6 @@ <w f="65" flags="">pensais</w> <w f="65" flags="">pensante</w> <w f="65" flags="">perdrait</w> - <w f="65" flags="">perestroïka</w> <w f="65" flags="">perfide</w> <w f="65" flags="">perméables</w> <w f="65" flags="">perpétuant</w> @@ -45576,7 +45554,6 @@ <w f="64" flags="">dormance</w> <w f="64" flags="">dormi</w> <w f="64" flags="">doublent</w> - <w f="64" flags="">doyennés</w> <w f="64" flags="">dragueur</w> <w f="64" flags="">dragueurs</w> <w f="64" flags="">drainées</w> @@ -45803,7 +45780,6 @@ <w f="64" flags="">herbicide</w> <w f="64" flags="">heurtèrent</w> <w f="64" flags="">hiboux</w> - <w f="64" flags="">hindî</w> <w f="64" flags="">hiragana</w> <w f="64" flags="">hivernaux</w> <w f="64" flags="">hivernent</w> @@ -46826,6 +46802,7 @@ <w f="63" flags="">Dyck</w> <w f="63" flags="">Délos</w> <w f="63" flags="">Eaton</w> + <w f="63" flags="">El-Kébir</w> <w f="63" flags="">Elgar</w> <w f="63" flags="">Emmanuel-Philibert</w> <w f="63" flags="">Erasmus</w> @@ -47645,7 +47622,6 @@ <w f="63" flags="">déterrer</w> <w f="63" flags="">efficiente</w> <w f="63" flags="">effroi</w> - <w f="63" flags="">el-Kébir</w> <w f="63" flags="">embarcadère</w> <w f="63" flags="">embarquement</w> <w f="63" flags="">embusqués</w> @@ -50498,7 +50474,6 @@ <w f="62" flags="">pointures</w> <w f="62" flags="">politicienne</w> <w f="62" flags="">polyarthrite</w> - <w f="62" flags="">polynomiales</w> <w f="62" flags="">polythéiste</w> <w f="62" flags="">ponctue</w> <w f="62" flags="">pondu</w> @@ -52102,7 +52077,6 @@ <w f="61" flags="">fécondée</w> <w f="61" flags="">fétichistes</w> <w f="61" flags="">fêta</w> - <w f="61" flags="">galle</w> <w f="61" flags="">gallons</w> <w f="61" flags="">gamelan</w> <w f="61" flags="">gantois</w> @@ -52406,7 +52380,6 @@ <w f="61" flags="">lycanthropes</w> <w f="61" flags="">lymphe</w> <w f="61" flags="">lyrics</w> - <w f="61" flags="">länder</w> <w f="61" flags="">m'appelle</w> <w f="61" flags="">madriers</w> <w f="61" flags="">mafieuses</w> @@ -52462,7 +52435,6 @@ <w f="61" flags="">modifiables</w> <w f="61" flags="">monade</w> <w f="61" flags="">monophysisme</w> - <w f="61" flags="">mons</w> <w f="61" flags="">montgolfières</w> <w f="61" flags="">montreront</w> <w f="61" flags="">monégasques</w> @@ -53890,7 +53862,6 @@ <w f="60" flags="">couteuse</w> <w f="60" flags="">craignit</w> <w f="60" flags="">cramoisi</w> - <w f="60" flags="">crane</w> <w f="60" flags="">cravates</w> <w f="60" flags="">cristallisée</w> <w f="60" flags="">crochu</w> @@ -54259,7 +54230,6 @@ <w f="60" flags="">gazettes</w> <w f="60" flags="">gaziers</w> <w f="60" flags="">gazéification</w> - <w f="60" flags="">gaëlique</w> <w f="60" flags="">geai</w> <w f="60" flags="">gestions</w> <w f="60" flags="">glissée</w> @@ -54422,7 +54392,6 @@ <w f="60" flags="">l'Argens</w> <w f="60" flags="">l'Audiencia</w> <w f="60" flags="">l'Aéro-Club</w> - <w f="60" flags="">l'Eden</w> <w f="60" flags="">l'Est-Anglie</w> <w f="60" flags="">l'Huveaune</w> <w f="60" flags="">l'Ibar</w> @@ -54448,7 +54417,6 @@ <w f="60" flags="">l'apposition</w> <w f="60" flags="">l'aristocrate</w> <w f="60" flags="">l'arrangeur</w> - <w f="60" flags="">l'artefact</w> <w f="60" flags="">l'assignation</w> <w f="60" flags="">l'associer</w> <w f="60" flags="">l'attaquent</w> @@ -54902,6 +54870,7 @@ <w f="60" flags="">rustre</w> <w f="60" flags="">râpé</w> <w f="60" flags="">réaffirmée</w> + <w f="60" flags="">réapparaitre</w> <w f="60" flags="">rébus</w> <w f="60" flags="">réceptionner</w> <w f="60" flags="">réceptionniste</w> @@ -56571,7 +56540,6 @@ <w f="59" flags="">guinées</w> <w f="59" flags="">gustative</w> <w f="59" flags="">guyanaise</w> - <w f="59" flags="">guérillero</w> <w f="59" flags="">gélatineuse</w> <w f="59" flags="">génocidaire</w> <w f="59" flags="">généra</w> @@ -56739,7 +56707,6 @@ <w f="59" flags="abbreviation">l'Ems</w> <w f="59" flags="">l'Erie</w> <w f="59" flags="">l'Espagnole</w> - <w f="59" flags="">l'Esterel</w> <w f="59" flags="">l'Estrémadure</w> <w f="59" flags="abbreviation">l'HMS</w> <w f="59" flags="abbreviation">l'ICC</w> @@ -56853,7 +56820,6 @@ <w f="59" flags="">laminoirs</w> <w f="59" flags="">lasso</w> <w f="59" flags="">latentes</w> - <w f="59" flags="">laure</w> <w f="59" flags="">leishmaniose</w> <w f="59" flags="">lemmings</w> <w f="59" flags="">lenticulaire</w> @@ -57083,7 +57049,6 @@ <w f="59" flags="">pathologiste</w> <w f="59" flags="">pattern</w> <w f="59" flags="">pectoraux</w> - <w f="59" flags="">pedigree</w> <w f="59" flags="">pendage</w> <w f="59" flags="">pensez</w> <w f="59" flags="">perfectif</w> @@ -57296,7 +57261,6 @@ <w f="59" flags="">rotin</w> <w f="59" flags="">rouage</w> <w f="59" flags="">rougir</w> - <w f="59" flags="">râga</w> <w f="59" flags="">râteau</w> <w f="59" flags="">règnera</w> <w f="59" flags="">récollets</w> @@ -57476,7 +57440,6 @@ <w f="59" flags="">survive</w> <w f="59" flags="">surélever</w> <w f="59" flags="">suspicieux</w> - <w f="59" flags="">sutras</w> <w f="59" flags="">suève</w> <w f="59" flags="">swaps</w> <w f="59" flags="">sycomore</w> @@ -58677,7 +58640,6 @@ <w f="58" flags="">d'antiquité</w> <w f="58" flags="">d'appendices</w> <w f="58" flags="">d'arrivées</w> - <w f="58" flags="">d'artefacts</w> <w f="58" flags="">d'artisan</w> <w f="58" flags="">d'arête</w> <w f="58" flags="">d'assauts</w> @@ -59844,7 +59806,6 @@ <w f="58" flags="">savate</w> <w f="58" flags="">scalde</w> <w f="58" flags="">scandaleuses</w> - <w f="58" flags="">scenarii</w> <w f="58" flags="">schwa</w> <w f="58" flags="">scolastiques</w> <w f="58" flags="">scripte</w> @@ -61680,7 +61641,6 @@ <w f="57" flags="">l'avertir</w> <w f="57" flags="">l'aéroclub</w> <w f="57" flags="">l'effectivité</w> - <w f="57" flags="">l'electro</w> <w f="57" flags="">l'ellipsoïde</w> <w f="57" flags="">l'en-but</w> <w f="57" flags="">l'encéphale</w> @@ -61831,7 +61791,6 @@ <w f="57" flags="">multifonctions</w> <w f="57" flags="">multilatérale</w> <w f="57" flags="">multilatérales</w> - <w f="57" flags="">multimedia</w> <w f="57" flags="">multiplexes</w> <w f="57" flags="">multipolaire</w> <w f="57" flags="">muons</w> @@ -62271,7 +62230,6 @@ <w f="57" flags="">savoisienne</w> <w f="57" flags="">saxo</w> <w f="57" flags="">scellement</w> - <w f="57" flags="">scenario</w> <w f="57" flags="">schizophrènes</w> <w f="57" flags="">scintillement</w> <w f="57" flags="">scié</w> @@ -63875,7 +63833,6 @@ <w f="56" flags="">efficience</w> <w f="56" flags="">efficient</w> <w f="56" flags="">el-Cheikh</w> - <w f="56" flags="">el-Kebir</w> <w f="56" flags="">embaucha</w> <w f="56" flags="">embusqué</w> <w f="56" flags="">emmenèrent</w> @@ -64412,7 +64369,6 @@ <w f="56" flags="">mentorat</w> <w f="56" flags="">menues</w> <w f="56" flags="">mercantiliste</w> - <w f="56" flags="">meta</w> <w f="56" flags="">mi-pente</w> <w f="56" flags="">microbiologiste</w> <w f="56" flags="">micrométéorites</w> @@ -65477,7 +65433,6 @@ <w f="55" flags="abbreviation">HBC</w> <w f="55" flags="abbreviation">HII</w> <w f="55" flags="abbreviation">HP-UX</w> - <w f="55" flags="abbreviation">HTA</w> <w f="55" flags="">Haden</w> <w f="55" flags="">Hainan</w> <w f="55" flags="">Hallstatt</w> @@ -66416,7 +66371,6 @@ <w f="55" flags="">d'Alta</w> <w f="55" flags="">d'Aman</w> <w f="55" flags="">d'Anagni</w> - <w f="55" flags="">d'Angoulème</w> <w f="55" flags="">d'Anhalt-Dessau</w> <w f="55" flags="">d'Anticosti</w> <w f="55" flags="">d'Antigua</w> @@ -66587,7 +66541,6 @@ <w f="55" flags="">denticules</w> <w f="55" flags="">dessécher</w> <w f="55" flags="">destitua</w> - <w f="55" flags="">devanagari</w> <w f="55" flags="">diabolo</w> <w f="55" flags="">dialoguent</w> <w f="55" flags="">diastolique</w> @@ -66599,7 +66552,6 @@ <w f="55" flags="">digipack</w> <w f="55" flags="">dilapide</w> <w f="55" flags="">diluant</w> - <w f="55" flags="">dime</w> <w f="55" flags="">diptère</w> <w f="55" flags="">directivité</w> <w f="55" flags="">disculpé</w> @@ -66838,7 +66790,6 @@ <w f="55" flags="">flavescence</w> <w f="55" flags="">fleurettiste</w> <w f="55" flags="">flexionnelle</w> - <w f="55" flags="">florès</w> <w f="55" flags="">fluo</w> <w f="55" flags="">fléchi</w> <w f="55" flags="">fondirent</w> @@ -67156,7 +67107,6 @@ <w f="55" flags="">l'ainée</w> <w f="55" flags="">l'ajournement</w> <w f="55" flags="">l'allocution</w> - <w f="55" flags="">l'ambigüité</w> <w f="55" flags="">l'ambitieuse</w> <w f="55" flags="">l'angine</w> <w f="55" flags="">l'antifascisme</w> @@ -67694,6 +67644,7 @@ <w f="55" flags="">qu'Eugène</w> <w f="55" flags="">qu'Henry</w> <w f="55" flags="">qu'Ibn</w> + <w f="55" flags="">qu'apparait</w> <w f="55" flags="">qu'association</w> <w f="55" flags="">qu'enfant</w> <w f="55" flags="">qu'entraîneur-joueur</w> @@ -69943,7 +69894,6 @@ <w f="54" flags="">mennonite</w> <w f="54" flags="">mentent</w> <w f="54" flags="">mercy</w> - <w f="54" flags="">mesa</w> <w f="54" flags="">meseta</w> <w f="54" flags="">mesurera</w> <w f="54" flags="">meublées</w> @@ -70487,7 +70437,6 @@ <w f="54" flags="">survola</w> <w f="54" flags="">suscitaient</w> <w f="54" flags="">susvisé</w> - <w f="54" flags="">sutra</w> <w f="54" flags="">synchronique</w> <w f="54" flags="">synchronisme</w> <w f="54" flags="">syncopé</w> @@ -72014,7 +71963,6 @@ <w f="53" flags="">d'Ayen</w> <w f="53" flags="">d'Eberhard</w> <w f="53" flags="">d'Echéry</w> - <w f="53" flags="">d'Ecouen</w> <w f="53" flags="">d'Efteling</w> <w f="53" flags="">d'Eichmann</w> <w f="53" flags="">d'Elisa</w> @@ -73120,7 +73068,6 @@ <w f="53" flags="">parpaings</w> <w f="53" flags="">partiale</w> <w f="53" flags="">partirait</w> - <w f="53" flags="">paseo</w> <w f="53" flags="">passacaille</w> <w f="53" flags="">pataphysique</w> <w f="53" flags="">patibulaire</w> @@ -74939,6 +74886,7 @@ <w f="52" flags="">congeler</w> <w f="52" flags="">congélateurs</w> <w f="52" flags="">conseillera</w> + <w f="52">conseillerais</w> <w f="52" flags="">conseillères</w> <w f="52" flags="">consolidations</w> <w f="52" flags="">consoude</w> @@ -75209,7 +75157,6 @@ <w f="52" flags="">divergeant</w> <w f="52" flags="">divisera</w> <w f="52" flags="">doline</w> - <w f="52" flags="">dona</w> <w f="52" flags="">donnât</w> <w f="52" flags="">dope</w> <w f="52" flags="">dormeurs</w> @@ -75428,7 +75375,6 @@ <w f="52" flags="">félibre</w> <w f="52" flags="">férue</w> <w f="52" flags="">fût-elle</w> - <w f="52" flags="">fÅ“hn</w> <w f="52" flags="">gaité</w> <w f="52" flags="">gallicans</w> <w f="52" flags="">galope</w> @@ -77912,10 +77858,8 @@ <w f="51" flags="">gaspillé</w> <w f="51" flags="">gauchisme</w> <w f="51" flags="">gaves</w> - <w f="51" flags="">genera</w> <w f="51" flags="">genette</w> <w f="51" flags="">gente</w> - <w f="51" flags="">gentile</w> <w f="51" flags="">gentium</w> <w f="51" flags="">gibbons</w> <w f="51" flags="">gicleur</w> @@ -80527,7 +80471,6 @@ <w f="50" flags="">liner</w> <w f="50" flags="">lingue</w> <w f="50" flags="">linnéen</w> - <w f="50" flags="">linoleum</w> <w f="50" flags="">linoléum</w> <w f="50" flags="">linéarisation</w> <w f="50" flags="">lipase</w> @@ -80564,7 +80507,6 @@ <w f="50" flags="">magnétisation</w> <w f="50" flags="">magnéto</w> <w f="50" flags="">magnétohydrodynamique</w> - <w f="50" flags="">mahârâja</w> <w f="50" flags="">majorer</w> <w f="50" flags="">majorettes</w> <w f="50" flags="">makhzen</w> @@ -83070,7 +83012,6 @@ <w f="49" flags="">l'Ambigu</w> <w f="49" flags="">l'Astra</w> <w f="49" flags="">l'Ecclésia</w> - <w f="49" flags="">l'Estérel</w> <w f="49" flags="">l'IDH</w> <w f="49" flags="abbreviation">l'ISA</w> <w f="49" flags="abbreviation">l'InVS</w> @@ -83417,7 +83358,6 @@ <w f="49" flags="">octosyllabiques</w> <w f="49" flags="">offensés</w> <w f="49" flags="">oisiveté</w> - <w f="49" flags="">omega</w> <w f="49" flags="">omoplate</w> <w f="49" flags="">oncogène</w> <w f="49" flags="">oncologie</w> @@ -85347,7 +85287,6 @@ <w f="48" flags="">césarisme</w> <w f="48" flags="">césures</w> <w f="48" flags="">côtoiera</w> - <w f="48" flags="">d'Ares</w> <w f="48" flags="">d'Axa</w> <w f="48" flags="">d'Hemingway</w> <w f="48" flags="abbreviation">d'URL</w> @@ -85768,7 +85707,6 @@ <w f="48" flags="">gaucherie</w> <w f="48" flags="">gelant</w> <w f="48" flags="">gendarmeries</w> - <w f="48" flags="">gene</w> <w f="48" flags="">genin</w> <w f="48" flags="">genouillères</w> <w f="48" flags="">gentianes</w> @@ -85806,7 +85744,6 @@ <w f="48" flags="">gueuse</w> <w f="48" flags="">guinée</w> <w f="48" flags="">gujarati</w> - <w f="48" flags="">gurû</w> <w f="48" flags="">guéries</w> <w f="48" flags="">guérira</w> <w f="48" flags="">guérisse</w> @@ -86135,7 +86072,6 @@ <w f="48" flags="">lamentant</w> <w f="48" flags="">lamenter</w> <w f="48" flags="">laminée</w> - <w f="48" flags="">lander</w> <w f="48" flags="">lands</w> <w f="48" flags="">langoureux</w> <w f="48" flags="">laotiennes</w> @@ -86293,7 +86229,6 @@ <w f="48" flags="">mésosphère</w> <w f="48" flags="">métalangage</w> <w f="48" flags="">mît</w> - <w f="48" flags="">môns</w> <w f="48" flags="">n'aboutiront</w> <w f="48" flags="">n'accorda</w> <w f="48" flags="">n'apprit</w> @@ -87166,7 +87101,6 @@ <w f="47" flags="">Avellino</w> <w f="47" flags="">Avesnes</w> <w f="47" flags="">Ayutthaya</w> - <w f="47" flags="abbreviation">BOF</w> <w f="47" flags="">Babin</w> <w f="47" flags="">Bagotville</w> <w f="47" flags="">Bainville</w> @@ -87876,6 +87810,7 @@ <w f="47" flags="">blitzkrieg</w> <w f="47" flags="">boards</w> <w f="47" flags="">boas</w> + <w f="47" flags="abbreviation">bof</w> <w f="47" flags="">bomba</w> <w f="47" flags="">bomber</w> <w f="47" flags="">bombés</w> @@ -87988,7 +87923,6 @@ <w f="47" flags="">clinicienne</w> <w f="47" flags="">cloisonnements</w> <w f="47" flags="">closerie</w> - <w f="47" flags="">clot</w> <w f="47" flags="">cloîtrées</w> <w f="47" flags="">clématite</w> <w f="47" flags="">clôturera</w> @@ -88967,7 +88901,6 @@ <w f="47" flags="">pesanteurs</w> <w f="47" flags="">petit-duc</w> <w f="47" flags="">peupla</w> - <w f="47" flags="">peña</w> <w f="47" flags="">phalangiste</w> <w f="47" flags="">pharmacocinétique</w> <w f="47" flags="">phasmes</w> @@ -91145,7 +91078,6 @@ <w f="46" flags="">impudique</w> <w f="46" flags="">impulsa</w> <w f="46" flags="">impulsifs</w> - <w f="46" flags="">imâm</w> <w f="46" flags="abbreviation">ina</w> <w f="46" flags="">inapplicables</w> <w f="46" flags="">incandescents</w> @@ -91300,7 +91232,6 @@ <w f="46" flags="">l'ex-directeur</w> <w f="46" flags="">l'ex-épouse</w> <w f="46" flags="">l'examine</w> - <w f="46" flags="">l'exigüité</w> <w f="46" flags="">l'expatriation</w> <w f="46" flags="">l'expliquent</w> <w f="46" flags="">l'exploratrice</w> @@ -91441,13 +91372,11 @@ <w f="46" flags="">martyriser</w> <w f="46" flags="">masseuse</w> <w f="46" flags="">mastectomie</w> - <w f="46" flags="">mega</w> <w f="46" flags="">membrée</w> <w f="46" flags="">mentant</w> <w f="46" flags="">mentionnèrent</w> <w f="46" flags="">menuets</w> <w f="46" flags="">mer-sol</w> - <w f="46" flags="">metro</w> <w f="46" flags="">mi-championnat</w> <w f="46" flags="">micocoulier</w> <w f="46" flags="">micro-algues</w> @@ -93469,7 +93398,6 @@ <w f="45" flags="">concouraient</w> <w f="45" flags="">concourra</w> <w f="45" flags="">condensations</w> - <w f="45" flags="">condottieres</w> <w f="45" flags="">confectionna</w> <w f="45" flags="">configurées</w> <w f="45" flags="">conflagration</w> @@ -96795,7 +96723,6 @@ <w f="44" flags="">eschatologie</w> <w f="44" flags="">escomptées</w> <w f="44" flags="">espar</w> - <w f="44" flags="">esperanto</w> <w f="44" flags="">espionnait</w> <w f="44" flags="">esquivant</w> <w f="44" flags="">essaimage</w> @@ -97285,9 +97212,7 @@ <w f="44" flags="">laryngite</w> <w f="44" flags="">laryngé</w> <w f="44" flags="">latéralité</w> - <w f="44" flags="">lauré</w> <w f="44" flags="">laze</w> - <w f="44" flags="">leges</w> <w f="44" flags="">lestées</w> <w f="44" flags="">lettrages</w> <w f="44" flags="">levantine</w> @@ -97372,7 +97297,6 @@ <w f="44" flags="">micronoyaux</w> <w f="44" flags="">miette</w> <w f="44" flags="">militarisés</w> - <w f="44" flags="">millenium</w> <w f="44" flags="">millerandage</w> <w f="44" flags="">minant</w> <w f="44" flags="">mini-jupe</w> @@ -99977,7 +99901,6 @@ <w f="43" flags="">mnémoniques</w> <w f="43" flags="">mobilisera</w> <w f="43" flags="">modifieront</w> - <w f="43" flags="">moitie</w> <w f="43" flags="">molester</w> <w f="43" flags="">mona</w> <w f="43" flags="">monistes</w> @@ -101868,7 +101791,6 @@ <w f="42" flags="">dichotomies</w> <w f="42" flags="">dichotomiques</w> <w f="42" flags="">dilapidations</w> - <w f="42" flags="">dimes</w> <w f="42" flags="">diplodocus</w> <w f="42" flags="">disait-elle</w> <w f="42" flags="">discréditées</w> @@ -102899,7 +102821,6 @@ <w f="42" flags="">restituait</w> <w f="42" flags="">retracés</w> <w f="42" flags="">retranscrivent</w> - <w f="42" flags="">retro</w> <w f="42" flags="">retrouvez</w> <w f="42" flags="">reversant</w> <w f="42" flags="">revirent</w> @@ -104901,7 +104822,6 @@ <w f="41" flags="">garde-temps</w> <w f="41" flags="">gardes-pêche</w> <w f="41" flags="">gastroentérite</w> - <w f="41" flags="">gates</w> <w f="41" flags="">gaufrier</w> <w f="41" flags="">gaules</w> <w f="41" flags="">gaussiens</w> @@ -105532,7 +105452,6 @@ <w f="41" flags="">plafonnées</w> <w f="41" flags="">plaisanté</w> <w f="41" flags="">planctons</w> - <w f="41" flags="">plantagenêt</w> <w f="41" flags="">plantera</w> <w f="41" flags="">plaqueminier</w> <w f="41" flags="">playa</w> @@ -108603,7 +108522,6 @@ <w f="40" flags="">radiatives</w> <w f="40" flags="">radiophare</w> <w f="40" flags="">radiosondes</w> - <w f="40" flags="">raga</w> <w f="40" flags="">rages</w> <w f="40" flags="">rainbow</w> <w f="40" flags="">rainuré</w> @@ -108827,7 +108745,6 @@ <w f="40" flags="">sarclage</w> <w f="40" flags="">satori</w> <w f="40" flags="">saturations</w> - <w f="40" flags="">satî</w> <w f="40" flags="">saupoudrage</w> <w f="40" flags="">saurez</w> <w f="40" flags="">sauvez</w> @@ -111688,7 +111605,6 @@ <w f="39" flags="">monèmes</w> <w f="39" flags="">moralisant</w> <w f="39" flags="">moro</w> - <w f="39" flags="">moré</w> <w f="39" flags="">mosaïsme</w> <w f="39" flags="">moteur-boîte</w> <w f="39" flags="">motivèrent</w> @@ -111728,6 +111644,7 @@ <w f="39" flags="">n'adopta</w> <w f="39" flags="">n'agissant</w> <w f="39" flags="">n'allèrent</w> + <w f="39">n'apportez</w> <w f="39" flags="">n'approcha</w> <w f="39" flags="">n'atteindrait</w> <w f="39" flags="">n'empêchaient</w> @@ -115033,7 +114950,6 @@ <w f="37" flags="">croyait-on</w> <w f="37" flags="">cryptogrammes</w> <w f="37" flags="">créancière</w> - <w f="37" flags="">crémerie</w> <w f="37" flags="">crénelages</w> <w f="37" flags="">crépue</w> <w f="37" flags="">crétacées</w> @@ -115728,7 +115644,6 @@ <w f="37" flags="">harkas</w> <w f="37" flags="">harnachements</w> <w f="37" flags="">hast</w> - <w f="37" flags="">haste</w> <w f="37" flags="">hellénisants</w> <w f="37" flags="">hennin</w> <w f="37" flags="">herbagers</w> @@ -118031,7 +117946,6 @@ <w f="36" flags="">doutons</w> <w f="36" flags="">doyennes</w> <w f="36" flags="">drives</w> - <w f="36" flags="">drivé</w> <w f="36" flags="">droguées</w> <w f="36" flags="">droitières</w> <w f="36" flags="">ductus</w> @@ -119687,6 +119601,7 @@ <w f="35" flags="">appelleraient</w> <w f="35" flags="">appoggiatures</w> <w f="35" flags="">appointée</w> + <w f="35">apporteriez</w> <w f="35" flags="">apposèrent</w> <w f="35" flags="">apprendraient</w> <w f="35" flags="">approprie</w> @@ -120848,7 +120763,6 @@ <w f="35" flags="">fantasmatiques</w> <w f="35" flags="">fardage</w> <w f="35" flags="">faro</w> - <w f="35" flags="">fasciculés</w> <w f="35" flags="">fascinaient</w> <w f="35" flags="">fascisation</w> <w f="35" flags="">fayard</w> @@ -121985,7 +121899,6 @@ <w f="35" flags="">pastore</w> <w f="35" flags="">pataude</w> <w f="35" flags="">patauge</w> - <w f="35" flags="">pati</w> <w f="35" flags="">paturon</w> <w f="35" flags="">paturons</w> <w f="35" flags="">patènes</w> @@ -123976,7 +123889,6 @@ <w f="34" flags="">déviateur</w> <w f="34" flags="">dîna</w> <w f="34" flags="">ectopiques</w> - <w f="34" flags="">eden</w> <w f="34" flags="">effectueraient</w> <w f="34" flags="">effraies</w> <w f="34" flags="">effritée</w> @@ -124531,7 +124443,6 @@ <w f="34" flags="">mestres</w> <w f="34" flags="">mesureront</w> <w f="34" flags="">meublent</w> - <w f="34" flags="">mi-aout</w> <w f="34" flags="">mi-humaines</w> <w f="34" flags="">mi-voix</w> <w f="34" flags="">micelle</w> @@ -127052,7 +126963,6 @@ <w f="33" flags="">pavanes</w> <w f="33" flags="">pavant</w> <w f="33" flags="">pavimenteux</w> - <w f="33" flags="">penelope</w> <w f="33" flags="">pensionna</w> <w f="33" flags="">pentacles</w> <w f="33" flags="">perborate</w> @@ -131024,7 +130934,6 @@ <w f="31" flags="">châtelaines</w> <w f="31" flags="">chènevières</w> <w f="31" flags="">cicatrisante</w> - <w f="31" flags="">cicéro</w> <w f="31" flags="">cicéronienne</w> <w f="31" flags="">cimentant</w> <w f="31" flags="">cincles</w> @@ -131800,7 +131709,6 @@ <w f="31" flags="">grattés</w> <w f="31" flags="">gravissaient</w> <w f="31" flags="">gravois</w> - <w f="31" flags="">greco</w> <w f="31" flags="">grecs-orthodoxes</w> <w f="31" flags="">greffera</w> <w f="31" flags="">grenadines</w> @@ -131965,7 +131873,6 @@ <w f="31" flags="">ivresses</w> <w f="31" flags="">j'écoutais</w> <w f="31" flags="">jaillie</w> - <w f="31" flags="">jaina</w> <w f="31" flags="">jamaïquaines</w> <w f="31" flags="">janus</w> <w f="31" flags="">javelles</w> @@ -132169,7 +132076,6 @@ <w f="31" flags="">lattée</w> <w f="31" flags="">laudatives</w> <w f="31" flags="">lavandins</w> - <w f="31" flags="">leger</w> <w f="31" flags="">levantines</w> <w f="31" flags="">lexicologiques</w> <w f="31" flags="">libéralisa</w> @@ -132223,7 +132129,6 @@ <w f="31" flags="">macro-algues</w> <w f="31" flags="">macrocéphale</w> <w f="31" flags="">macèrent</w> - <w f="31" flags="">maelstrom</w> <w f="31" flags="">magnésiennes</w> <w f="31" flags="">magnétisées</w> <w f="31" flags="">mahométan</w> @@ -134732,7 +134637,6 @@ <w f="30" flags="">farcit</w> <w f="30" flags="">fardé</w> <w f="30" flags="">fasciation</w> - <w f="30" flags="">fasciculé</w> <w f="30" flags="">fascinations</w> <w f="30" flags="">faucha</w> <w f="30" flags="">fausse-renoncule</w> @@ -136328,6 +136232,8 @@ <w f="30" flags="">sérails</w> <w f="30" flags="">sérialisée</w> <w f="30" flags="">séricigènes</w> + <w f="30">t'adresser</w> + <w f="30">t'adresses</w> <w f="30" flags="">t'aider</w> <w f="30" flags="">t'emmerde</w> <w f="30" flags="">taboues</w> @@ -137547,7 +137453,6 @@ <w f="28" flags="">d'arrangeurs</w> <w f="28" flags="">d'arrhes</w> <w f="28" flags="">d'arrière-plans</w> - <w f="28" flags="">d'artefact</w> <w f="28" flags="">d'arythmies</w> <w f="28" flags="">d'assurance-crédit</w> <w f="28" flags="">d'astigmatisme</w> @@ -138268,7 +138173,6 @@ <w f="28" flags="">herbager</w> <w f="28" flags="">herborisa</w> <w f="28" flags="">herculéen</w> - <w f="28" flags="">herpes</w> <w f="28" flags="">hiatale</w> <w f="28" flags="">histidines</w> <w f="28" flags="">hivernages</w> @@ -146791,11 +146695,9 @@ <w f="25" flags="">fédé</w> <w f="25" flags="">fédéral-provincial</w> <w f="25" flags="">félicitaient</w> - <w f="25" flags="">féra</w> <w f="25" flags="">gagnais</w> <w f="25" flags="">gaillets</w> <w f="25" flags="">gainiers</w> - <w f="25" flags="">gallé</w> <w f="25" flags="">galonnés</w> <w f="25" flags="">galoubet-tambourin</w> <w f="25" flags="">galoubets</w> @@ -147598,7 +147500,6 @@ <w f="25" flags="">maçonnes</w> <w f="25" flags="">maïzena</w> <w f="25" flags="">melba</w> - <w f="25" flags="">melissa</w> <w f="25" flags="">menteuses</w> <w f="25" flags="">mentholée</w> <w f="25" flags="">mentionnerons</w> @@ -147712,7 +147613,6 @@ <w f="25" flags="">mouvaient</w> <w f="25" flags="">moyen-bavarois</w> <w f="25" flags="">moyen-néerlandais</w> - <w f="25" flags="">moëres</w> <w f="25" flags="">mugir</w> <w f="25" flags="">multivariées</w> <w f="25" flags="">musé</w> @@ -151397,7 +151297,6 @@ <w f="23" flags="">dandiner</w> <w f="23" flags="">dansais</w> <w f="23" flags="">danse-contact</w> - <w f="23" flags="">daphne</w> <w f="23" flags="">dardes</w> <w f="23" flags="">daring</w> <w f="23" flags="">dariques</w> @@ -152474,7 +152373,6 @@ <w f="23" flags="">kantiens</w> <w f="23" flags="">keno</w> <w f="23" flags="">khamsin</w> - <w f="23" flags="">khân</w> <w f="23" flags="">kiki</w> <w f="23" flags="">kilkenny</w> <w f="23" flags="">kinder</w> @@ -152886,7 +152784,6 @@ <w f="23" flags="">lacèrent</w> <w f="23" flags="">lacée</w> <w f="23" flags="">lae</w> - <w f="23" flags="">laiche</w> <w f="23" flags="">laideron</w> <w f="23" flags="">laisse-toi</w> <w f="23" flags="">laisseras</w> @@ -153811,7 +153708,6 @@ <w f="23" flags="">poissonnières</w> <w f="23" flags="">poissé</w> <w f="23" flags="">polacre</w> - <w f="23" flags="">polaroid</w> <w f="23" flags="">polatouches</w> <w f="23" flags="">polissons</w> <w f="23" flags="">pollupostage</w> @@ -154711,7 +154607,6 @@ <w f="23" flags="">servocommande</w> <w f="23" flags="">servomécanismes</w> <w f="23" flags="">sexagésimaux</w> - <w f="23" flags="">shâh</w> <w f="23" flags="">siccatifs</w> <w f="23" flags="">sifflaient</w> <w f="23" flags="">sillages</w> @@ -155963,6 +155858,7 @@ <w f="21" flags="">Motte-Saint-Valentin</w> <w f="21" flags="">Moulin-Brûlé</w> <w f="21" flags="">Musser</w> + <w f="21" flags="">Mélissa</w> <w f="21" flags="">Métro-Richelieu</w> <w f="21" flags="">Mézières-en-Gâtinais</w> <w f="21" flags="">Napoléon-Charles</w> @@ -158839,7 +158735,6 @@ <w f="21" flags="">hee</w> <w f="21" flags="">heller</w> <w f="21" flags="">hellénismes</w> - <w f="21" flags="">herbés</w> <w f="21" flags="">herve</w> <w f="21" flags="">heurtons</w> <w f="21" flags="">hiberné</w> @@ -159635,7 +159530,6 @@ <w f="21" flags="">lactifères</w> <w f="21" flags="">lacéra</w> <w f="21" flags="">laguerre</w> - <w f="21" flags="">laiches</w> <w f="21" flags="">laisserais</w> <w f="21" flags="">lamentos</w> <w f="21" flags="">lamentèrent</w> @@ -160062,7 +159956,6 @@ <w f="21" flags="">méga-corporation</w> <w f="21" flags="">mélamine-formaldéhyde</w> <w f="21" flags="">mélangeront</w> - <w f="21" flags="">mélissa</w> <w f="21" flags="">mémorisait</w> <w f="21" flags="">ménologes</w> <w f="21" flags="">ménopausique</w> @@ -160666,7 +160559,6 @@ <w f="21" flags="">peinard</w> <w f="21" flags="">peinez</w> <w f="21" flags="">peinturer</w> - <w f="21" flags="">pelagos</w> <w f="21" flags="">pelliculée</w> <w f="21" flags="">peltaste</w> <w f="21" flags="">pelté</w> @@ -165431,7 +165323,6 @@ <w f="18" flags="">crédit-carbone</w> <w f="18" flags="">créditera</w> <w f="18" flags="">crédulités</w> - <w f="18" flags="">crémeries</w> <w f="18" flags="">crénelées-dentelées</w> <w f="18" flags="">créolisés</w> <w f="18" flags="">créosotes</w> @@ -170056,7 +169947,6 @@ <w f="18" flags="">position-impulsion</w> <w f="18" flags="">postulations</w> <w f="18" flags="">posât</w> - <w f="18" flags="">potencé</w> <w f="18" flags="">potentialisé</w> <w f="18" flags="">potenza</w> <w f="18" flags="">potestative</w> @@ -172484,7 +172374,6 @@ <w f="18" flags="">écartes</w> <w f="18" flags="">échafaudant</w> <w f="18" flags="">échafaudèrent</w> - <w f="18" flags="">échancre</w> <w f="18" flags="">échangeons</w> <w f="18" flags="">échangeraient</w> <w f="18" flags="">écharper</w> @@ -172751,7 +172640,6 @@ <w f="15" flags="">Antoinette-Élisabeth</w> <w f="15" flags="">Anvers-Bruxelles</w> <w f="15" flags="">Anvers-Wavre</w> - <w f="15" flags="">Apportez-moi</w> <w f="15" flags="">Arbre-Saint-Pierre</w> <w f="15" flags="">Ardenne-Rives-de-Meuse</w> <w f="15" flags="">Argas</w> @@ -173065,6 +172953,7 @@ <w f="15" flags="">Château-Voué</w> <w f="15" flags="">Château-sur-Aisne</w> <w f="15" flags="">Chérasse</w> + <w f="15" flags="">Cicero</w> <w f="15" flags="">Cinq-Chemins</w> <w f="15" flags="">Cinq-Moulins</w> <w f="15" flags="">Cinq-Provinces</w> @@ -174677,6 +174566,7 @@ <w f="15" flags="">apporte-t-il</w> <w f="15" flags="">apporterez</w> <w f="15" flags="">apportes</w> + <w f="15" flags="">apportez-moi</w> <w f="15" flags="">apprend-t-on</w> <w f="15" flags="">apprenti-dessinateur</w> <w f="15" flags="">apprenti-pâtissier</w> @@ -175926,8 +175816,6 @@ <w f="15" flags="">ciboriums</w> <w f="15" flags="">cicatrisations</w> <w f="15" flags="">cicatrisés</w> - <w f="15" flags="">cicero</w> - <w f="15" flags="">cicéros</w> <w f="15" flags="">ciel-terre</w> <w f="15" flags="">cillées</w> <w f="15" flags="">cimentera</w> @@ -179207,7 +179095,6 @@ <w f="15" flags="">gemmologiste</w> <w f="15" flags="">gentillets</w> <w f="15" flags="">gentillettes</w> - <w f="15" flags="">genépi</w> <w f="15" flags="">gercées</w> <w f="15" flags="">germanisa</w> <w f="15" flags="">germinaux</w> @@ -179448,7 +179335,6 @@ <w f="15" flags="">heng</w> <w f="15" flags="">hennissant</w> <w f="15" flags="">heptagones</w> - <w f="15" flags="">herbé</w> <w f="15" flags="">herméticité</w> <w f="15" flags="">herri</w> <w f="15" flags="">hersages</w> @@ -180957,7 +180843,6 @@ <w f="15" flags="">limitez</w> <w f="15" flags="">limonites</w> <w f="15" flags="">limée</w> - <w f="15" flags="">limón</w> <w f="15" flags="">lingotières</w> <w f="15" flags="">liniers</w> <w f="15" flags="">linotypie</w> @@ -182796,7 +182681,6 @@ <w f="15" flags="">passage-clef</w> <w f="15" flags="">passagers-kilomètres</w> <w f="15" flags="">passassent</w> - <w f="15" flags="">passat</w> <w f="15" flags="">passe-plats</w> <w f="15" flags="">passe-rose</w> <w f="15" flags="">passementière</w> @@ -182844,7 +182728,6 @@ <w f="15" flags="">pelas</w> <w f="15" flags="">pelliculées</w> <w f="15" flags="">pelotonnée</w> - <w f="15" flags="">peléen</w> <w f="15" flags="">peléennes</w> <w f="15" flags="">penchât</w> <w f="15" flags="">pense-il</w> @@ -182868,7 +182751,6 @@ <w f="15" flags="">perdit-il</w> <w f="15" flags="">perdureraient</w> <w f="15" flags="">perdîmes</w> - <w f="15" flags="">peres</w> <w f="15" flags="">perfectionneront</w> <w f="15" flags="">perfoliées</w> <w f="15" flags="">perforera</w> @@ -183005,7 +182887,6 @@ <w f="15" flags="">planchera</w> <w f="15" flags="">planchéiée</w> <w f="15" flags="">planeuse</w> - <w f="15" flags="">plantagenet</w> <w f="15" flags="">planteraient</w> <w f="15" flags="">planteuses</w> <w f="15" flags="">plastiqueurs</w> @@ -187747,7 +187628,6 @@ <w f="10" flags="">côtoyez</w> <w f="10" flags="">d'Agnat</w> <w f="10" flags="">d'Albert-le-Grand</w> - <w f="10" flags="">d'Ales</w> <w f="10" flags="">d'Algérien</w> <w f="10" flags="">d'Angoumois-infanterie</w> <w f="10" flags="">d'Anonyme</w> @@ -188046,7 +187926,6 @@ <w f="10" flags="">ferryboat</w> <w f="10" flags="">feule</w> <w f="10" flags="">fichier-clef</w> - <w f="10" flags="">fieffe</w> <w f="10" flags="">fieffer</w> <w f="10" flags="">fies</w> <w f="10" flags="">fieu</w> @@ -188231,7 +188110,6 @@ <w f="10" flags="">hava</w> <w f="10" flags="">havir</w> <w f="10" flags="">hebdomadiers</w> - <w f="10" flags="">hela</w> <w f="10" flags="">helminthe</w> <w f="10" flags="">henni</w> <w f="10" flags="">herzégovine</w> @@ -188729,7 +188607,6 @@ <w f="10" flags="">malpolis</w> <w f="10" flags="">malta</w> <w f="10" flags="">malter</w> - <w f="10" flags="">malé</w> <w f="10" flags="">mancha</w> <w f="10" flags="">mangano</w> <w f="10" flags="">mante-religieuse</w> @@ -189012,7 +188889,6 @@ <w f="10" flags="">pastelle</w> <w f="10" flags="">pasteurienne</w> <w f="10" flags="">pastillas</w> - <w f="10" flags="">paséo</w> <w f="10" flags="">patachons</w> <w f="10" flags="">patay</w> <w f="10" flags="">patoche</w> @@ -191229,7 +191105,6 @@ <w f="1" flags="">miton</w> <w f="1" flags="">moblots</w> <w f="1" flags="">moch</w> - <w f="1" flags="">moeres</w> <w f="1" flags="">moha</w> <w f="1" flags="">moisant</w> <w f="1" flags="">moise</w> @@ -191271,7 +191146,6 @@ <w f="1" flags="">mémère</w> <w f="1" flags="">ménine</w> <w f="1" flags="">ményanthe</w> - <w f="1" flags="">mésa</w> <w f="1" flags="">métra</w> <w f="1" flags="">métromanie</w> <w f="1" flags="">mézeray</w> @@ -191837,6 +191711,7 @@ <w f="0" flags="e">gouine</w> <w f="0" flags="n">gousse</w> <w f="0" flags="n">gémissement</w> + <w f="0">haha</w> <w f="0" flags="n">hardcore</w> <w f="0" flags="n">hermaphrodite</w> <w f="0" flags="e">homo</w> diff --git a/java/proguard.flags b/java/proguard.flags index 752ced3e37..ca205b9279 100644 --- a/java/proguard.flags +++ b/java/proguard.flags @@ -3,10 +3,6 @@ <init>(...); } --keep class com.android.inputmethod.latin.Flag { - *; -} - -keep class com.android.inputmethod.keyboard.ProximityInfo { <init>(com.android.inputmethod.keyboard.ProximityInfo); } diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict index 98a9361b586582d61e3446e509023902a15bb340..e02e300e4c0a69e2c670be0ee4c3a2336288c97c 100644 GIT binary patch delta 1722 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 delta 1789 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 diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict index 717078c93031f228fabbefb1da4166970eadeb1c..8e616591c15d0962ac6ce15e8f024aa90022a2b2 100644 GIT binary patch delta 12047 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 PCF^v`t6yck()s@YEa*<r delta 12610 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 Di^uD- diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml index 22543efe5a..2738328133 100644 --- a/java/res/values-af/strings.xml +++ b/java/res/values-af/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Verstek"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Stel kontakname voor"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gebruik name van kontakte vir voorstelle en korreksies"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Aktiveer herkorrigerings"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Stel voorstelle vir herkorrigerings"</string> <string name="auto_cap" msgid="1719746674854628252">"Outohoofletters"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Voeg woordeboeke by"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hoofwoordeboek"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Matig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressief"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Baie aggressief"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Volgendewoordvoorstelle"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gebruik vorige woord om voorstelle te verbeter"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Volgendewoordvoorspelling"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gebruik vorige woord ook vir voorspelling"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Volgende woordvoorstelle"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Gebaseer op vorige woord"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Gestoor"</string> <string name="label_go_key" msgid="1635148082137219148">"Gaan"</string> <string name="label_next_key" msgid="362972844525672568">"Volgende"</string> diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml index a1b168cb7a..a6373ccb6a 100644 --- a/java/res/values-am/strings.xml +++ b/java/res/values-am/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"áŠá‰£áˆª"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"የዕá‹á‰‚á‹« ስሠጠá‰áˆ"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ከዕá‹á‰‚ያዎች ለጥቆማዎች እና ማስተካከያዎች ስሞች ተጠቀáˆ"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"ድጋሚ ለማስተካከሠአንቃ"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"ድጋሚ ለማስተካከሠጥቆማዎችን አዘጋጅ"</string> <string name="auto_cap" msgid="1719746674854628252">"ራስ-ሰሠአቢዠማድረáŒ"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"መá‹áŒˆá‰ ቃላቶች ጨáˆáˆ"</string> <string name="main_dictionary" msgid="4798763781818361168">"ዋና መá‹áŒˆá‰ ቃላት"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"መጠáŠáŠ›"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"ኃá‹áˆˆáŠ›"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"በጣሠá‰áŒ¡"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"የቀጣዠቃሠአስተያየቶች"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"áˆáŠáˆ®á‰½áŠ• ለማሻሻሠቀዳሚ ቃሠተጠቀáˆ"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"የቀጣዠቃሠáŒáˆá‰µ"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ለትንበያ የቀደመ ቃሠእንዲሠተጠቀáˆ"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"የቀጣዠቃሠአስተያየቶች"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"በቀዳሚዠቃሠላዠየተመሠረተ"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ተቀáˆáŒ§áˆ"</string> <string name="label_go_key" msgid="1635148082137219148">"ሂድ"</string> <string name="label_next_key" msgid="362972844525672568">"በመቀጠáˆ"</string> diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml index 2a22074473..9e6f1ea513 100644 --- a/java/res/values-ar/strings.xml +++ b/java/res/values-ar/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"اÙتراضي"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Ø§Ù‚ØªØ±Ø§Ø Ø£Ø³Ù…Ø§Ø¡ جهات الاتصال"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"استخدام الأسماء من جهات الاتصال للاقتراØات والتصØÙŠØات"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"تمكين عمليات إعادة التصØÙŠØ"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"تعيين اقتراØات لعمليات إعادة التصØÙŠØ"</string> <string name="auto_cap" msgid="1719746674854628252">"Ø£Øر٠كبيرة تلقائيًا"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"القواميس الإضاÙية"</string> <string name="main_dictionary" msgid="4798763781818361168">"القاموس الرئيسي"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"معتدل"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Øاد"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"شديد الصرامة"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"اقتراØات الكلمات التالية"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"استخدام الكلمة السابقة لتØسين الاقتراØات"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"تنبؤ الكلمات التالية"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"استخدام الكلمة السابقة أيضًا للتنبؤ"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"اقتراØات الكلمات التالية"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"استنادًا إلى الكلمة السابقة"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الØÙظ"</string> <string name="label_go_key" msgid="1635148082137219148">"تنÙيذ"</string> <string name="label_next_key" msgid="362972844525672568">"التالي"</string> diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml index ff3213ad60..fb371f4c3d 100644 --- a/java/res/values-be/strings.xml +++ b/java/res/values-be/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Па змаўчанні"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Прапан. імёны кантактаў"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ВыкарыÑтоўваць імёны Ñа ÑпіÑу кантактаў Ð´Ð»Ñ Ð¿Ñ€Ð°Ð¿Ð°Ð½Ð¾Ñž Ñ– выпраўл."</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Уключыць карÑкцiроўкі"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Задаць прапановы Ð´Ð»Ñ ÐºÐ°Ñ€Ñкцiроўкі"</string> <string name="auto_cap" msgid="1719746674854628252">"Ðўтаматычна рабіць вÑÐ»Ñ–ÐºÑ–Ñ Ð»Ñ–Ñ‚Ð°Ñ€Ñ‹"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ð”Ð°Ð´Ð°Ñ‚ÐºÐ¾Ð²Ñ‹Ñ Ñлоўнікі"</string> <string name="main_dictionary" msgid="4798763781818361168">"ÐÑноўны Ñлоўнік"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Сціплы"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"ÐгрÑÑіўны"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Вельмі агрÑÑіўны"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Падказкi Ð´Ð»Ñ Ð½Ð°Ñтупнага Ñлова"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ВыкарыÑтаць папÑÑ€ÑднÑе Ñлова, каб палепшыць прапановы"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Падказка наÑтупнага Ñлова"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ВыкарыÑтанне папÑÑ€ÑднÑга Ñлова Ð´Ð»Ñ Ð¿Ð°Ð´ÐºÐ°Ð·Ð°Ðº"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Падказкi Ð´Ð»Ñ Ð½Ð°Ñтупнага Ñлова"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Ðа аÑнове папÑÑ€ÑднÑга Ñлова"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ЗахаваныÑ"</string> <string name="label_go_key" msgid="1635148082137219148">"Пачаць"</string> <string name="label_next_key" msgid="362972844525672568">"Далей"</string> diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml index 5e916cef08..94945c03bd 100644 --- a/java/res/values-bg/strings.xml +++ b/java/res/values-bg/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По подразбиране"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"ÐŸÑ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° контакти"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Използване на имена от „Контакти“ за Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ поправки"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Повторни поправки: Ðктив."</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Задаване на Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° повторни поправки"</string> <string name="auto_cap" msgid="1719746674854628252">"Ðвтоматично поÑтавÑне на главни букви"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Добавени речници"</string> <string name="main_dictionary" msgid="4798763781818361168">"ОÑновен речник"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"ÐгреÑивно"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Много агреÑивно"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"ÐŸÑ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° Ñледващата дума"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Използване на предишната дума за подобрÑване на предложениÑта"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Предвиждане на Ñледващата дума"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Използване на предишната дума и за предвиждане"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"ÐŸÑ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° Ñледващата дума"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Въз оÑнова на предишната дума"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string> <string name="label_go_key" msgid="1635148082137219148">"Старт"</string> <string name="label_next_key" msgid="362972844525672568">"Ðапред"</string> diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml index 1b7cfc255e..b6fb56093f 100644 --- a/java/res/values-ca/strings.xml +++ b/java/res/values-ca/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminat"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Suggereix noms contactes"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilitza els noms de Contactes per a suggeriments i correccions"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Activa la capacitat de tornar a corregir"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Estableix suggeriments per tornar a corregir"</string> <string name="auto_cap" msgid="1719746674854628252">"Majúscules automà tiques"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionaris complementaris"</string> <string name="main_dictionary" msgid="4798763781818361168">"Diccionari principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Molt agressiu"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Suggeriments de paraula següent"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Utilitza la paraula anterior per millorar els suggeriments"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Predicció de paraula següent"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilitza també la paraula anterior per a la predicció"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Suggeriments de paraula següent"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"En funció de la paraula anterior"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: desada"</string> <string name="label_go_key" msgid="1635148082137219148">"Vés"</string> <string name="label_next_key" msgid="362972844525672568">"Següent"</string> diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml index 7e6ee0b4a7..5818d5c6fa 100644 --- a/java/res/values-cs/strings.xml +++ b/java/res/values-cs/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"VýchozÃ"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhovat jména kontaktů"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"PoužÃt jména ze seznamu kontaktů k návrhům a opravám"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Povolit opÄ›tovné opravy"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nastavit návrhy pro opÄ›tovné opravy"</string> <string name="auto_cap" msgid="1719746674854628252">"Velká pÃsmena automaticky"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Doplňkové slovnÃky"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hlavnà slovnÃk"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"MÃrné"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"AgresivnÃ"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Velmi agresivnÃ"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Návrh dalÅ¡Ãho slova"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"PoužÃt pÅ™edchozà slovo ke zlepÅ¡enà návrhů"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Odhad dalÅ¡Ãho slova"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"PoužÃt pÅ™edchozà slovo také pro odhad"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Návrhy dalÅ¡Ãho slova"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základÄ› pÅ™edchozÃho slova"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Uloženo"</string> <string name="label_go_key" msgid="1635148082137219148">"PÅ™ejÃt"</string> <string name="label_next_key" msgid="362972844525672568">"DalÅ¡Ã"</string> diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml index c6800a9529..dc1df0772a 100644 --- a/java/res/values-da/strings.xml +++ b/java/res/values-da/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"ForeslÃ¥ navne pÃ¥ kontakter"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Brug navne fra Kontaktpersoner til forslag og rettelser"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Aktivér fornyet rettelse"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Angiv forslag til fornyet rettelse"</string> <string name="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Tillægsordbøger"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hovedordbog"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Meget aggressiv"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Forslag til næste ord"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Brug forrige ord til at forbedre forslag"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Forudsigelse af næste ord"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Brug ogsÃ¥ tidligere ord til forudsigelse"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Forslag til næste ord"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Baseret pÃ¥ tidligere ord"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string> <string name="label_go_key" msgid="1635148082137219148">"GÃ¥"</string> <string name="label_next_key" msgid="362972844525672568">"Næste"</string> diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml index cd2d78e4af..b249525349 100644 --- a/java/res/values-de/strings.xml +++ b/java/res/values-de/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakte vorschlagen"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen aus \"Kontakte\" als Vorschläge und Korrekturmöglichkeiten anzeigen"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Korrekturen aktivieren"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Vorschläge für Korrekturen festlegen"</string> <string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschr."</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Erweiterte Wörterbücher"</string> <string name="main_dictionary" msgid="4798763781818361168">"Allgemeines Wörterbuch"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mäßig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Stark"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sehr stark"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Vorschläge für nächstes Wort"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Zur Verbesserung von Vorschlägen vorheriges Wort verwenden"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Vervollständigung für nächstes Wort"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Vorheriges Wort auch für Vervollständigung verwenden"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Vorschläge für nächstes Wort"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Auf Grundlage des vorherigen Wortes"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: gespeichert"</string> <string name="label_go_key" msgid="1635148082137219148">"Los"</string> <string name="label_next_key" msgid="362972844525672568">"Weiter"</string> diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml index 5dcbf43bae..d9e1aa8c4a 100644 --- a/java/res/values-el/strings.xml +++ b/java/res/values-el/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Î Ïοεπιλογή"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Î Ïόταση ονομάτων επαφών"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ΧÏησιμοποιήστε ονόματα από τις ΕπαφÎÏ‚ για Ï€Ïοτάσεις και διοÏθ."</string> - <string name="enable_span_insert" msgid="7204653105667167620">"ΕνεÏγ. επανάλ. διοÏθώσεων"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"ΟÏισμός Ï€Ïοτάσεων για επαναλήψεις διοÏθώσεων"</string> <string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χÏήση κεφαλαίων"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Î Ïόσθετα λεξικά"</string> <string name="main_dictionary" msgid="4798763781818361168">"ΚÏÏιο λεξικό"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ÎœÎÏ„Ïια"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Υψηλή"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Î Î¿Î»Ï ÎµÏ€Î¹Î¸ÎµÏ„Î¹ÎºÎ®"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Î Ïοτάσεις επόμενων λÎξεων"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ΧÏήση Ï€ÏοηγοÏμενης λÎξης για τη βελτίωση Ï€Ïοτάσεων"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Î Ïόβλεψη επόμενης λÎξης"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ΧÏησιμοποιήστε, επίσης, την Ï€ÏοηγοÏμενη λÎξη για Ï€Ïόβλεψη"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Î Ïοτάσεις επόμενων λÎξεων"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Βάσει Ï€ÏοηγοÏμενης λÎξης"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ΑποθηκεÏτηκε"</string> <string name="label_go_key" msgid="1635148082137219148">"Μετ."</string> <string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string> diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml index cd9b218e79..7241e5df0c 100644 --- a/java/res/values-en-rGB/strings.xml +++ b/java/res/values-en-rGB/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Enable recorrections"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Set suggestions for recorrections"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Add-on dictionaries"</string> <string name="main_dictionary" msgid="4798763781818361168">"Main dictionary"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressive"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Very aggressive"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Next word suggestions"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Use previous word to improve suggestion"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Next word prediction"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use previous word also for prediction"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Next word suggestions"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Based on previous word"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string> <string name="label_go_key" msgid="1635148082137219148">"Go"</string> <string name="label_next_key" msgid="362972844525672568">"Next"</string> diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml index 39ca40903d..01d9912da7 100644 --- a/java/res/values-es-rUS/strings.xml +++ b/java/res/values-es-rUS/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminada"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nombres de contacto"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nombres de los contactos para sugerencias y correcciones"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Activar correcciones"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Establecer sugerencias para realizar correcciones"</string> <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionarios complementarios"</string> <string name="main_dictionary" msgid="4798763781818361168">"Diccionario principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muy agresivo"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sugerencias para la palabra siguiente"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usar la palabra anterior para mejorar las sugerencias"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Predicción de la palabra siguiente"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usar la palabra anterior también para predicción."</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sugerencias de palabra siguiente"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Siguiente"</string> diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml index 79a36cccd7..f97d93ddf5 100644 --- a/java/res/values-es/strings.xml +++ b/java/res/values-es/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminado"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir contactos"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nombres de contactos para sugerencias y correcciones"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Activar nuevas correcciones"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Establecer sugerencias para nuevas correcciones"</string> <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionarios complementarios"</string> <string name="main_dictionary" msgid="4798763781818361168">"Diccionario principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Parcial"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muy agresiva"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sugerir siguiente palabra"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usar palabra anterior para mejorar las sugerencias"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Predecir siguiente palabra"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar también la palabra anterior para realizar la predicción"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sugerir siguiente palabra"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Según la palabra anterior"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Sig."</string> diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml index 45870d3a94..e4f0f2f58e 100644 --- a/java/res/values-et/strings.xml +++ b/java/res/values-et/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Vaikeseade"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Soovita kontaktkirjeid"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Kasuta soovitusteks ja parandusteks nimesid kontaktiloendist"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Uute paranduste lubamine"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Soovituste seadmine uute paranduste jaoks"</string> <string name="auto_cap" msgid="1719746674854628252">"Automaatne suurtähtede kasutamine"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Pistiksõnaraamatud"</string> <string name="main_dictionary" msgid="4798763781818361168">"Peamine sõnaraamat"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mõõdukas"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressiivne"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Väga agressiivne"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Järgmise sõna soovitused"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Kasuta soovituste täiustamiseks eelmist sõna"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Järgmise sõna ennustus"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Kasuta ennustuseks ka eelmist sõna"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Järgmise sõna soovitused"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Eelmise sõna põhjal"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : salvestatud"</string> <string name="label_go_key" msgid="1635148082137219148">"Mine"</string> <string name="label_next_key" msgid="362972844525672568">"Edasi"</string> diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml index 9f0e5aaa44..4ad5025eb1 100644 --- a/java/res/values-fa/strings.xml +++ b/java/res/values-fa/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"پیش Ùرض"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"پیشنهاد نام های مخاطب"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"برای پیشنهاد Ùˆ تصØÛŒØ Ø§Ø² نام مخاطبین استÙاده شود"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Ùعال کردن تصØÛŒØ Ù…Ø¬Ø¯Ø¯"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"تنظیم پیشنهادات برای تصØÛŒØ Ù…Ø¬Ø¯Ø¯"</string> <string name="auto_cap" msgid="1719746674854628252">"نوشتن با Øرو٠بزرگ خودکار"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ùرهنگ‌های لغت اÙزودنی"</string> <string name="main_dictionary" msgid="4798763781818361168">"Ùرهنگ‌ لغت اصلی"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"متوسط"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Ùعال"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"بسیار پرخاشگرانه"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"پیشنهادات کلمه بعدی"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"برای بهبود پیشنهاد از کلمه قبلی استÙاده شود"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"پیش‌بینی کلمه بعدی"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"استÙاده از کلمه قبلی برای پیش بینی"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"پیشنهادات کلمه بعدی"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"بر اساس کلمه قبلی"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string> <string name="label_go_key" msgid="1635148082137219148">"برو"</string> <string name="label_next_key" msgid="362972844525672568">"بعدی"</string> diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml index f4dff35b90..3ca48be5d6 100644 --- a/java/res/values-fi/strings.xml +++ b/java/res/values-fi/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Oletus"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yhteystietojen nimiä"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Käytä yhteystietojen nimiä ehdotuksissa ja korjauksissa"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Ota korjaukset käyttöön"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Aseta korjausehdotuksia"</string> <string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Lisäsanakirjat"</string> <string name="main_dictionary" msgid="4798763781818361168">"Pääsanakirja"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Osittainen"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Täysi"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Hyvin aggressiivinen"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Seuraavan sanan ehdotukset"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Paranna ehdotuksia aiempien sanojen avulla"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Seuraavan sanan ennakointi"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Käytä edellistä sanaa myös ennakointiin"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Seuraavan sanan ehdotukset"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Perustuu edelliseen sanan"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Tallennettu"</string> <string name="label_go_key" msgid="1635148082137219148">"Siirry"</string> <string name="label_next_key" msgid="362972844525672568">"Seur."</string> diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml index 1094c4ac30..e457480c19 100644 --- a/java/res/values-fr/strings.xml +++ b/java/res/values-fr/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Par défaut"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Activer la recorrection"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Définir des suggestions de recorrection"</string> <string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dictionnaires complémentaires"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dictionnaire principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Simple"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Proactive"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Très exigeante"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Suggestions pour le mot suivant"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Améliorer les suggestions grâce au mot précédent"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Prédiction du mot suivant"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utiliser le mot précédent pour la prédiction"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Suggestions pour le mot suivant"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Suggestions basées sur le mot précédent"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"Suiv."</string> diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml index c131e12784..0b76cfde6a 100644 --- a/java/res/values-hi/strings.xml +++ b/java/res/values-hi/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"डिफ़ॉलà¥à¤Ÿ"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"संपरà¥à¤• नाम सà¥à¤à¤¾à¤à¤‚"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"सà¥à¤à¤¾à¤µ और सà¥à¤§à¤¾à¤° के लिठसंपरà¥à¤• से नामों का उपयोग करें"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"पà¥à¤¨: सà¥à¤§à¤¾à¤° सकà¥à¤·à¤® करें"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"पà¥à¤¨: सà¥à¤§à¤¾à¤° के लिâ€à¤ सà¥à¤à¤¾à¤µ सेट करें"</string> <string name="auto_cap" msgid="1719746674854628252">"सà¥â€à¤µà¤¤: अकà¥à¤·à¤° बड़े करना"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"à¤à¤¡-ऑन डिकà¥à¤¶à¤¨à¤°à¥€"</string> <string name="main_dictionary" msgid="4798763781818361168">"मà¥à¤–à¥â€à¤¯ डिकà¥â€à¤¶à¤¨à¤°à¥€"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"साधारण"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"तीवà¥à¤°"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"बहà¥à¤¤ तीवà¥à¤°"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"अगला शबà¥â€à¤¦ सà¥à¤à¤¾à¤µ"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"सà¥à¤à¤¾à¤µà¥‹à¤‚ को बेहतर बनाने के लिठपिछले शबà¥â€à¤¦ का उपयोग करें"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"अगला शबà¥â€à¤¦ पूरà¥à¤µà¤¾à¤¨à¥à¤®à¤¾à¤¨"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"पूरà¥à¤µà¤¾à¤¨à¥à¤®à¤¾à¤¨ के लिठपिछले शबà¥à¤¦ का उपयोग करें"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"अगले शबà¥à¤¦ सà¥à¤à¤¾à¤µ"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"पिछले शबà¥à¤¦à¥‹à¤‚ के आधार पर"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: सहेजा गया"</string> <string name="label_go_key" msgid="1635148082137219148">"जाà¤à¤‚"</string> <string name="label_next_key" msgid="362972844525672568">"अगला"</string> diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml index f8a198df26..c8649e9517 100644 --- a/java/res/values-hr/strings.xml +++ b/java/res/values-hr/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Zadano"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Predlaži imena kontakata"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Upotreba imena iz Kontakata za prijedloge i ispravke"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Omogući ponovne ispravke"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Postavite prijedloge za ponovne ispravke"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"RjeÄnici-dodaci"</string> <string name="main_dictionary" msgid="4798763781818361168">"Glavni rjeÄnik"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Skromno"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivno"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Vrlo agresivno"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Prijedlozi za sljedeću rijeÄ"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Upotrijebi prethodnu rijeÄ radi poboljÅ¡anja prijedloga"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"PredviÄ‘anje sljedeće rijeÄi"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Upotrijebite prethodnu rijeÄ i za predviÄ‘anje"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Prijedlozi za sljedeću rijeÄ"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na temelju prethodne rijeÄi"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Spremljeno"</string> <string name="label_go_key" msgid="1635148082137219148">"Idi"</string> <string name="label_next_key" msgid="362972844525672568">"Dalje"</string> diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml index fc1ac12278..d2a38cb244 100644 --- a/java/res/values-hu/strings.xml +++ b/java/res/values-hu/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"AlapbeállÃtás"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Javasolt névjegyek"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"A névjegyek használata a javaslatokhoz és javÃtásokhoz"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Újbóli javÃtás engedélyezése"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Javaslatok beállÃtása az újbóli javÃtásokhoz"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdÅ‘betű"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"BÅ‘vÃtmények: szótárak"</string> <string name="main_dictionary" msgid="4798763781818361168">"FÅ‘ szótár"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mérsékelt"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"AgresszÃv"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Nagyon agresszÃv"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"KövetkezÅ‘ szóra vonatkozó javaslatok"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Javaslatok fejlesztése az elÅ‘zÅ‘ szó használatával"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"KövetkezÅ‘ szó elÅ‘rejelzése"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Az elÅ‘zÅ‘ szó használata a prediktÃv bevitelhez is"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"KövetkezÅ‘ szóra vonatkozó javaslatok"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Az elÅ‘zÅ‘ szó alapján"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : mentve"</string> <string name="label_go_key" msgid="1635148082137219148">"Ugrás"</string> <string name="label_next_key" msgid="362972844525672568">"Tovább"</string> diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml index a7a2c03834..2d10e62744 100644 --- a/java/res/values-in/strings.xml +++ b/java/res/values-in/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sarankan nama Kontak"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama dari Kontak untuk saran dan koreksi"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Aktifkan koreksi ulang"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Setel saran untuk koreksi ulang"</string> <string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Kamus pengaya"</string> <string name="main_dictionary" msgid="4798763781818361168">"Kamus utama"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sangat agresif"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Saran kata berikutnya"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gunakan kata sebelumnya untuk meningkatkan saran"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Prediksi kata berikutnya"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan kata sebelumnya juga untuk prediksi"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Saran kata berikutnya"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan kata sebelumnya"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Telah disimpan"</string> <string name="label_go_key" msgid="1635148082137219148">"Buka"</string> <string name="label_next_key" msgid="362972844525672568">"Berikutnya"</string> diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml index e77a0d04d1..c3a2b5135a 100644 --- a/java/res/values-it/strings.xml +++ b/java/res/values-it/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinito"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Suggerisci nomi di contatti"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizza nomi di Contatti per suggerimenti e correzioni"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Attiva nuove correzioni"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Imposta suggerimenti per nuove correzioni"</string> <string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dizionari aggiuntivi"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dizionario principale"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Media"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Massima"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Massima"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Suggerimenti parola successiva"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usa parola precedente per migliorare suggerimenti"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Previsione parola successiva"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usa anche la parola precedente per la previsione"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Suggerimenti parola successiva"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"In base alla parola precedente"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string> <string name="label_go_key" msgid="1635148082137219148">"Vai"</string> <string name="label_next_key" msgid="362972844525672568">"Avanti"</string> diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml index 000c9f3373..3859993f92 100644 --- a/java/res/values-iw/strings.xml +++ b/java/res/values-iw/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ברירת מחדל"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"הצע שמות של ×× ×©×™ קשר"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"השתמש בשמות מרשימת ×× ×©×™ הקשר עבור הצעות ×•×ª×™×§×•× ×™×"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"הפוך ×ª×™×§×•× ×™× ×—×•×–×¨×™× ×œ×¤×¢×™×œ×™×"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"הגדר הצעות עבור ×ª×™×§×•× ×™× ×—×•×–×¨×™×"</string> <string name="auto_cap" msgid="1719746674854628252">"הפיכת ×ותיות לרישיות ב×ופן ×וטומטי"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"הוספת ×ž×™×œ×•× ×™×"</string> <string name="main_dictionary" msgid="4798763781818361168">"מילון ר×שי"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"מצומצ×"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"מחמיר"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"מחמיר מ×וד"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"הצעות המילה הב××”"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"השתמש במילה הקודמת כדי לשפר ×ת ההצעות"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"חיזוי המילה הב××”"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"השתמש במילה הקודמת ×’× ×¢×‘×•×¨ חיזוי"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"הצעות המילה הב××”"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"בהתבסס על המילה הקודמת"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : × ×©×ž×¨×”"</string> <string name="label_go_key" msgid="1635148082137219148">"בצע"</string> <string name="label_next_key" msgid="362972844525672568">"הב×"</string> diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml index 05dd3a3641..f9349f5409 100644 --- a/java/res/values-ja/strings.xml +++ b/java/res/values-ja/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"デフォルト"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"候補ã®é€£çµ¡å…ˆåを表示"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"連絡先ã®åå‰ã‚’使用ã—ã¦å€™è£œè¡¨ç¤ºã‚„自動修æ£ã‚’è¡Œã„ã¾ã™"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"å†ä¿®æ£ã‚’有効ã«ã™ã‚‹"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"å†ä¿®æ£ã®å€™è£œã‚’挿入ã™ã‚‹"</string> <string name="auto_cap" msgid="1719746674854628252">"自動大文å—変æ›"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"アドオン辞書"</string> <string name="main_dictionary" msgid="4798763781818361168">"メイン辞書"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ä¸"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"å¼·"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"最も強ã„"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"次ã®å…¥åŠ›å€™è£œ"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ç›´å‰ã®å˜èªžã‹ã‚‰å…¥åŠ›å€™è£œã‚’予測ã—ã¾ã™"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"次ã®å…¥åŠ›å€™è£œã‚’予測"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"å‰ã®èªžå¥ã‚‚予測ã«ä½¿ç”¨"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"次ã®å…¥åŠ›å€™è£œ"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"å‰ã®èªžå¥ã«åŸºã¥ã„ãŸå…¥åŠ›å€™è£œè¡¨ç¤º"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:ä¿å˜ã—ã¾ã—ãŸ"</string> <string name="label_go_key" msgid="1635148082137219148">"実行"</string> <string name="label_next_key" msgid="362972844525672568">"次ã¸"</string> diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml index 6a998838a2..cd8cb6b519 100644 --- a/java/res/values-ko/strings.xml +++ b/java/res/values-ko/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"기본값"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"ì£¼ì†Œë¡ ì´ë¦„ 활용"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"추천 ë° ìˆ˜ì •ì— ì£¼ì†Œë¡ì˜ ì´ë¦„ 사용"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"ìž¬ìˆ˜ì • 가능 ì„¤ì •"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"ìž¬ìˆ˜ì • 추천어 ì‚¬ì „ 활성화"</string> <string name="auto_cap" msgid="1719746674854628252">"ìžë™ 대문ìží™”"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"ì‚¬ì „ 추가"</string> <string name="main_dictionary" msgid="4798763781818361168">"기본 ì‚¬ì „"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"약"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"중"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"ê°•"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"ë‹¤ìŒ ì¶”ì²œ 검색어"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ì´ì „ 단어를 사용하여 추천 검색어 ê°œì„ "</string> - <string name="bigram_prediction" msgid="3216364899483135294">"ë‹¤ìŒ ì˜ˆìƒ ê²€ìƒ‰ì–´"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ì´ì „ 단어를 사용하여 ì˜ˆìƒ ê²€ìƒ‰ì–´ 표시"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"ë‹¤ìŒ ê²€ìƒ‰ì–´ 추천"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"ì´ì „ ë‹¨ì–´ì— ê¸°ë°˜í•œ 추천"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: ì €ìž¥ë¨"</string> <string name="label_go_key" msgid="1635148082137219148">"ì´ë™"</string> <string name="label_next_key" msgid="362972844525672568">"다ìŒ"</string> diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml index 86bfc37149..2f6abc8567 100644 --- a/java/res/values-lt/strings.xml +++ b/java/res/values-lt/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Numatytasis"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"SiÅ«lyti kontaktų vardus"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"SiÅ«lant ir taisant naudoti vardus iÅ¡ „Kontaktų“"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Ä®diegti pakartotinius pataisymus"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nustatyti pakartotinio pataisymo pasiÅ«lymus"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių raÅ¡ymas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Papildomi žodynai"</string> <string name="main_dictionary" msgid="4798763781818361168">"Pagrindinis žodynas"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Vidutinis"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Atkaklus"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Labai agresyviai"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Kito žodžio pasiÅ«lymai"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Naudoti ankstesnį žodį pasiÅ«lymams patobulinti"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Kito žodžio numatymas"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Numatant naudoti ir ankstesnį žodį"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Kito žodžio pasiÅ«lymai"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Pagal ankstesnį žodį"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: iÅ¡saugota"</string> <string name="label_go_key" msgid="1635148082137219148">"PradÄ—ti"</string> <string name="label_next_key" msgid="362972844525672568">"Kitas"</string> diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml index 403e0f2d17..66dd1473e9 100644 --- a/java/res/values-lv/strings.xml +++ b/java/res/values-lv/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"NoklusÄ“jums"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Ieteikt kontaktp. vÄrdus"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Izmantot kontaktpersonu vÄrdus kÄ ieteikumus un labojumus"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"IespÄ“jot atk. labojumus"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"IestatÄ«t atkÄrtotu labojumu ieteikumus"</string> <string name="auto_cap" msgid="1719746674854628252">"AutomÄtiska lielo burtu lietoÅ¡ana"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"PapildinÄjumu vÄrdnÄ«cas"</string> <string name="main_dictionary" msgid="4798763781818361168">"GalvenÄ vÄrdnÄ«ca"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"MÄ“rena"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"AgresÄ«va"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Ä»oti radikÄla"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"NÄkamÄ vÄrda ieteikumi"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Ieteikumu uzlaboÅ¡anai izmantot iepriekÅ¡Ä“jo vÄrdu"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"NÄkamÄ vÄrda prognozÄ“Å¡ana"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Izmantot iepriekÅ¡Ä“jo vÄrdu arÄ« prognozÄ“m"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"NÄkamie vÄrdu ieteikumi"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Pamatojoties uz iepriekÅ¡Ä“jo vÄrdu"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: saglabÄts"</string> <string name="label_go_key" msgid="1635148082137219148">"SÄkt"</string> <string name="label_next_key" msgid="362972844525672568">"TÄlÄk"</string> diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml index 60f5a4133e..53c9020390 100644 --- a/java/res/values-ms/strings.xml +++ b/java/res/values-ms/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Lalai"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Cadangkan nama Kenalan"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama daripada Kenalan untuk cadangan dan pembetulan"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Dayakan pembetulan semula"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Tetapkan cadangan untuk pembetulan semula"</string> <string name="auto_cap" msgid="1719746674854628252">"Huruf besar auto"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Kamus tambahan"</string> <string name="main_dictionary" msgid="4798763781818361168">"Kamus utama"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sangat agresif"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Cadangan perkataan seterusnya"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gunakan perkataan sebelumnya untuk memperbaik cadangan"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Ramalan perkataan seterusnya"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan juga perkataan sebelumnya untuk ramalan"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Cadangan perkataan seterusnya"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Berdasarkan perkataan sebelumnya"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Disimpan"</string> <string name="label_go_key" msgid="1635148082137219148">"Pergi"</string> <string name="label_next_key" msgid="362972844525672568">"Seterusnya"</string> diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml index fc2bd5539b..bdde36ae85 100644 --- a/java/res/values-nb/strings.xml +++ b/java/res/values-nb/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"ForeslÃ¥ kontaktnavn"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Bruk navn fra Kontakter til forslag og korrigeringer"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Aktiver korrigeringer"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Angi forslag for korrigeringer"</string> <string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Tilleggsordbøker"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hovedordliste"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Omfattende"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Veldig aggressiv"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Forslag til rettelser av neste ord"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Bruk forrige ord til Ã¥ forbedre forslagene"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Forslag til neste ord"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Bruk forrige ord ogsÃ¥ for forslag"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Forslag til neste ord"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Basert pÃ¥ det forrige ordet"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string> <string name="label_go_key" msgid="1635148082137219148">"Utfør"</string> <string name="label_next_key" msgid="362972844525672568">"Neste"</string> @@ -146,7 +142,7 @@ <string name="enable" msgid="5031294444630523247">"Aktiver"</string> <string name="not_now" msgid="6172462888202790482">"Ikke nÃ¥"</string> <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Inndatastilen finnes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string> - <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Nyttighetsmodus"</string> + <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruksstudiemodus"</string> <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Innstillinger for vibrasjonsvarighet ved tastetrykk"</string> <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Innstillinger for lydstyrke ved tastetrykk"</string> </resources> diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml index 26d5e3f20a..9624e176e7 100644 --- a/java/res/values-nl/strings.xml +++ b/java/res/values-nl/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standaard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Contactnamen suggereren"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen uit Contacten gebruiken voor suggesties en correcties"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Verbeteringen inschakelen"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Suggesties instellen voor verbeteringen"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Woordenboeken toevoegen"</string> <string name="main_dictionary" msgid="4798763781818361168">"Algemeen woordenboek"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Normaal"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressief"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Zeer agressief"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Volgende woordsuggesties"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Vorig woord gebruiken om suggesties te verbeteren"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Volgende woordvoorspelling"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Het voorgaande woord ook voor voorspelling gebruiken"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Suggesties voor volgend woord"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Op basis van het vorige woord"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: opgeslagen"</string> <string name="label_go_key" msgid="1635148082137219148">"Start"</string> <string name="label_next_key" msgid="362972844525672568">"Verder"</string> diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml index dc4f396a79..c8a72b77a7 100644 --- a/java/res/values-pl/strings.xml +++ b/java/res/values-pl/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Wartość domyÅ›lna"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Proponuj osoby z kontaktów"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"W propozycjach i poprawkach użyj nazwisk z kontaktów"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"WÅ‚Ä…cz poprawki"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Ustaw sugestie poprawek"</string> <string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dodatkowe sÅ‚owniki"</string> <string name="main_dictionary" msgid="4798763781818361168">"SÅ‚ownik główny"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Umiarkowana"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresywna"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Bardzo agresywna"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestie kolejnych słów"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Używaj poprzedniego wyrazu, by polepszyć sugestie"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Przewidywanie nastÄ™pnego wyrazu"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Przewiduj również na podstawie poprzedniego sÅ‚owa"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sugestie kolejnych słów"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podstawie poprzedniego sÅ‚owa"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"Dalej"</string> diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml index 35eedd82ae..cef2ce75be 100644 --- a/java/res/values-pt-rPT/strings.xml +++ b/java/res/values-pt-rPT/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinido"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de Contactos"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nomes dos Contactos para sugestões e correções"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Ativar correções"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Definir sugestões para correções"</string> <string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dicionários extras"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dicionário principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressiva"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muito agressivo"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestões da palavra seguinte"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Utilizar palavra anterior para melhorar sugestões"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Previsão da palavra seguinte"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar a palavra anterior também para predição"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sugestões da palavra seguinte"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"Avançar"</string> diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml index a12fc23e1d..d092879cf1 100644 --- a/java/res/values-pt/strings.xml +++ b/java/res/values-pt/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Padrão"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de contato"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nomes dos Contatos para sugestões e correções"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Ativar recorreções"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Definir sugestões para recorreções"</string> <string name="auto_cap" msgid="1719746674854628252">"Capitaliz. automática"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dicionários complementares"</string> <string name="main_dictionary" msgid="4798763781818361168">"Dicionário principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressivo"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muito agressivo"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestões p/ palavra seguinte"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Usar palavra anterior para melhorar as sugestões"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Previsão da palavra seguinte"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use também a palavra anterior para prever"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sugestões para a palavra seguinte"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Com base na palavra anterior"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string> <string name="label_go_key" msgid="1635148082137219148">"Ir"</string> <string name="label_next_key" msgid="362972844525672568">"Avançar"</string> diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml index c6c936e492..b39691ceb9 100644 --- a/java/res/values-rm/strings.xml +++ b/java/res/values-rm/strings.xml @@ -67,10 +67,6 @@ <skip /> <!-- no translation found for use_contacts_dict_summary (6599983334507879959) --> <skip /> - <!-- no translation found for enable_span_insert (7204653105667167620) --> - <skip /> - <!-- no translation found for enable_span_insert_summary (2947317657871394467) --> - <skip /> <string name="auto_cap" msgid="1719746674854628252">"Maiusclas automaticas"</string> <!-- no translation found for configure_dictionaries_title (4238652338556902049) --> <skip /> @@ -98,13 +94,9 @@ <skip /> <!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) --> <skip /> - <!-- no translation found for bigram_suggestion (8169311444438922902) --> - <skip /> - <!-- no translation found for bigram_suggestion_summary (6635527607242625713) --> - <skip /> - <!-- no translation found for bigram_prediction (3216364899483135294) --> + <!-- no translation found for bigram_prediction (5809665643352206540) --> <skip /> - <!-- no translation found for bigram_prediction_summary (1747261921174300098) --> + <!-- no translation found for bigram_prediction_summary (3253961591626441019) --> <skip /> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà "</string> <string name="label_go_key" msgid="1635148082137219148">"Dai"</string> diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml index 523a855c74..08275665cd 100644 --- a/java/res/values-ro/strings.xml +++ b/java/res/values-ro/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Prestabilit"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"SugeraÅ£i nume din Agendă"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"UtilizaÅ£i numele din Agendă pentru sugestii ÅŸi corecÅ£ii"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"ActivaÅ£i rectificările"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"SetaÅ£i sugestii pentru rectificări"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"DicÅ£ionare suplimentare"</string> <string name="main_dictionary" msgid="4798763781818361168">"DicÅ£ionar principal"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderată"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivă"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Foarte exigentă"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sugestii pentru cuvântul următor"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"UtilizaÅ£i cuvântul anterior pentru a îmbunătăţi sugestiile"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"PredicÅ£ia cuvântului următor"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Se utilizează ÅŸi cuvântul precedent pentru predicÅ£ii"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sugestii pentru cuvântul următor"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Bazate pe cuvântul precedent"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: salvat"</string> <string name="label_go_key" msgid="1635148082137219148">"OK"</string> <string name="label_next_key" msgid="362972844525672568">"ÃŽnainte"</string> diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml index 34fdb0f5c0..77ffe7b55d 100644 --- a/java/res/values-ru/strings.xml +++ b/java/res/values-ru/strings.xml @@ -44,10 +44,8 @@ <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="use_contacts_dict" msgid="4435317977804180815">"ПодÑказки имен контактов"</string> - <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ПодÑказки и иÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° оÑнове имен из контактов"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"ÐвтоиÑправление"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Показывать варианты иÑправлениÑ"</string> + <string name="use_contacts_dict" msgid="4435317977804180815">"ПодÑказывать имена"</string> + <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ПодÑказывать иÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° оÑнове имен из ÑпиÑка контактов"</string> <string name="auto_cap" msgid="1719746674854628252">"Заглавные автоматичеÑки"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Дополнительные Ñловари"</string> <string name="main_dictionary" msgid="4798763781818361168">"ОÑновной Ñловарь"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умеренное"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Ðктивное"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Очень активно"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Следующие варианты"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ИÑпользовать предыдущее Ñлово, чтобы иÑправить предложенные варианты"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð´Ñказка"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ИÑпользовать предыдущее Ñлово Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ð½Ð¾Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"ПодÑказка Ð´Ð»Ñ Ñледующего Ñлова"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"ПодÑказки, оÑнованные на предыдущих Ñловах"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Ñохранено"</string> <string name="label_go_key" msgid="1635148082137219148">"ПоиÑк"</string> <string name="label_next_key" msgid="362972844525672568">"Далее"</string> diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml index 41fc0cf242..2b31bd8588 100644 --- a/java/res/values-sk/strings.xml +++ b/java/res/values-sk/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predvolená"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhnúť mená kontaktov"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"PoužÃvaÅ¥ mená z Kontaktov na návrhy a opravy"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"PovoliÅ¥ opätovné opravy"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"NastaviÅ¥ návrhy pre opätovné opravy"</string> <string name="auto_cap" msgid="1719746674854628252">"Veľké pÃsmená automaticky"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Doplnkové slovnÃky"</string> <string name="main_dictionary" msgid="4798763781818361168">"Hlavný slovnÃk"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mierne"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"AgresÃvne"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Veľmi agresÃvne"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Návrhy ÄalÅ¡ieho slova"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Na zlepÅ¡enie návrhov použiÅ¥ predchádzajúce slovo"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Odhad ÄalÅ¡ieho slova"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"PoužiÅ¥ predchádzajúce slovo aj pre predpoveÄ"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Návrhy ÄalÅ¡ieho slova"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na základe predchádzajúceho slova"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uložené"</string> <string name="label_go_key" msgid="1635148082137219148">"HľadaÅ¥"</string> <string name="label_next_key" msgid="362972844525672568">"ÄŽalej"</string> diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml index f18de78bc2..05e20b04cb 100644 --- a/java/res/values-sl/strings.xml +++ b/java/res/values-sl/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Privzeto"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Predlagaj imena stikov"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Uporaba imen iz stikov za predloge in popravke"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"OmogoÄi vnoviÄne popravke"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Nastavitev predlogov za vnoviÄne popravke"</string> <string name="auto_cap" msgid="1719746674854628252">"Samod. velike zaÄetnice"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Dodatni slovarji"</string> <string name="main_dictionary" msgid="4798763781818361168">"Glavni slovar"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Zmerno"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Strogo"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Zelo strogo"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Predlogi naslednje besede"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Predloge izboljÅ¡aj s prejÅ¡njo besedo"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Predvidevanje naslednje besede"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Uporabi prejÅ¡njo besedo tudi za predvidevanje"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Predlogi za naslednjo besedo"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Na podlagi prejÅ¡nje besede"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: shranjeno"</string> <string name="label_go_key" msgid="1635148082137219148">"Pojdi"</string> <string name="label_next_key" msgid="362972844525672568">"Naprej"</string> diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml index 11e678ebc2..43fe7003d8 100644 --- a/java/res/values-sr/strings.xml +++ b/java/res/values-sr/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Подразумевано"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Предложи имена контаката"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"КориÑти имена из Контаката за предлоге и иÑправке"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Омогући поновне иÑправке"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Подешавање предлога за поновне иÑправке"</string> <string name="auto_cap" msgid="1719746674854628252">"ÐутоматÑки ÑƒÐ½Ð¾Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ… Ñлова"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Помоћни речници"</string> <string name="main_dictionary" msgid="4798763781818361168">"Главни речник"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"ÐгреÑивно"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Веома агреÑивно"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Предлози за Ñледећу реч"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"КориÑти претходну реч за побољшање предлога"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Предвиђање Ñледеће речи"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"КориÑти претходну реч и за предвиђање"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Предлози за Ñледећу реч"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Ðа оÑнову претходне речи"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string> <string name="label_go_key" msgid="1635148082137219148">"Иди"</string> <string name="label_next_key" msgid="362972844525672568">"Следеће"</string> diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml index bf1e5054f9..f244469764 100644 --- a/java/res/values-sv/strings.xml +++ b/java/res/values-sv/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"FöreslÃ¥ kontaktnamn"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Använd namn frÃ¥n Kontakter för förslag och korrigeringar"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Aktivera omkorrigeringar"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Ställ in förslag för omkorrigeringar"</string> <string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Tilläggsordlistor"</string> <string name="main_dictionary" msgid="4798763781818361168">"Huvudordlistan"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"MÃ¥ttlig"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Mycket aggressivt"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"FöreslÃ¥ nästa ord"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Förbättra förslagen med föregÃ¥ende ord"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"FörutspÃ¥ nästa ord"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Använd även föregÃ¥ende ord för att ge förslag"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"FöreslÃ¥ nästa ord"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Baserat pÃ¥ föregÃ¥ende ord"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string> <string name="label_go_key" msgid="1635148082137219148">"Kör"</string> <string name="label_next_key" msgid="362972844525672568">"Nästa"</string> diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml index f416fcd76e..9cec8679d8 100644 --- a/java/res/values-sw/strings.xml +++ b/java/res/values-sw/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Chaguo-msingi"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Pendekeza majini ya Anwani"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Tumia majina kutoka kwa Anwani kwa mapendekezo na marekebisho"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Wezesha masahihisho mapya"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Weka mapendekezo kwa ajili ya kusahihisha upya"</string> <string name="auto_cap" msgid="1719746674854628252">"Uwekaji wa herufi kubwa kiotomatiki"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Nyongeza za kamusi"</string> <string name="main_dictionary" msgid="4798763781818361168">"Kamusi kuu"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ya wastani"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Ya hima"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Changamfu zaidi"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Mapendekezo ya neno lifuatalo"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Tumia neno la awali ili kuboresha mapendekezo"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Utabiri wa neno lifuatalo"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Tumia neno la awali pia kwa udadisi"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Mapendekezo ya neno lifuatalo"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Kulingana na neno la awali"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Imehifadhiwa"</string> <string name="label_go_key" msgid="1635148082137219148">"Nenda"</string> <string name="label_next_key" msgid="362972844525672568">"Ifuatayo"</string> diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml index 6f25a20249..174ee45070 100644 --- a/java/res/values-th/strings.xml +++ b/java/res/values-th/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ค่าเริ่มต้น"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"à¹à¸™à¸°à¸™à¸³à¸Šà¸·à¹ˆà¸à¸œà¸¹à¹‰à¸•à¸´à¸”ต่à¸"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ใช้ชื่à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸à¸•à¸´à¸”ต่à¸à¸ªà¸³à¸«à¸£à¸±à¸šà¸„ำà¹à¸™à¸°à¸™à¸³à¹à¸¥à¸°à¸à¸²à¸£à¹à¸à¹‰à¹„ข"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"เปิดใช้งานà¸à¸²à¸£à¹à¸à¹‰à¹„ขซ้ำ"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"ตั้งค่าคำà¹à¸™à¸°à¸™à¸³à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¹à¸à¹‰à¹„ขซ้ำ"</string> <string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหà¸à¹ˆà¸à¸±à¸•à¹‚นมัติ"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"พจนานุà¸à¸£à¸¡ Add-On"</string> <string name="main_dictionary" msgid="4798763781818361168">"พจนานุà¸à¸£à¸¡à¸«à¸¥à¸±à¸"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ปานà¸à¸¥à¸²à¸‡"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"เข้มงวด"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"เข้มงวดมาà¸"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"คำà¹à¸™à¸°à¸™à¸³à¸ªà¸³à¸«à¸£à¸±à¸šà¸„ำถัดไป"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ใช้คำà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰à¹€à¸žà¸·à¹ˆà¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¸„ำà¹à¸™à¸°à¸™à¸³"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"à¸à¸²à¸£à¸„าดคะเนคำถัดไป"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ใช้คำà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸„าดคะเน"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"คำà¹à¸™à¸°à¸™à¸³à¸ªà¸³à¸«à¸£à¸±à¸šà¸„ำถัดไป"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"ตามคำà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึà¸à¹à¸¥à¹‰à¸§"</string> <string name="label_go_key" msgid="1635148082137219148">"ไป"</string> <string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string> diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml index e2fe6c5b4b..25801ca7dc 100644 --- a/java/res/values-tl/strings.xml +++ b/java/res/values-tl/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Mungkahi pangalan Contact"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gamitin pangalan mula Mga Contact sa mga mungkahi\'t pagwawasto"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Paganahin ang mga muling pagtatama"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Magtakda ng mga suhestyon para sa mga muling pagtatama"</string> <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Mga diksyunaryo na add-on"</string> <string name="main_dictionary" msgid="4798763781818361168">"Pangunahing diksyunaryo"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresibo"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Napaka-agresibo"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Mga paghuhula sa susunod na salita"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Gamitin ang naunang salita para mapahusay ang mga suhestiyon"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Paghuhula sa susunod na salita"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gamitin ang nakaraang salita para din sa hula"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Mga suhestiyon sa susunod na salita"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Batay sa nakaraang salita"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Na-save"</string> <string name="label_go_key" msgid="1635148082137219148">"Punta"</string> <string name="label_next_key" msgid="362972844525672568">"Susunod"</string> diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml index 16411b8edf..190736e82f 100644 --- a/java/res/values-tr/strings.xml +++ b/java/res/values-tr/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Varsayılan"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"KiÅŸi Adları öner"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Öneri ve düzeltmeler için KiÅŸiler\'deki adları kullan"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Düzeltmeleri etkinleÅŸtir"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Yeniden düzeltmeler için önerileri ayarla"</string> <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük fark yap"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Ek sözlükler"</string> <string name="main_dictionary" msgid="4798763781818361168">"Ana sözlük"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ölçülü"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Çok geniÅŸ ölçekte"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Sonraki kelime önerileri"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Önerileri geliÅŸtirmek için önceki kelimeyi kullan"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Sonraki kelime tahmini"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Önceki kelimeyi de tahmin için kullan"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Sonraki kelime önerileri"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Önceki kelimeye dayanarak"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string> <string name="label_go_key" msgid="1635148082137219148">"Git"</string> <string name="label_next_key" msgid="362972844525672568">"Ä°leri"</string> diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml index c2e743b45b..04a8a638ec 100644 --- a/java/res/values-uk/strings.xml +++ b/java/res/values-uk/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"За умовчаннÑм"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Пропон. імена контактів"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ВикориÑÑ‚. імена зі ÑпиÑку контактів Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ð¹ Ñ– виправлень"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Увімкнути виправленнÑ"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Показувати варіанти автовиправлень"</string> <string name="auto_cap" msgid="1719746674854628252">"Ðвто викор. вел. літер"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Додані Ñловники"</string> <string name="main_dictionary" msgid="4798763781818361168">"ОÑновний Ñловник"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Помірне"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Ðктивне"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Дуже активне"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Пропозиції наÑтупного Ñлова"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"ВикориÑтати попереднє Ñлово Ð´Ð»Ñ Ð¿Ð¾ÐºÑ€Ð°Ñ‰ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ð¹"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"ÐŸÐµÑ€ÐµÐ´Ð±Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ð°Ñтупного Ñлова"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"ВикориÑтовувати попереднє Ñлово також Ñк передбачений запит"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Пропозиції наÑтупного Ñлова"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Ðа оÑнові попереднього Ñлова"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string> <string name="label_go_key" msgid="1635148082137219148">"Іти"</string> <string name="label_next_key" msgid="362972844525672568">"Далі"</string> diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml index 9ce2d5a78d..c9dc0e644d 100644 --- a/java/res/values-vi/strings.xml +++ b/java/res/values-vi/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Mặc định"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Äá» xuất tên liên hệ"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Sá» dụng tên từ Danh bạ cho các Ä‘á» xuất và chỉnh sá»a"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Báºt sá»a đổi lại"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Äặt Ä‘á» xuất cho các sá»a đổi lại"</string> <string name="auto_cap" msgid="1719746674854628252">"Tá»± Ä‘á»™ng viết hoa"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Thêm từ Ä‘iển"</string> <string name="main_dictionary" msgid="4798763781818361168">"Từ Ä‘iển chÃnh"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ÄÆ¡n giản"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Linh hoạt"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Rất linh hoạt"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Äá» xuất từ tiếp theo"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Sá» dụng từ trÆ°á»›c đó để cải tiến Ä‘á» xuất"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Dá»± Ä‘oán từ tiếp theo"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"CÅ©ng sá» dụng từ trÆ°á»›c đó để dá»± Ä‘oán"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Äá» xuất từ tiếp theo"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Dá»±a trên từ trÆ°á»›c đó"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Äã lÆ°u"</string> <string name="label_go_key" msgid="1635148082137219148">"Tìm"</string> <string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string> diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml index 4907f202fd..9f5e4633d4 100644 --- a/java/res/values-zh-rCN/strings.xml +++ b/java/res/values-zh-rCN/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"默认"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"è”系人姓å建议"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用è”系人ä¸çš„姓åæ供建议和更æ£"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"å…许å†æ¬¡æ›´æ£"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"设置建议以用于å†æ¬¡æ›´æ£"</string> <string name="auto_cap" msgid="1719746674854628252">"自动大写"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"é™„åŠ è¯å…¸"</string> <string name="main_dictionary" msgid="4798763781818361168">"主è¯å…¸"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"å°æ”¹"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"大改"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"改动æžå¤§"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"下一å—è¯å»ºè®®"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"使用上一å—è¯æ”¹è¿›å»ºè®®"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"下一å—è¯é¢„测"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"结åˆå‰ä¸€ä¸ªå—è¯è¿›è¡Œé¢„测"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"下一å—è¯å»ºè®®"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"æ ¹æ®ä¸Šä¸€ä¸ªå—è¯æ供建议"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已ä¿å˜"</string> <string name="label_go_key" msgid="1635148082137219148">"开始"</string> <string name="label_next_key" msgid="362972844525672568">"下一æ¥"</string> diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml index 9179e669b9..20592dc44a 100644 --- a/java/res/values-zh-rTW/strings.xml +++ b/java/res/values-zh-rTW/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"é è¨"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"建è°è¯çµ¡äººå稱"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"æ ¹æ“šã€Œè¯çµ¡äººã€å稱æ供建è°èˆ‡ä¿®æ£"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"啟用é‡æ–°æ›´æ£"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"è¨å®šå»ºè°ä¾›é‡æ–°æ›´æ£"</string> <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"外掛å—å…¸"</string> <string name="main_dictionary" msgid="4798763781818361168">"主è¦å—å…¸"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"æ›´æ£ç¯„åœå°"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"æ›´æ£ç¯„åœå¤§"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"æ›´æ£ç¯„åœæ¥µå¤§"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"下一個å—詞建è°"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"æ ¹æ“šå‰ä¸€å€‹å—詞找出更é©åˆçš„建è°"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"下一個å—è©žé 測"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"åŒæ¨£ä½¿ç”¨å‰ä¸€å€‹å—詞進行é 測"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"下一個å—詞建è°"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"æ ¹æ“šå…ˆå‰å—詞產生"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲å˜"</string> <string name="label_go_key" msgid="1635148082137219148">"開始"</string> <string name="label_next_key" msgid="362972844525672568">"繼續"</string> diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml index 3f7c96b66e..35cb99cf8b 100644 --- a/java/res/values-zu/strings.xml +++ b/java/res/values-zu/strings.xml @@ -46,8 +46,6 @@ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Okuzenzakalelayo"</string> <string name="use_contacts_dict" msgid="4435317977804180815">"Sikisela amagama Othintana nabo"</string> <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Amagama abasebenzisi kusuka Kothintana nabo bokusikisela nokulungisa"</string> - <string name="enable_span_insert" msgid="7204653105667167620">"Vumela ukulungiswa kabusha"</string> - <string name="enable_span_insert_summary" msgid="2947317657871394467">"Setha iziphakamiso zokulungisa kabusha"</string> <string name="auto_cap" msgid="1719746674854628252">"Ukwenza ofeleba okuzenzakalelayo"</string> <string name="configure_dictionaries_title" msgid="4238652338556902049">"Faka izichazamazwi"</string> <string name="main_dictionary" msgid="4798763781818361168">"Isichazamazwi sakho ngqangi"</string> @@ -62,10 +60,8 @@ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Thobekile"</string> <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Bukhali"</string> <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Nobudlova kakhulu"</string> - <string name="bigram_suggestion" msgid="8169311444438922902">"Iziphakamiso zegama elilandelayo"</string> - <string name="bigram_suggestion_summary" msgid="6635527607242625713">"Sebenzisa igama elandulele ukuthuthukisa iziphakamiso"</string> - <string name="bigram_prediction" msgid="3216364899483135294">"Ukuqagela kwegama elilandelayo"</string> - <string name="bigram_prediction_summary" msgid="1747261921174300098">"Sebenzisa igama langaphambilini ukuze uqagele"</string> + <string name="bigram_prediction" msgid="5809665643352206540">"Iziphakamiso zegama elilandelayo"</string> + <string name="bigram_prediction_summary" msgid="3253961591626441019">"Ngokususela egameni langaphambilini"</string> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kulondoloziwe"</string> <string name="label_go_key" msgid="1635148082137219148">"Iya"</string> <string name="label_next_key" msgid="362972844525672568">"Okulandelayo"</string> diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index d6a68d0dc4..0970aeee03 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -181,6 +181,52 @@ <!-- Description for Bulgarian (BDS) subtype. --> <string name="subtype_bulgarian_bds">%s (BDS)</string> + <!-- Compatibility map from subtypeLocale:subtypeExtraValue to keyboardLayoutSet --> + <string-array name="locale_and_extra_value_to_keyboard_layout_set_map"> + <item>en_US:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + <item>en_GB:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + <item>ar:SupportTouchPositionCorrection</item> + <item>arabic</item> + <item>cs:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwertz</item> + <item>da:AsciiCapable,SupportTouchPositionCorrection</item> + <item>nordic</item> + <item>de:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwertz</item> + <item>es:AsciiCapable,SupportTouchPositionCorrection</item> + <item>spanish</item> + <item>fi:AsciiCapable,SupportTouchPositionCorrection</item> + <item>nordic</item> + <item>fr:AsciiCapable,SupportTouchPositionCorrection</item> + <item>azerty</item> + <item>fr_CA:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + <item>hr:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwertz</item> + <item>hu:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwertz</item> + <item>it:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + <item>iw:SupportTouchPositionCorrection</item> + <item>hebrew</item> + <item>nb:AsciiCapable,SupportTouchPositionCorrection</item> + <item>nordic</item> + <item>nl:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + <item>pl:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + <item>ru:SupportTouchPositionCorrection</item> + <item>east_slavic</item> + <item>sr:SupportTouchPositionCorrection</item> + <item>south_slavic</item> + <item>sv:AsciiCapable,SupportTouchPositionCorrection</item> + <item>nordic</item> + <item>tr:AsciiCapable,SupportTouchPositionCorrection</item> + <item>qwerty</item> + </string-array> + <!-- dictionary pack package name /settings activity (for shared prefs and settings) --> <string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string> <string name="dictionary_pack_settings_activity">com.google.android.inputmethod.latin.dictionarypack.DictionarySettingsActivity</string> diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index 0b781af798..6c66a48440 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -85,11 +85,6 @@ <!-- Description for option enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=65] --> <string name="use_contacts_dict_summary">Use names from Contacts for suggestions and corrections</string> - <!-- Option name for enabling insertion of suggestion spans (advanced option) [CHAR LIMIT=25] --> - <string name="enable_span_insert">Enable recorrections</string> - <!-- Option summary for enabling insertion of suggestion spans (advanced option) [CHAR LIMIT=65] --> - <string name="enable_span_insert_summary">Set suggestions for recorrections</string> - <!-- Option to enable auto capitalization of sentences --> <string name="auto_cap">Auto-capitalization</string> @@ -120,14 +115,10 @@ <!-- Option to suggest auto correction suggestions very aggressively. Auto-corrects to a word which has even large edit distance from typed word. [CHAR LIMIT=20] --> <string name="auto_correction_threshold_mode_very_aggeressive">Very aggressive</string> - <!-- Option to enable next word correction --> - <string name="bigram_suggestion">Next word suggestions</string> - <!-- Option to enable next word suggestion. This uses the previous word in an attempt to improve the suggestions quality --> - <string name="bigram_suggestion_summary">Use previous word to improve suggestions</string> - <!-- Option to enable using next word prediction --> - <string name="bigram_prediction">Next word prediction</string> - <!-- Description for "next word prediction" option. This displays suggestions even when there is no input, based on the previous word. --> - <string name="bigram_prediction_summary">Use previous word also for prediction</string> + <!-- Option to enable using next word suggestions. After the user types a space, with this option on, the keyboard will try to predict the next word. --> + <string name="bigram_prediction">Next word suggestions</string> + <!-- Description for "next word suggestion" option. This displays suggestions even when there is no input, based on the previous word. --> + <string name="bigram_prediction_summary">Based on previous word</string> <!-- Indicates that a word has been added to the dictionary --> <string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string> @@ -305,7 +296,7 @@ <string name="subtype_locale">Language</string> <!-- Title of the spinner for choosing a keyboard layout of custom style in the settings dialog [CHAR LIMIT=15] --> <string name="keyboard_layout_set">Layout</string> - <!-- The message of the dialog to note that a custom input style needs to be enabled. [CHAR LIMIT=64] --> + <!-- The message of the dialog to note that a custom input style needs to be enabled. [CHAR LIMIT=130] --> <string name="custom_input_style_note_message">"Your custom input style needs to be enabled before you start using it. Do you want to enable it now?"</string> <!-- Title of the button to enable a custom input style entry in the settings dialog [CHAR LIMIT=15] --> <string name="enable">Enable</string> diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 07bff098be..7f8a23a0ee 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -76,19 +76,19 @@ android:label="@string/subtype_en_US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,TrySuppressingImeSwitcher,AsciiCapable" + android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_en_GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,TrySuppressingImeSwitcher,AsciiCapable" + android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="ar" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=arabic" + android:imeSubtypeExtraValue="SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -112,19 +112,19 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="cs" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="da" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="de" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -136,7 +136,7 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="es" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -154,19 +154,19 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="fi" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="fr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="fr_CA" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -178,13 +178,13 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="hr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="hu" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -196,14 +196,14 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="it" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. --> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="iw" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=hebrew" + android:imeSubtypeExtraValue="SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -239,19 +239,19 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="nb" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="nl" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="pl" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -275,7 +275,7 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="ru" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic" + android:imeSubtypeExtraValue="SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -293,13 +293,13 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="sr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic" + android:imeSubtypeExtraValue="SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" android:imeSubtypeLocale="sv" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" @@ -311,7 +311,7 @@ android:label="@string/subtype_generic" android:imeSubtypeLocale="tr" android:imeSubtypeMode="keyboard" - android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" + android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection" /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml index d8bf7847e7..bf8805875e 100644 --- a/java/res/xml/prefs.xml +++ b/java/res/xml/prefs.xml @@ -80,6 +80,12 @@ <PreferenceCategory android:title="@string/misc_category" android:key="misc_settings"> + <CheckBoxPreference + android:key="next_word_prediction" + android:title="@string/bigram_prediction" + android:summary="@string/bigram_prediction_summary" + android:persistent="true" + android:defaultValue="true" /> <CheckBoxPreference android:key="usability_study_mode" android:title="@string/prefs_usability_study_mode" @@ -114,12 +120,6 @@ android:summary="@string/use_contacts_dict_summary" android:persistent="true" android:defaultValue="true" /> - <CheckBoxPreference - android:key="next_word_prediction" - android:title="@string/bigram_prediction" - android:summary="@string/bigram_prediction_summary" - android:persistent="true" - android:defaultValue="true" /> <PreferenceScreen android:key="pref_vibration_duration_settings" android:title="@string/prefs_keypress_vibration_duration_settings"/> diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java index 23acb8b749..5ffd94a43e 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java +++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java @@ -19,6 +19,7 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.text.TextUtils; import android.util.Log; +import android.util.SparseIntArray; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Key; @@ -39,8 +40,8 @@ public class KeyCodeDescriptionMapper { // Map of key labels to spoken description resource IDs private final HashMap<CharSequence, Integer> mKeyLabelMap; - // Map of key codes to spoken description resource IDs - private final HashMap<Integer, Integer> mKeyCodeMap; + // Sparse array of spoken description resource IDs indexed by key codes + private final SparseIntArray mKeyCodeMap; public static void init() { sInstance.initInternal(); @@ -52,7 +53,7 @@ public class KeyCodeDescriptionMapper { private KeyCodeDescriptionMapper() { mKeyLabelMap = new HashMap<CharSequence, Integer>(); - mKeyCodeMap = new HashMap<Integer, Integer>(); + mKeyCodeMap = new SparseIntArray(); } private void initInternal() { @@ -60,7 +61,7 @@ public class KeyCodeDescriptionMapper { mKeyLabelMap.put(":-)", R.string.spoken_description_smiley); // Symbols that most TTS engines can't speak - mKeyCodeMap.put((int) ' ', R.string.spoken_description_space); + mKeyCodeMap.put(' ', R.string.spoken_description_space); // Special non-character codes defined in Keyboard mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete); @@ -273,7 +274,8 @@ public class KeyCodeDescriptionMapper { return context.getString(OBSCURED_KEY_RES_ID); } - if (mKeyCodeMap.containsKey(code)) { + final int resId = mKeyCodeMap.get(code); + if (resId != 0) { return context.getString(mKeyCodeMap.get(code)); } else if (isDefinedNonCtrl) { return Character.toString((char) code); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 6d85fea27f..1aec001296 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -23,6 +23,8 @@ import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; +import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.TypedValue; import android.util.Xml; import android.view.InflateException; @@ -44,7 +46,6 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.HashSet; import java.util.Locale; @@ -134,7 +135,7 @@ public class Keyboard { public final Key[] mAltCodeKeysWhileTyping; public final KeyboardIconsSet mIconsSet; - private final HashMap<Integer, Key> mKeyCache = new HashMap<Integer, Key>(); + private final SparseArray<Key> mKeyCache = new SparseArray<Key>(); private final ProximityInfo mProximityInfo; private final boolean mProximityCharsCorrectionEnabled; @@ -202,7 +203,7 @@ public class Keyboard { } public boolean hasKey(Key aKey) { - if (mKeyCache.containsKey(aKey)) { + if (mKeyCache.indexOfValue(aKey) >= 0) { return true; } @@ -346,8 +347,8 @@ public class Keyboard { private int mMaxHeightCount = 0; private int mMaxWidthCount = 0; - private final HashMap<Integer, Integer> mHeightHistogram = new HashMap<Integer, Integer>(); - private final HashMap<Integer, Integer> mWidthHistogram = new HashMap<Integer, Integer>(); + private final SparseIntArray mHeightHistogram = new SparseIntArray(); + private final SparseIntArray mWidthHistogram = new SparseIntArray(); private void clearHistogram() { mMostCommonKeyHeight = 0; @@ -359,22 +360,22 @@ public class Keyboard { mWidthHistogram.clear(); } - private static int updateHistogramCounter(HashMap<Integer, Integer> histogram, - Integer key) { - final int count = (histogram.containsKey(key) ? histogram.get(key) : 0) + 1; + private static int updateHistogramCounter(SparseIntArray histogram, int key) { + final int index = histogram.indexOfKey(key); + final int count = (index >= 0 ? histogram.get(key) : 0) + 1; histogram.put(key, count); return count; } private void updateHistogram(Key key) { - final Integer height = key.mHeight + key.mVerticalGap; + final int height = key.mHeight + key.mVerticalGap; final int heightCount = updateHistogramCounter(mHeightHistogram, height); if (heightCount > mMaxHeightCount) { mMaxHeightCount = heightCount; mMostCommonKeyHeight = height; } - final Integer width = key.mWidth + key.mHorizontalGap; + final int width = key.mWidth + key.mHorizontalGap; final int widthCount = updateHistogramCounter(mWidthHistogram, width); if (widthCount > mMaxWidthCount) { mMaxWidthCount = widthCount; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index 8c7246855b..aab89a3e5e 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -29,6 +29,7 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.text.InputType; import android.util.Log; +import android.util.SparseArray; import android.util.Xml; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; @@ -116,9 +117,9 @@ public class KeyboardLayoutSet { InputMethodSubtype mSubtype; int mOrientation; int mWidth; - // KeyboardLayoutSet element id to element's parameters map. - final HashMap<Integer, ElementParams> mKeyboardLayoutSetElementIdToParamsMap = - new HashMap<Integer, ElementParams>(); + // Sparse array of KeyboardLayoutSet element parameters indexed by element's id. + final SparseArray<ElementParams> mKeyboardLayoutSetElementIdToParamsMap = + new SparseArray<ElementParams>(); static class ElementParams { int mKeyboardXmlId; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 18e01fb498..fb98af3e65 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -30,6 +30,7 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Message; import android.util.AttributeSet; +import android.util.SparseArray; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -42,7 +43,6 @@ import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import com.android.inputmethod.latin.StringUtils; -import java.util.HashMap; import java.util.HashSet; /** @@ -124,12 +124,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { private Canvas mCanvas; private final Paint mPaint = new Paint(); private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics(); - // This map caches key label text height in pixel as value and key label text size as map key. - private static final HashMap<Integer, Float> sTextHeightCache = - new HashMap<Integer, Float>(); - // This map caches key label text width in pixel as value and key label text size as map key. - private static final HashMap<Integer, Float> sTextWidthCache = - new HashMap<Integer, Float>(); + // This sparse array caches key label text height in pixel indexed by key label text size. + private static final SparseArray<Float> sTextHeightCache = new SparseArray<Float>(); + // This sparse array caches key label text width in pixel indexed by key label text size. + private static final SparseArray<Float> sTextWidthCache = new SparseArray<Float>(); private static final char[] KEY_LABEL_REFERENCE_CHAR = { 'M' }; private static final char[] KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR = { '8' }; @@ -766,7 +764,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { private final Rect mTextBounds = new Rect(); private float getCharHeight(char[] referenceChar, Paint paint) { - final Integer key = getCharGeometryCacheKey(referenceChar[0], paint); + final int key = getCharGeometryCacheKey(referenceChar[0], paint); final Float cachedValue = sTextHeightCache.get(key); if (cachedValue != null) return cachedValue; @@ -778,7 +776,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } private float getCharWidth(char[] referenceChar, Paint paint) { - final Integer key = getCharGeometryCacheKey(referenceChar[0], paint); + final int key = getCharGeometryCacheKey(referenceChar[0], paint); final Float cachedValue = sTextWidthCache.get(key); if (cachedValue != null) return cachedValue; diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 383298de91..7714ba892d 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -127,7 +127,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private static final int MSG_TYPING_STATE_EXPIRED = 4; private final KeyTimerParams mParams; - private boolean mInKeyRepeat; public KeyTimerHandler(LatinKeyboardView outerInstance, KeyTimerParams params) { super(outerInstance); @@ -140,8 +139,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final PointerTracker tracker = (PointerTracker) msg.obj; switch (msg.what) { case MSG_REPEAT_KEY: - tracker.onRegisterKey(tracker.getKey()); - startKeyRepeatTimer(tracker, mParams.mKeyRepeatInterval); + final Key currentKey = tracker.getKey(); + if (currentKey != null && currentKey.mCode == msg.arg1) { + tracker.onRegisterKey(currentKey); + startKeyRepeatTimer(tracker, mParams.mKeyRepeatInterval); + } break; case MSG_LONGPRESS_KEY: if (tracker != null) { @@ -158,22 +160,23 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } private void startKeyRepeatTimer(PointerTracker tracker, long delay) { - sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker), delay); + final Key key = tracker.getKey(); + if (key == null) return; + sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay); } @Override public void startKeyRepeatTimer(PointerTracker tracker) { - mInKeyRepeat = true; startKeyRepeatTimer(tracker, mParams.mKeyRepeatStartTimeout); } public void cancelKeyRepeatTimer() { - mInKeyRepeat = false; removeMessages(MSG_REPEAT_KEY); } + // TODO: Suppress layout changes in key repeat mode public boolean isInKeyRepeat() { - return mInKeyRepeat; + return hasMessages(MSG_REPEAT_KEY); } @Override @@ -451,8 +454,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke */ @Override public void setKeyboard(Keyboard keyboard) { - // Remove any pending messages, except dismissing preview - mKeyTimerHandler.cancelKeyTimers(); + // Remove any pending messages, except dismissing preview and key repeat. + mKeyTimerHandler.cancelLongPressTimer(); super.setKeyboard(keyboard); mKeyDetector.setKeyboard( keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); @@ -755,15 +758,18 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final PointerTracker tracker = PointerTracker.getPointerTracker( pointerId, this); final int px, py; + final MotionEvent motionEvent; if (mMoreKeysPanel != null && tracker.mPointerId == mMoreKeysPanelPointerTrackerId) { px = mMoreKeysPanel.translateX((int)me.getX(i)); py = mMoreKeysPanel.translateY((int)me.getY(i)); + motionEvent = null; } else { px = (int)me.getX(i); py = (int)me.getY(i); + motionEvent = me; } - tracker.onMoveEvent(px, py, eventTime); + tracker.onMoveEvent(px, py, eventTime, motionEvent); if (ENABLE_USABILITY_STUDY_LOG) { final float pointerSize = me.getSize(i); final float pointerPressure = me.getPressure(i); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 34e428e82c..32ef408b40 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -148,9 +148,6 @@ public class PointerTracker { // true if this pointer has been long-pressed and is showing a more keys panel. private boolean mIsShowingMoreKeysPanel; - // true if this pointer is repeatable key - private boolean mIsRepeatableKey; - // true if this pointer is in sliding key input boolean mIsInSlidingKeyInput; @@ -319,6 +316,13 @@ public class PointerTracker { private void setKeyDetectorInner(KeyDetector keyDetector) { mKeyDetector = keyDetector; mKeyboard = keyDetector.getKeyboard(); + final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY); + if (newKey != mCurrentKey) { + if (mDrawingProxy != null) { + setReleasedKeyGraphics(mCurrentKey); + } + mCurrentKey = newKey; + } final int keyQuarterWidth = mKeyboard.mMostCommonKeyWidth / 4; mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth; } @@ -465,7 +469,7 @@ public class PointerTracker { onUpEvent(x, y, eventTime); break; case MotionEvent.ACTION_MOVE: - onMoveEvent(x, y, eventTime); + onMoveEvent(x, y, eventTime, null); break; case MotionEvent.ACTION_CANCEL: onCancelEvent(x, y, eventTime); @@ -521,7 +525,6 @@ public class PointerTracker { || mKeyDetector.alwaysAllowsSlidingInput(); mKeyboardLayoutHasBeenChanged = false; mKeyAlreadyProcessed = false; - mIsRepeatableKey = false; mIsInSlidingKeyInput = false; mIgnoreModifierKey = false; if (key != null) { @@ -545,7 +548,7 @@ public class PointerTracker { mIsInSlidingKeyInput = true; } - public void onMoveEvent(int x, int y, long eventTime) { + public void onMoveEvent(int x, int y, long eventTime, MotionEvent me) { if (DEBUG_MOVE_EVENT) printTouchEvent("onMoveEvent:", x, y, eventTime); if (mKeyAlreadyProcessed) @@ -668,7 +671,7 @@ public class PointerTracker { } if (mKeyAlreadyProcessed) return; - if (!mIsRepeatableKey) { + if (mCurrentKey != null && !mCurrentKey.isRepeatable()) { detectAndSendKey(mCurrentKey, mKeyX, mKeyY); } } @@ -714,9 +717,6 @@ public class PointerTracker { if (key != null && key.isRepeatable()) { onRegisterKey(key); mTimerProxy.startKeyRepeatTimer(this); - mIsRepeatableKey = true; - } else { - mIsRepeatableKey = false; } } @@ -760,14 +760,10 @@ public class PointerTracker { callListenerOnRelease(key, code, false); } - private long mPreviousEventTime; - private void printTouchEvent(String title, int x, int y, long eventTime) { final Key key = mKeyDetector.detectHitKey(x, y); final String code = KeyDetector.printableCode(key); - final long delta = eventTime - mPreviousEventTime; Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %s", title, - (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, code)); - mPreviousEventTime = eventTime; + (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, eventTime, code)); } } diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index 1bc8254792..ae123e29aa 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -24,7 +24,6 @@ import com.android.inputmethod.keyboard.Keyboard.Params.TouchPositionCorrection; import com.android.inputmethod.latin.JniUtils; import java.util.Arrays; -import java.util.HashMap; public class ProximityInfo { /** MAX_PROXIMITY_CHARS_SIZE must be the same as MAX_PROXIMITY_CHARS_SIZE_INTERNAL @@ -190,10 +189,6 @@ public class ProximityInfo { private void computeNearestNeighbors() { final int defaultWidth = mMostCommonKeyWidth; final Key[] keys = mKeys; - final HashMap<Integer, Key> keyCodeMap = new HashMap<Integer, Key>(); - for (final Key key : keys) { - keyCodeMap.put(key.mCode, key); - } final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE); final int threshold = thresholdBase * thresholdBase; // Round-up so we don't have any pixels outside the grid diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java index 80f4f259b1..291b3b9438 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java @@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.util.Log; +import android.util.SparseArray; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.R; @@ -89,7 +90,7 @@ public class KeyStyles { private class DeclaredKeyStyle extends KeyStyle { private final String mParentStyleName; - private final HashMap<Integer, Object> mStyleAttributes = new HashMap<Integer, Object>(); + private final SparseArray<Object> mStyleAttributes = new SparseArray<Object>(); public DeclaredKeyStyle(String parentStyleName) { mParentStyleName = parentStyleName; @@ -100,8 +101,9 @@ public class KeyStyles { if (a.hasValue(index)) { return parseStringArray(a, index); } - if (mStyleAttributes.containsKey(index)) { - return (String[])mStyleAttributes.get(index); + final Object value = mStyleAttributes.get(index); + if (value != null) { + return (String[])value; } final KeyStyle parentStyle = mStyles.get(mParentStyleName); return parentStyle.getStringArray(a, index); @@ -112,8 +114,9 @@ public class KeyStyles { if (a.hasValue(index)) { return parseString(a, index); } - if (mStyleAttributes.containsKey(index)) { - return (String)mStyleAttributes.get(index); + final Object value = mStyleAttributes.get(index); + if (value != null) { + return (String)value; } final KeyStyle parentStyle = mStyles.get(mParentStyleName); return parentStyle.getString(a, index); @@ -124,8 +127,9 @@ public class KeyStyles { if (a.hasValue(index)) { return a.getInt(index, defaultValue); } - if (mStyleAttributes.containsKey(index)) { - return (Integer)mStyleAttributes.get(index); + final Object value = mStyleAttributes.get(index); + if (value != null) { + return (Integer)value; } final KeyStyle parentStyle = mStyles.get(mParentStyleName); return parentStyle.getInt(a, index, defaultValue); @@ -133,12 +137,13 @@ public class KeyStyles { @Override public int getFlag(TypedArray a, int index) { - int value = a.getInt(index, 0); - if (mStyleAttributes.containsKey(index)) { - value |= (Integer)mStyleAttributes.get(index); + int flags = a.getInt(index, 0); + final Object value = mStyleAttributes.get(index); + if (value != null) { + flags |= (Integer)value; } final KeyStyle parentStyle = mStyles.get(mParentStyleName); - return value | parentStyle.getFlag(a, index); + return flags | parentStyle.getFlag(a, index); } void readKeyAttributes(TypedArray keyAttr) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java index 540e63b3f3..5155851fed 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -20,6 +20,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.Log; +import android.util.SparseIntArray; import com.android.inputmethod.latin.R; @@ -31,8 +32,7 @@ public class KeyboardIconsSet { public static final int ICON_UNDEFINED = 0; private static final int ATTR_UNDEFINED = 0; - private static final HashMap<Integer, Integer> ATTR_ID_TO_ICON_ID - = new HashMap<Integer, Integer>(); + private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray(); // Icon name to icon id map. private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<String, Integer>(); @@ -76,7 +76,9 @@ public class KeyboardIconsSet { } public void loadIcons(final TypedArray keyboardAttrs) { - for (final Integer attrId : ATTR_ID_TO_ICON_ID.keySet()) { + final int size = ATTR_ID_TO_ICON_ID.size(); + for (int index = 0; index < size; index++) { + final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index); try { final Drawable icon = keyboardAttrs.getDrawable(attrId); setDefaultBounds(icon); diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java index e0452483c9..c78974dac1 100644 --- a/java/src/com/android/inputmethod/latin/AutoCorrection.java +++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java @@ -21,34 +21,17 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import android.text.TextUtils; import android.util.Log; -import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; public class AutoCorrection { private static final boolean DBG = LatinImeLogger.sDBG; private static final String TAG = AutoCorrection.class.getSimpleName(); + private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; private AutoCorrection() { // Purely static class: can't instantiate. } - public static CharSequence computeAutoCorrectionWord( - final ConcurrentHashMap<String, Dictionary> dictionaries, - final WordComposer wordComposer, final ArrayList<SuggestedWordInfo> suggestions, - final CharSequence consideredWord, final float autoCorrectionThreshold, - final CharSequence whitelistedWord) { - if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) { - return whitelistedWord; - } else if (hasAutoCorrectionForConsideredWord( - dictionaries, wordComposer, suggestions, consideredWord)) { - return consideredWord; - } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, - consideredWord, autoCorrectionThreshold)) { - return suggestions.get(0).mWord; - } - return null; - } - public static boolean isValidWord(final ConcurrentHashMap<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) { if (TextUtils.isEmpty(word)) { @@ -56,7 +39,7 @@ public class AutoCorrection { } final CharSequence lowerCasedWord = word.toString().toLowerCase(); for (final String key : dictionaries.keySet()) { - if (key.equals(Suggest.DICT_KEY_WHITELIST)) continue; + if (key.equals(Dictionary.TYPE_WHITELIST)) continue; final Dictionary dictionary = dictionaries.get(key); // It's unclear how realistically 'dictionary' can be null, but the monkey is somehow // managing to get null in here. Presumably the language is changing to a language with @@ -81,7 +64,7 @@ public class AutoCorrection { } int maxFreq = -1; for (final String key : dictionaries.keySet()) { - if (key.equals(Suggest.DICT_KEY_WHITELIST)) continue; + if (key.equals(Dictionary.TYPE_WHITELIST)) continue; final Dictionary dictionary = dictionaries.get(key); if (null == dictionary) continue; final int tempFreq = dictionary.getFrequency(word); @@ -92,11 +75,12 @@ public class AutoCorrection { return maxFreq; } - public static boolean allowsToBeAutoCorrected( + // Returns true if this is a whitelist entry, or it isn't in any dictionary. + public static boolean isWhitelistedOrNotAWord( final ConcurrentHashMap<String, Dictionary> dictionaries, final CharSequence word, final boolean ignoreCase) { final WhitelistDictionary whitelistDictionary = - (WhitelistDictionary)dictionaries.get(Suggest.DICT_KEY_WHITELIST); + (WhitelistDictionary)dictionaries.get(Dictionary.TYPE_WHITELIST); // If "word" is in the whitelist dictionary, it should not be auto corrected. if (whitelistDictionary != null && whitelistDictionary.shouldForciblyAutoCorrectFrom(word)) { @@ -105,33 +89,18 @@ public class AutoCorrection { return !isValidWord(dictionaries, word, ignoreCase); } - private static boolean hasAutoCorrectionForWhitelistedWord(CharSequence whiteListedWord) { - return whiteListedWord != null; - } - - private static boolean hasAutoCorrectionForConsideredWord( - final ConcurrentHashMap<String, Dictionary> dictionaries, - final WordComposer wordComposer, final ArrayList<SuggestedWordInfo> suggestions, - final CharSequence consideredWord) { - if (TextUtils.isEmpty(consideredWord)) return false; - return wordComposer.size() > 1 && suggestions.size() > 0 - && !allowsToBeAutoCorrected(dictionaries, consideredWord, false); - } - - private static boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer, - ArrayList<SuggestedWordInfo> suggestions, + public static boolean suggestionExceedsAutoCorrectionThreshold(SuggestedWordInfo suggestion, CharSequence consideredWord, float autoCorrectionThreshold) { - if (wordComposer.size() > 1 && suggestions.size() > 0) { - final SuggestedWordInfo autoCorrectionSuggestion = suggestions.get(0); + if (null != suggestion) { //final int autoCorrectionSuggestionScore = sortedScores[0]; - final int autoCorrectionSuggestionScore = autoCorrectionSuggestion.mScore; + final int autoCorrectionSuggestionScore = suggestion.mScore; // TODO: when the normalized score of the first suggestion is nearly equals to // the normalized score of the second suggestion, behave less aggressive. final float normalizedScore = BinaryDictionary.calcNormalizedScore( - consideredWord.toString(), autoCorrectionSuggestion.mWord.toString(), + consideredWord.toString(), suggestion.mWord.toString(), autoCorrectionSuggestionScore); if (DBG) { - Log.d(TAG, "Normalized " + consideredWord + "," + autoCorrectionSuggestion + "," + Log.d(TAG, "Normalized " + consideredWord + "," + suggestion + "," + autoCorrectionSuggestionScore + ", " + normalizedScore + "(" + autoCorrectionThreshold + ")"); } @@ -139,10 +108,43 @@ public class AutoCorrection { if (DBG) { Log.d(TAG, "Auto corrected by S-threshold."); } - return true; + return !shouldBlockAutoCorrectionBySafetyNet(consideredWord.toString(), + suggestion.mWord); } } return false; } + // TODO: Resolve the inconsistencies between the native auto correction algorithms and + // this safety net + public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord, + final CharSequence suggestion) { + // Safety net for auto correction. + // Actually if we hit this safety net, it's a bug. + // If user selected aggressive auto correction mode, there is no need to use the safety + // net. + // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, + // we should not use net because relatively edit distance can be big. + final int typedWordLength = typedWord.length(); + if (typedWordLength < MINIMUM_SAFETY_NET_CHAR_LENGTH) { + return false; + } + final int maxEditDistanceOfNativeDictionary = + (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; + final int distance = BinaryDictionary.editDistance(typedWord, suggestion.toString()); + if (DBG) { + Log.d(TAG, "Autocorrected edit distance = " + distance + + ", " + maxEditDistanceOfNativeDictionary); + } + if (distance > maxEditDistanceOfNativeDictionary) { + if (DBG) { + Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestion); + Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " + + "Turning off auto-correction."); + } + return true; + } else { + return false; + } + } } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index d0613bd722..ae415d0ab1 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -20,7 +20,9 @@ import android.content.Context; import android.text.TextUtils; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; @@ -40,17 +42,18 @@ public class BinaryDictionary extends Dictionary { */ public static final int MAX_WORD_LENGTH = 48; public static final int MAX_WORDS = 18; + public static final int MAX_SPACES = 16; private static final String TAG = "BinaryDictionary"; private static final int MAX_BIGRAMS = 60; private static final int TYPED_LETTER_MULTIPLIER = 2; - private int mDicTypeId; private long mNativeDict; private final int[] mInputCodes = new int[MAX_WORD_LENGTH]; private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; + private final int[] mSpaceIndices = new int[MAX_SPACES]; private final int[] mScores = new int[MAX_WORDS]; private final int[] mBigramScores = new int[MAX_BIGRAMS]; @@ -65,14 +68,12 @@ public class BinaryDictionary extends Dictionary { * @param offset the offset of the dictionary data within the file. * @param length the length of the binary data. * @param useFullEditDistance whether to use the full edit distance in suggestions + * @param dictType the dictionary type, as a human-readable string */ public BinaryDictionary(final Context context, final String filename, final long offset, final long length, - final boolean useFullEditDistance, final Locale locale) { - // Note: at the moment a binary dictionary is always of the "main" type. - // Initializing this here will help transitioning out of the scheme where - // the Suggest class knows everything about every single dictionary. - mDicTypeId = Suggest.DIC_MAIN; + final boolean useFullEditDistance, final Locale locale, final String dictType) { + super(dictType); mUseFullEditDistance = useFullEditDistance; loadDictionary(filename, offset, length); } @@ -87,8 +88,10 @@ public class BinaryDictionary extends Dictionary { private native int getFrequencyNative(long dict, int[] word, int wordLength); private native boolean isValidBigramNative(long dict, int[] word1, int[] word2); private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates, - int[] yCoordinates, int[] inputCodes, int codesSize, int[] prevWordForBigrams, - boolean useFullEditDistance, char[] outputChars, int[] scores); + int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodes, int codesSize, + int commitPoint, boolean isGesture, + int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars, + int[] scores, int[] outputIndices); private native int getBigramsNative(long dict, int[] prevWord, int prevWordLength, int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores, int maxWordLength, int maxBigrams); @@ -103,9 +106,9 @@ public class BinaryDictionary extends Dictionary { } @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback) { - if (mNativeDict == 0) return; + public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, + final CharSequence previousWord) { + if (mNativeDict == 0) return null; int[] codePoints = StringUtils.toCodePointArray(previousWord.toString()); Arrays.fill(mOutputChars_bigrams, (char) 0); @@ -123,6 +126,7 @@ public class BinaryDictionary extends Dictionary { count = MAX_BIGRAMS; } + final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); for (int j = 0; j < count; ++j) { if (codesSize > 0 && mBigramScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; @@ -131,19 +135,22 @@ public class BinaryDictionary extends Dictionary { ++len; } if (len > 0) { - callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j], - mDicTypeId, Dictionary.BIGRAM); + suggestions.add(new SuggestedWordInfo( + new String(mOutputChars_bigrams, start, len), + mBigramScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType)); } } + return suggestions; } // proximityInfo and/or prevWordForBigrams may not be null. @Override - public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, - final WordCallback callback, final ProximityInfo proximityInfo) { + public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { final int count = getSuggestions(codes, prevWordForBigrams, proximityInfo, mOutputChars, - mScores); + mScores, mSpaceIndices); + final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); for (int j = 0; j < count; ++j) { if (mScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; @@ -152,10 +159,13 @@ public class BinaryDictionary extends Dictionary { ++len; } if (len > 0) { - callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId, - Dictionary.UNIGRAM); + // TODO: actually get the kind from native code + suggestions.add(new SuggestedWordInfo( + new String(mOutputChars, start, len), + mScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType)); } } + return suggestions; } /* package for test */ boolean isValidDictionary() { @@ -165,7 +175,7 @@ public class BinaryDictionary extends Dictionary { // proximityInfo may not be null. /* package for test */ int getSuggestions(final WordComposer codes, final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo, - char[] outputChars, int[] scores) { + char[] outputChars, int[] scores, int[] spaceIndices) { if (!isValidDictionary()) return -1; final int codesSize = codes.size(); @@ -179,14 +189,22 @@ public class BinaryDictionary extends Dictionary { Arrays.fill(outputChars, (char) 0); Arrays.fill(scores, 0); - final int[] prevWordCodePointArray = null == prevWordForBigrams + // TODO: toLowerCase in the native code + final int[] prevWordCodePointArray = (null == prevWordForBigrams) ? null : StringUtils.toCodePointArray(prevWordForBigrams.toString()); - // TODO: pass the previous word to native code - return getSuggestionsNative( - mNativeDict, proximityInfo.getNativeProximityInfo(), - codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, - prevWordCodePointArray, mUseFullEditDistance, outputChars, scores); + int[] emptyArray = new int[codesSize]; + Arrays.fill(emptyArray, 0); + + //final int commitPoint = codes.getCommitPoint(); + //codes.clearCommitPoint(); + + final InputPointers ips = codes.getInputPointers(); + + return getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(), + ips.getXCoordinates(), ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), + mInputCodes, codesSize, 0 /* unused */, false, prevWordCodePointArray, + mUseFullEditDistance, outputChars, scores, spaceIndices); } public static float calcNormalizedScore(String before, String after, int score) { diff --git a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java b/java/src/com/android/inputmethod/latin/BoundedTreeSet.java new file mode 100644 index 0000000000..cf977617d1 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/BoundedTreeSet.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin; + +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; + +import java.util.Collection; +import java.util.Comparator; +import java.util.TreeSet; + +/** + * A TreeSet that is bounded in size and throws everything that's smaller than its limit + */ +public class BoundedTreeSet extends TreeSet<SuggestedWordInfo> { + private final int mCapacity; + public BoundedTreeSet(final Comparator<SuggestedWordInfo> comparator, final int capacity) { + super(comparator); + mCapacity = capacity; + } + + @Override + public boolean add(final SuggestedWordInfo e) { + if (size() < mCapacity) return super.add(e); + if (comparator().compare(e, last()) > 0) return false; + super.add(e); + pollLast(); // removes the last element + return true; + } + + @Override + public boolean addAll(final Collection<? extends SuggestedWordInfo> e) { + if (null == e) return false; + return super.addAll(e); + } +} diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 10e511eaff..5edc4314fc 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -62,8 +62,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { */ private final boolean mUseFirstLastBigrams; - public ContactsBinaryDictionary(final Context context, final int dicTypeId, Locale locale) { - super(context, getFilenameWithLocale(NAME, locale.toString()), dicTypeId); + public ContactsBinaryDictionary(final Context context, Locale locale) { + super(context, getFilenameWithLocale(NAME, locale.toString()), Dictionary.TYPE_CONTACTS); mLocale = locale; mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale); registerObserver(context); @@ -120,12 +120,6 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { } } - @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback) { - super.getBigrams(codes, previousWord, callback); - } - private boolean useFirstLastBigramsForLocale(Locale locale) { // TODO: Add firstname/lastname bigram rules for other languages. if (locale != null && locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) { @@ -167,7 +161,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { * bigrams depending on locale. */ private void addName(String name) { - int len = name.codePointCount(0, name.length()); + int len = StringUtils.codePointCount(name); String prevWord = null; // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { @@ -177,7 +171,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { i = end - 1; // Don't add single letter words, possibly confuses // capitalization of i. - final int wordLen = word.codePointCount(0, word.length()); + final int wordLen = StringUtils.codePointCount(word); if (wordLen < MAX_WORD_LENGTH && wordLen > 1) { super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS); if (!TextUtils.isEmpty(prevWord)) { @@ -266,14 +260,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { * Checks if the words in a name are in the current binary dictionary. */ private boolean isNameInDictionary(String name) { - int len = name.codePointCount(0, name.length()); + int len = StringUtils.codePointCount(name); String prevWord = null; for (int i = 0; i < len; i++) { if (Character.isLetter(name.codePointAt(i))) { int end = getWordEndPosition(name, len, i); String word = name.substring(i, end); i = end - 1; - final int wordLen = word.codePointCount(0, word.length()); + final int wordLen = StringUtils.codePointCount(word); if (wordLen < MAX_WORD_LENGTH && wordLen > 1) { if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) { if (!super.isValidBigramLocked(prevWord, word)) { diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index 9c3d46e70e..0835450c12 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -17,6 +17,9 @@ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; + +import java.util.ArrayList; /** * Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key @@ -28,55 +31,43 @@ public abstract class Dictionary { */ protected static final int FULL_WORD_SCORE_MULTIPLIER = 2; - public static final int UNIGRAM = 0; - public static final int BIGRAM = 1; - public static final int NOT_A_PROBABILITY = -1; - /** - * Interface to be implemented by classes requesting words to be fetched from the dictionary. - * @see #getWords(WordComposer, CharSequence, WordCallback, ProximityInfo) - */ - public interface WordCallback { - /** - * Adds a word to a list of suggestions. The word is expected to be ordered based on - * the provided score. - * @param word the character array containing the word - * @param wordOffset starting offset of the word in the character array - * @param wordLength length of valid characters in the character array - * @param score the score of occurrence. This is normalized between 1 and 255, but - * can exceed those limits - * @param dicTypeId of the dictionary where word was from - * @param dataType tells type of this data, either UNIGRAM or BIGRAM - * @return true if the word was added, false if no more words are required - */ - boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId, - int dataType); + + public static final String TYPE_USER_TYPED = "user_typed"; + public static final String TYPE_APPLICATION_DEFINED = "application_defined"; + public static final String TYPE_HARDCODED = "hardcoded"; // punctuation signs and such + public static final String TYPE_MAIN = "main"; + public static final String TYPE_CONTACTS = "contacts"; + // User dictionary, the system-managed one. + public static final String TYPE_USER = "user"; + // User history dictionary internal to LatinIME. + public static final String TYPE_USER_HISTORY = "history"; + public static final String TYPE_WHITELIST ="whitelist"; + protected final String mDictType; + + public Dictionary(final String dictType) { + mDictType = dictType; } /** * Searches for words in the dictionary that match the characters in the composer. Matched - * words are added through the callback object. - * @param composer the key sequence to match + * words are returned as an ArrayList. + * @param composer the key sequence to match with coordinate info, as a WordComposer * @param prevWordForBigrams the previous word, or null if none - * @param callback the callback object to send matched words to as possible candidates * @param proximityInfo the object for key proximity. May be ignored by some implementations. - * @see WordCallback#addWord(char[], int, int, int, int, int) + * @return the list of suggestions */ - abstract public void getWords(final WordComposer composer, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo); + abstract public ArrayList<SuggestedWordInfo> getWords(final WordComposer composer, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo); /** - * Searches for pairs in the bigram dictionary that matches the previous word and all the - * possible words following are added through the callback object. + * Searches for pairs in the bigram dictionary that matches the previous word. * @param composer the key sequence to match * @param previousWord the word before - * @param callback the callback object to send possible word following previous word + * @return the list of suggestions */ - public void getBigrams(final WordComposer composer, final CharSequence previousWord, - final WordCallback callback) { - // empty base implementation - } + public abstract ArrayList<SuggestedWordInfo> getBigrams(final WordComposer composer, + final CharSequence previousWord); /** * Checks if the given word occurs in the dictionary diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index 26c2e637e6..dcc53c59f9 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -17,9 +17,11 @@ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import android.util.Log; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.concurrent.CopyOnWriteArrayList; @@ -31,11 +33,13 @@ public class DictionaryCollection extends Dictionary { private final String TAG = DictionaryCollection.class.getSimpleName(); protected final CopyOnWriteArrayList<Dictionary> mDictionaries; - public DictionaryCollection() { + public DictionaryCollection(final String dictType) { + super(dictType); mDictionaries = new CopyOnWriteArrayList<Dictionary>(); } - public DictionaryCollection(Dictionary... dictionaries) { + public DictionaryCollection(final String dictType, Dictionary... dictionaries) { + super(dictType); if (null == dictionaries) { mDictionaries = new CopyOnWriteArrayList<Dictionary>(); } else { @@ -44,23 +48,48 @@ public class DictionaryCollection extends Dictionary { } } - public DictionaryCollection(Collection<Dictionary> dictionaries) { + public DictionaryCollection(final String dictType, Collection<Dictionary> dictionaries) { + super(dictType); mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); mDictionaries.removeAll(Collections.singleton(null)); } @Override - public void getWords(final WordComposer composer, final CharSequence prevWordForBigrams, - final WordCallback callback, final ProximityInfo proximityInfo) { - for (final Dictionary dict : mDictionaries) - dict.getWords(composer, prevWordForBigrams, callback, proximityInfo); + public ArrayList<SuggestedWordInfo> getWords(final WordComposer composer, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { + final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; + if (dictionaries.isEmpty()) return null; + // To avoid creating unnecessary objects, we get the list out of the first + // dictionary and add the rest to it if not null, hence the get(0) + ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getWords(composer, + prevWordForBigrams, proximityInfo); + if (null == suggestions) suggestions = new ArrayList<SuggestedWordInfo>(); + final int length = dictionaries.size(); + for (int i = 0; i < length; ++ i) { + final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getWords(composer, + prevWordForBigrams, proximityInfo); + if (null != sugg) suggestions.addAll(sugg); + } + return suggestions; } @Override - public void getBigrams(final WordComposer composer, final CharSequence previousWord, - final WordCallback callback) { - for (final Dictionary dict : mDictionaries) - dict.getBigrams(composer, previousWord, callback); + public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer composer, + final CharSequence previousWord) { + final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; + if (dictionaries.isEmpty()) return null; + // To avoid creating unnecessary objects, we get the list out of the first + // dictionary and add the rest to it if not null, hence the get(0) + ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getBigrams(composer, + previousWord); + if (null == suggestions) suggestions = new ArrayList<SuggestedWordInfo>(); + final int length = dictionaries.size(); + for (int i = 0; i < length; ++ i) { + final ArrayList<SuggestedWordInfo> sugg = + dictionaries.get(i).getBigrams(composer, previousWord); + if (null != sugg) suggestions.addAll(sugg); + } + return suggestions; } @Override diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index a22d73af76..06a5f4b72b 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -49,7 +49,8 @@ public class DictionaryFactory { final Locale locale, final boolean useFullEditDistance) { if (null == locale) { Log.e(TAG, "No locale defined for dictionary"); - return new DictionaryCollection(createBinaryDictionary(context, locale)); + return new DictionaryCollection(Dictionary.TYPE_MAIN, + createBinaryDictionary(context, locale)); } final LinkedList<Dictionary> dictList = new LinkedList<Dictionary>(); @@ -59,7 +60,7 @@ public class DictionaryFactory { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, - useFullEditDistance, locale); + useFullEditDistance, locale, Dictionary.TYPE_MAIN); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); } @@ -69,7 +70,7 @@ public class DictionaryFactory { // If the list is empty, that means we should not use any dictionary (for example, the user // explicitly disabled the main dictionary), so the following is okay. dictList is never // null, but if for some reason it is, DictionaryCollection handles it gracefully. - return new DictionaryCollection(dictList); + return new DictionaryCollection(Dictionary.TYPE_MAIN, dictList); } /** @@ -112,7 +113,7 @@ public class DictionaryFactory { return null; } return new BinaryDictionary(context, sourceDir, afd.getStartOffset(), afd.getLength(), - false /* useFullEditDistance */, locale); + false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource"); return null; @@ -140,7 +141,7 @@ public class DictionaryFactory { long startOffset, long length, final boolean useFullEditDistance, Locale locale) { if (dictionary.isFile()) { return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length, - useFullEditDistance, locale); + useFullEditDistance, locale, Dictionary.TYPE_MAIN); } else { Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath()); return null; diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index c65404cbc2..1cda9f2573 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -19,6 +19,7 @@ import android.os.SystemClock; import android.util.Log; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.makedict.BinaryDictInputOutput; import com.android.inputmethod.latin.makedict.FusionDictionary; import com.android.inputmethod.latin.makedict.FusionDictionary.Node; @@ -75,9 +76,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** The expandable fusion dictionary used to generate the binary dictionary. */ private FusionDictionary mFusionDictionary; - /** The dictionary type id. */ - public final int mDicTypeId; - /** * The name of this dictionary, used as the filename for storing the binary dictionary. Multiple * dictionary instances with the same filename is supported, with access controlled by @@ -123,11 +121,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * @param context The application context of the parent. * @param filename The filename for this binary dictionary. Multiple dictionaries with the same * filename is supported. - * @param dictType The type of this dictionary. + * @param dictType the dictionary type, as a human-readable string */ public ExpandableBinaryDictionary( - final Context context, final String filename, final int dictType) { - mDicTypeId = dictType; + final Context context, final String filename, final String dictType) { + super(dictType); mFilename = filename; mContext = context; mBinaryDictionary = null; @@ -194,46 +192,47 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } @Override - public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, - final WordCallback callback, final ProximityInfo proximityInfo) { + public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { asyncReloadDictionaryIfRequired(); - getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); + return getWordsInner(codes, prevWordForBigrams, proximityInfo); } - protected final void getWordsInner(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + protected final ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { // Ensure that there are no concurrent calls to getWords. If there are, do nothing and // return. if (mLocalDictionaryController.tryLock()) { try { if (mBinaryDictionary != null) { - mBinaryDictionary.getWords(codes, prevWordForBigrams, callback, proximityInfo); + return mBinaryDictionary.getWords(codes, prevWordForBigrams, proximityInfo); } } finally { mLocalDictionaryController.unlock(); } } + return null; } @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback) { + public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, + final CharSequence previousWord) { asyncReloadDictionaryIfRequired(); - getBigramsInner(codes, previousWord, callback); + return getBigramsInner(codes, previousWord); } - protected void getBigramsInner(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback) { + protected ArrayList<SuggestedWordInfo> getBigramsInner(final WordComposer codes, + final CharSequence previousWord) { if (mLocalDictionaryController.tryLock()) { try { if (mBinaryDictionary != null) { - mBinaryDictionary.getBigrams(codes, previousWord, callback); + return mBinaryDictionary.getBigrams(codes, previousWord); } } finally { mLocalDictionaryController.unlock(); } } + return null; } @Override @@ -306,7 +305,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // Build the new binary dictionary final BinaryDictionary newBinaryDictionary = new BinaryDictionary(mContext, filename, 0, length, true /* useFullEditDistance */, - null); + null, mDictType); if (mBinaryDictionary != null) { // Ensure all threads accessing the current dictionary have finished before swapping in diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java index f5886aa128..76213c0dab 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java @@ -38,7 +38,6 @@ public class ExpandableDictionary extends Dictionary { private Context mContext; private char[] mWordBuilder = new char[BinaryDictionary.MAX_WORD_LENGTH]; - private int mDicTypeId; private int mMaxDepth; private int mInputLength; @@ -152,11 +151,11 @@ public class ExpandableDictionary extends Dictionary { private int[][] mCodes; - public ExpandableDictionary(Context context, int dicTypeId) { + public ExpandableDictionary(final Context context, final String dictType) { + super(dictType); mContext = context; clearDictionary(); mCodes = new int[BinaryDictionary.MAX_WORD_LENGTH][]; - mDicTypeId = dicTypeId; } public void loadDictionary() { @@ -248,20 +247,20 @@ public class ExpandableDictionary extends Dictionary { } @Override - public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, - final WordCallback callback, final ProximityInfo proximityInfo) { + public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); // Currently updating contacts, don't return any results. - if (mUpdatingDictionary) return; + if (mUpdatingDictionary) return null; } if (codes.size() >= BinaryDictionary.MAX_WORD_LENGTH) { - return; + return null; } final ArrayList<SuggestedWordInfo> suggestions = getWordsInner(codes, prevWordForBigrams, proximityInfo); - Utils.addAllSuggestions(mDicTypeId, Dictionary.UNIGRAM, suggestions, callback); + return suggestions; } protected final ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes, @@ -269,8 +268,9 @@ public class ExpandableDictionary extends Dictionary { final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); mInputLength = codes.size(); if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; - final int[] xCoordinates = codes.getXCoordinates(); - final int[] yCoordinates = codes.getYCoordinates(); + final InputPointers ips = codes.getInputPointers(); + final int[] xCoordinates = ips.getXCoordinates(); + final int[] yCoordinates = ips.getYCoordinates(); // Cache the codes so that we don't have to lookup an array list for (int i = 0; i < mInputLength; i++) { // TODO: Calculate proximity info here. @@ -383,7 +383,7 @@ public class ExpandableDictionary extends Dictionary { // the respective size of the typed word and the suggestion if it matters sometime // in the future. suggestions.add(new SuggestedWordInfo(new String(word, 0, depth + 1), finalFreq, - SuggestedWordInfo.KIND_CORRECTION)); + SuggestedWordInfo.KIND_CORRECTION, mDictType)); if (suggestions.size() >= Suggest.MAX_SUGGESTIONS) return false; } if (null != node.mShortcutTargets) { @@ -391,7 +391,7 @@ public class ExpandableDictionary extends Dictionary { for (int shortcutIndex = 0; shortcutIndex < length; ++shortcutIndex) { final char[] shortcut = node.mShortcutTargets.get(shortcutIndex); suggestions.add(new SuggestedWordInfo(new String(shortcut, 0, shortcut.length), - finalFreq, SuggestedWordInfo.KIND_SHORTCUT)); + finalFreq, SuggestedWordInfo.KIND_SHORTCUT, mDictType)); if (suggestions.size() > Suggest.MAX_SUGGESTIONS) return false; } } @@ -600,22 +600,25 @@ public class ExpandableDictionary extends Dictionary { } private void runBigramReverseLookUp(final CharSequence previousWord, - final WordCallback callback) { + final ArrayList<SuggestedWordInfo> suggestions) { // Search for the lowercase version of the word only, because that's where bigrams // store their sons. Node prevWord = searchNode(mRoots, previousWord.toString().toLowerCase(), 0, previousWord.length()); if (prevWord != null && prevWord.mNGrams != null) { - reverseLookUp(prevWord.mNGrams, callback); + reverseLookUp(prevWord.mNGrams, suggestions); } } @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback) { + public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, + final CharSequence previousWord) { if (!reloadDictionaryIfRequired()) { - runBigramReverseLookUp(previousWord, callback); + final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); + runBigramReverseLookUp(previousWord, suggestions); + return suggestions; } + return null; } /** @@ -642,11 +645,12 @@ public class ExpandableDictionary extends Dictionary { /** * reverseLookUp retrieves the full word given a list of terminal nodes and adds those words - * through callback. + * to the suggestions list passed as an argument. * @param terminalNodes list of terminal nodes we want to add + * @param suggestions the suggestion collection to add the word to */ private void reverseLookUp(LinkedList<NextWord> terminalNodes, - final WordCallback callback) { + final ArrayList<SuggestedWordInfo> suggestions) { Node node; int freq; for (NextWord nextWord : terminalNodes) { @@ -660,8 +664,9 @@ public class ExpandableDictionary extends Dictionary { } while (node != null); if (freq >= 0) { - callback.addWord(mLookedUpString, index, BinaryDictionary.MAX_WORD_LENGTH - index, - freq, mDicTypeId, Dictionary.BIGRAM); + suggestions.add(new SuggestedWordInfo(new String(mLookedUpString, index, + BinaryDictionary.MAX_WORD_LENGTH - index), + freq, SuggestedWordInfo.KIND_CORRECTION, mDictType)); } } } diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java new file mode 100644 index 0000000000..218243e9ff --- /dev/null +++ b/java/src/com/android/inputmethod/latin/InputPointers.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin; + +import java.util.Arrays; + +public class InputPointers { + private final ScalableIntArray mXCoordinates = new ScalableIntArray(); + private final ScalableIntArray mYCoordinates = new ScalableIntArray(); + private final ScalableIntArray mPointerIds = new ScalableIntArray(); + private final ScalableIntArray mTimes = new ScalableIntArray(); + + public void addPointer(int index, int x, int y, int pointerId, int time) { + mXCoordinates.add(index, x); + mYCoordinates.add(index, y); + mPointerIds.add(index, pointerId); + mTimes.add(index, time); + } + + public void addPointer(int x, int y, int pointerId, int time) { + mXCoordinates.add(x); + mYCoordinates.add(y); + mPointerIds.add(pointerId); + mTimes.add(time); + } + + public void set(InputPointers ip) { + mXCoordinates.set(ip.mXCoordinates); + mYCoordinates.set(ip.mYCoordinates); + mPointerIds.set(ip.mPointerIds); + mTimes.set(ip.mTimes); + } + + public void copy(InputPointers ip) { + mXCoordinates.copy(ip.mXCoordinates); + mYCoordinates.copy(ip.mYCoordinates); + mPointerIds.copy(ip.mPointerIds); + mTimes.copy(ip.mTimes); + } + + public void reset() { + mXCoordinates.reset(); + mYCoordinates.reset(); + mPointerIds.reset(); + mTimes.reset(); + } + + public int getPointerSize() { + return mXCoordinates.getLength(); + } + + public int[] getXCoordinates() { + return mXCoordinates.mArray; + } + + public int[] getYCoordinates() { + return mYCoordinates.mArray; + } + + public int[] getPointerIds() { + return mPointerIds.mArray; + } + + public int[] getTimes() { + return mTimes.mArray; + } + + private static class ScalableIntArray { + private static final int DEFAULT_SIZE = BinaryDictionary.MAX_WORD_LENGTH; + private int[] mArray; + private int mLength; + + public ScalableIntArray() { + reset(); + } + + public void add(int index, int val) { + if (mLength < index + 1) { + mLength = index; + add(val); + } else { + mArray[index] = val; + } + } + + public void add(int val) { + if (mLength >= mArray.length) { + final int[] newArray = new int[mLength * 2]; + System.arraycopy(mArray, 0, newArray, 0, mLength); + } + mArray[mLength] = val; + ++mLength; + } + + public int getLength() { + return mLength; + } + + public void reset() { + mArray = new int[DEFAULT_SIZE]; + mLength = 0; + } + + public int[] getPrimitiveArray() { + return mArray; + } + + public void copy(ScalableIntArray ip) { + mArray = Arrays.copyOf(ip.mArray, ip.mArray.length); + } + + public void set(ScalableIntArray ip) { + mArray = ip.mArray; + mLength = ip.mLength; + } + } +} diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java index 4e1f5fe921..318aecb503 100644 --- a/java/src/com/android/inputmethod/latin/LastComposedWord.java +++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java @@ -41,26 +41,26 @@ public class LastComposedWord { public static final int NOT_A_SEPARATOR = -1; public final int[] mPrimaryKeyCodes; - public final int[] mXCoordinates; - public final int[] mYCoordinates; public final String mTypedWord; public final String mCommittedWord; public final int mSeparatorCode; public final CharSequence mPrevWord; + public final InputPointers mInputPointers = new InputPointers(); private boolean mActive; public static final LastComposedWord NOT_A_COMPOSED_WORD = - new LastComposedWord(null, null, null, "", "", NOT_A_SEPARATOR, null); + new LastComposedWord(null, null, "", "", NOT_A_SEPARATOR, null); // Warning: this is using the passed objects as is and fully expects them to be // immutable. Do not fiddle with their contents after you passed them to this constructor. - public LastComposedWord(final int[] primaryKeyCodes, final int[] xCoordinates, - final int[] yCoordinates, final String typedWord, final String committedWord, + public LastComposedWord(final int[] primaryKeyCodes, final InputPointers inputPointers, + final String typedWord, final String committedWord, final int separatorCode, final CharSequence prevWord) { mPrimaryKeyCodes = primaryKeyCodes; - mXCoordinates = xCoordinates; - mYCoordinates = yCoordinates; + if (inputPointers != null) { + mInputPointers.copy(inputPointers); + } mTypedWord = typedWord; mCommittedWord = committedWord; mSeparatorCode = separatorCode; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 5cbf40400f..21f0ea0077 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -471,8 +471,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged() // is not guaranteed. It may even be called at the same time on a different thread. if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); - mUserHistoryDictionary = UserHistoryDictionary.getInstance( - this, localeStr, Suggest.DIC_USER_HISTORY, mPrefs); + mUserHistoryDictionary = UserHistoryDictionary.getInstance(this, localeStr, mPrefs); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); } @@ -500,8 +499,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // If the locale has changed then recreate the contacts dictionary. This // allows locale dependent rules for handling bigram name predictions. oldContactsDictionary.close(); - dictionaryToUse = new ContactsBinaryDictionary( - this, Suggest.DIC_CONTACTS, locale); + dictionaryToUse = new ContactsBinaryDictionary(this, locale); } else { // Make sure the old contacts dictionary is opened. If it is already open, // this is a no-op, so it's safe to call it anyways. @@ -509,7 +507,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen dictionaryToUse = oldContactsDictionary; } } else { - dictionaryToUse = new ContactsBinaryDictionary(this, Suggest.DIC_CONTACTS, locale); + dictionaryToUse = new ContactsBinaryDictionary(this, locale); } } @@ -890,7 +888,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen applicationSuggestedWords, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, - false /* allowsToBeAutoCorrected */, false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */); @@ -1718,9 +1715,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } - mHandler.cancelUpdateSuggestions(); - mHandler.cancelUpdateBigramPredictions(); - if (!mWordComposer.isComposingWord()) { // We are never called with an empty word composer, but if because of a bug // we are, what we should do here is just call updateBigramsPredictions. This will @@ -1736,7 +1730,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // getSuggestedWords handles gracefully a null value of prevWord final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer, prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), - mCurrentSettings.mCorrectionEnabled); + mCurrentSettings.mCorrectionEnabled, false); // Basically, we update the suggestion strip only when suggestion count > 1. However, // there is an exception: We update the suggestion strip whenever typed word's length @@ -1745,7 +1739,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // need to clear the previous state when the user starts typing a word (i.e. typed word's // length == 1). if (suggestedWords.size() > 1 || typedWord.length() == 1 - || !suggestedWords.mAllowsToBeAutoCorrected + || !suggestedWords.mTypedWordValid || mSuggestionsView.isShowingAddToDictionaryHint()) { showSuggestions(suggestedWords, typedWord); } else { @@ -1760,7 +1754,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen new SuggestedWords(typedWordAndPreviousSuggestions, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, - false /* allowsToBeAutoCorrected */, false /* isPunctuationSuggestions */, true /* isObsoleteSuggestions */, false /* isPrediction */); @@ -1771,7 +1764,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void showSuggestions(final SuggestedWords suggestedWords, final CharSequence typedWord) { final CharSequence autoCorrection; if (suggestedWords.size() > 0) { - if (suggestedWords.hasAutoCorrectionWord()) { + if (suggestedWords.mWillAutoCorrect) { autoCorrection = suggestedWords.getWord(1); } else { autoCorrection = typedWord; @@ -1936,8 +1929,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void updateBigramPredictions() { - if (mSuggest == null || !mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) + mHandler.cancelUpdateSuggestions(); + mHandler.cancelUpdateBigramPredictions(); + + if (mSuggest == null || !mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) { + if (mWordComposer.isComposingWord()) { + Log.w(TAG, "Called updateBigramPredictions but suggestions were not requested!"); + mWordComposer.setAutoCorrection(mWordComposer.getTypedWord()); + } return; + } if (!mCurrentSettings.mBigramPredictionEnabled) { setPunctuationSuggestions(); @@ -1948,7 +1949,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (mCurrentSettings.mCorrectionEnabled) { final CharSequence prevWord = mConnection.getThisWord(mCurrentSettings.mWordSeparators); if (!TextUtils.isEmpty(prevWord)) { - suggestedWords = mSuggest.getBigramPredictions(prevWord); + suggestedWords = mSuggest.getSuggestedWords(mWordComposer, + prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), + mCurrentSettings.mCorrectionEnabled, true); } else { suggestedWords = null; } diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java index dc0868e7c3..e843848bc5 100644 --- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java +++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java @@ -71,7 +71,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang public static void onStartSuggestion(CharSequence previousWords) { } - public static void onAddSuggestedWord(String word, int typeId, int dataType) { + public static void onAddSuggestedWord(String word, String sourceDictionaryId) { } public static void onSetKeyboard(Keyboard kb) { diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java index cf3cc78732..e83d7c84a1 100644 --- a/java/src/com/android/inputmethod/latin/ResearchLogger.java +++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java @@ -197,6 +197,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang Log.d(TAG, "stop called"); if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) { mLoggingState = LOGGING_STATE_STOPPING; + flushEventQueue(true); // put this in the Handler queue so pending writes are processed first. mLoggingHandler.post(new Runnable() { @Override @@ -379,11 +380,52 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mCurrentLogUnit.addLogAtom(keys, values, false); } + // Used to track how often words are logged. Too-frequent logging can leak + // semantics, disclosing private data. + /* package for test */ static class LoggingFrequencyState { + private static final int DEFAULT_WORD_LOG_FREQUENCY = 10; + private int mWordsRemainingToSkip; + private final int mFrequency; + + /** + * Tracks how often words may be uploaded. + * + * @param frequency 1=Every word, 2=Every other word, etc. + */ + public LoggingFrequencyState(int frequency) { + mFrequency = frequency; + mWordsRemainingToSkip = mFrequency; + } + + public void onWordLogged() { + mWordsRemainingToSkip = mFrequency; + } + + public void onWordNotLogged() { + if (mWordsRemainingToSkip > 1) { + mWordsRemainingToSkip--; + } + } + + public boolean isSafeToLog() { + return mWordsRemainingToSkip <= 1; + } + } + + /* package for test */ LoggingFrequencyState mLoggingFrequencyState = + new LoggingFrequencyState(LoggingFrequencyState.DEFAULT_WORD_LOG_FREQUENCY); + /* package for test */ boolean isPrivacyThreat(String word) { - // currently: word not in dictionary or contains numbers. + // Current checks: + // - Word not in dictionary + // - Word contains numbers + // - Privacy-safe word not logged recently if (TextUtils.isEmpty(word)) { return false; } + if (!mLoggingFrequencyState.isSafeToLog()) { + return true; + } final int length = word.length(); boolean hasLetter = false; for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { @@ -410,15 +452,26 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang return false; } + private void onWordComplete(String word) { + final boolean isPrivacyThreat = isPrivacyThreat(word); + flushEventQueue(isPrivacyThreat); + if (isPrivacyThreat) { + mLoggingFrequencyState.onWordNotLogged(); + } else { + mLoggingFrequencyState.onWordLogged(); + } + } + /** * Write out enqueued LogEvents to the log, possibly dropping privacy sensitive events. */ - /* package for test */ synchronized void flushQueue(boolean removePotentiallyPrivateEvents) { + /* package for test */ synchronized void flushEventQueue( + boolean removePotentiallyPrivateEvents) { if (isAllowedToLog()) { mCurrentLogUnit.setRemovePotentiallyPrivateEvents(removePotentiallyPrivateEvents); mLoggingHandler.post(mCurrentLogUnit); - mCurrentLogUnit = new LogUnit(); } + mCurrentLogUnit = new LogUnit(); } private synchronized void outputEvent(final String[] keys, final Object[] values) { @@ -479,12 +532,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang SuggestedWords words = (SuggestedWords) value; mJsonWriter.beginObject(); mJsonWriter.name("typedWordValid").value(words.mTypedWordValid); - mJsonWriter.name("hasAutoCorrectionCandidate") - .value(words.mHasAutoCorrectionCandidate); + mJsonWriter.name("willAutoCorrect").value(words.mWillAutoCorrect); mJsonWriter.name("isPunctuationSuggestions") .value(words.mIsPunctuationSuggestions); - mJsonWriter.name("allowsToBeAutoCorrected") - .value(words.mAllowsToBeAutoCorrected); mJsonWriter.name("isObsoleteSuggestions") .value(words.mIsObsoleteSuggestions); mJsonWriter.name("isPrediction") @@ -652,7 +702,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent( EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values); - researchLogger.flushQueue(researchLogger.isPrivacyThreat(autoCorrection)); } private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = { @@ -665,7 +714,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang }; final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values); - researchLogger.flushQueue(researchLogger.isPrivacyThreat(scrubbedWord)); + researchLogger.onWordComplete(scrubbedWord); } private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = { @@ -743,7 +792,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } final ResearchLogger researchLogger = getInstance(); researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values); - researchLogger.flushQueue(true); // Play it safe. Remove privacy-sensitive events. + researchLogger.flushEventQueue(true); // Play it safe. Remove privacy-sensitive events. } } @@ -824,7 +873,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent( EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values); - researchLogger.flushQueue(researchLogger.isPrivacyThreat(cs.toString())); } private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = { @@ -839,7 +887,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final ResearchLogger researchLogger = getInstance(); researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, values); - researchLogger.flushQueue(researchLogger.isPrivacyThreat(suggestion.toString())); } private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = { diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 0c19bed057..40d327ebb6 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -340,13 +340,6 @@ public class RichInputConnection { * Returns the word before the cursor if the cursor is at the end of a word, null otherwise */ public CharSequence getWordBeforeCursorIfAtEndOfWord(final SettingsValues settings) { - // Bail out if the cursor is not at the end of a word (cursor must be preceded by - // non-whitespace, non-separator, non-start-of-text) - // Example ("|" is the cursor here) : <SOL>"|a" " |a" " | " all get rejected here. - final CharSequence textBeforeCursor = getTextBeforeCursor(1, 0); - if (TextUtils.isEmpty(textBeforeCursor) - || settings.isWordSeparator(textBeforeCursor.charAt(0))) return null; - // Bail out if the cursor is in the middle of a word (cursor must be followed by whitespace, // separator or end of line/text) // Example: "test|"<EOL> "te|st" get rejected here @@ -363,6 +356,15 @@ public class RichInputConnection { word = word.subSequence(1, word.length()); } if (TextUtils.isEmpty(word)) return null; + // Find the last code point of the string + final int lastCodePoint = Character.codePointBefore(word, word.length()); + // If for some reason the text field contains non-unicode binary data, or if the + // charsequence is exactly one char long and the contents is a low surrogate, return null. + if (!Character.isDefined(lastCodePoint)) return null; + // Bail out if the cursor is not at the end of a word (cursor must be preceded by + // non-whitespace, non-separator, non-start-of-text) + // Example ("|" is the cursor here) : <SOL>"|a" " |a" " | " all get rejected here. + if (settings.isWordSeparator(lastCodePoint)) return null; final char firstChar = word.charAt(0); // we just tested that word is not empty if (word.length() == 1 && !Character.isLetter(firstChar)) return null; diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 4c67b4957f..4c89a6e914 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -143,19 +143,39 @@ public class Settings extends InputMethodSettingsFragment generalSettings.removePreference(mVoicePreference); } + final PreferenceGroup advancedSettings = + (PreferenceGroup) findPreference(PREF_ADVANCED_SETTINGS); if (!VibratorUtils.getInstance(context).hasVibrator()) { - final PreferenceGroup advancedSettings = - (PreferenceGroup) findPreference(PREF_ADVANCED_SETTINGS); generalSettings.removePreference(findPreference(PREF_VIBRATE_ON)); if (null != advancedSettings) { // Theoretically advancedSettings cannot be null advancedSettings.removePreference(findPreference(PREF_VIBRATION_DURATION_SETTINGS)); } } - final boolean showPopupOption = res.getBoolean( + final boolean showKeyPreviewPopupOption = res.getBoolean( R.bool.config_enable_show_popup_on_keypress_option); - if (!showPopupOption) { + mKeyPreviewPopupDismissDelay = + (ListPreference) findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); + if (!showKeyPreviewPopupOption) { generalSettings.removePreference(findPreference(PREF_POPUP_ON)); + if (null != advancedSettings) { // Theoretically advancedSettings cannot be null + advancedSettings.removePreference(mKeyPreviewPopupDismissDelay); + } + } else { + final String[] entries = new String[] { + res.getString(R.string.key_preview_popup_dismiss_no_delay), + res.getString(R.string.key_preview_popup_dismiss_default_delay), + }; + final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger( + R.integer.config_key_preview_linger_timeout)); + mKeyPreviewPopupDismissDelay.setEntries(entries); + mKeyPreviewPopupDismissDelay.setEntryValues( + new String[] { "0", popupDismissDelayDefaultValue }); + if (null == mKeyPreviewPopupDismissDelay.getValue()) { + mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue); + } + mKeyPreviewPopupDismissDelay.setEnabled( + SettingsValues.isKeyPreviewPopupEnabled(prefs, res)); } final CheckBoxPreference includeOtherImesInLanguageSwitchList = @@ -163,23 +183,6 @@ public class Settings extends InputMethodSettingsFragment includeOtherImesInLanguageSwitchList.setEnabled( !SettingsValues.isLanguageSwitchKeySupressed(prefs)); - mKeyPreviewPopupDismissDelay = - (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); - final String[] entries = new String[] { - res.getString(R.string.key_preview_popup_dismiss_no_delay), - res.getString(R.string.key_preview_popup_dismiss_default_delay), - }; - final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger( - R.integer.config_key_preview_linger_timeout)); - mKeyPreviewPopupDismissDelay.setEntries(entries); - mKeyPreviewPopupDismissDelay.setEntryValues( - new String[] { "0", popupDismissDelayDefaultValue }); - if (null == mKeyPreviewPopupDismissDelay.getValue()) { - mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue); - } - mKeyPreviewPopupDismissDelay.setEnabled( - SettingsValues.isKeyPreviewPopupEnabled(prefs, res)); - final PreferenceScreen dictionaryLink = (PreferenceScreen) findPreference(PREF_CONFIGURE_DICTIONARIES_KEY); final Intent intent = dictionaryLink.getIntent(); @@ -305,13 +308,15 @@ public class Settings extends InputMethodSettingsFragment private void updateKeyPreviewPopupDelaySummary() { final ListPreference lp = mKeyPreviewPopupDismissDelay; - lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]); + final CharSequence[] entries = lp.getEntries(); + if (entries == null || entries.length <= 0) return; + lp.setSummary(entries[lp.findIndexOfValue(lp.getValue())]); } private void updateVoiceModeSummary() { mVoicePreference.setSummary( getResources().getStringArray(R.array.voice_input_modes_summary) - [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]); + [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]); } private void refreshEnablingsOfKeypressSoundAndVibrationSettings( diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index ef423f19b5..aab84fccdd 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -179,13 +179,13 @@ public class SettingsValues { if (puncs != null) { for (final String puncSpec : puncs) { puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec), - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED)); + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED, + Dictionary.TYPE_HARDCODED)); } } return new SuggestedWords(puncList, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, - false /* allowsToBeAutoCorrected */, true /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */); diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java index a43b90525f..6e7d985d62 100644 --- a/java/src/com/android/inputmethod/latin/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -184,6 +184,9 @@ public class StringUtils { final char[] characters = string.toCharArray(); final int length = characters.length; final int[] codePoints = new int[Character.codePointCount(characters, 0, length)]; + if (length <= 0) { + return new int[0]; + } int codePoint = Character.codePointAt(characters, 0); int dsti = 0; for (int srci = Character.charCount(codePoint); diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index ca293060ae..acc17ef3f0 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -60,6 +60,10 @@ public class SubtypeLocale { // Exceptional locales to display name map. private static final HashMap<String, String> sExceptionalDisplayNamesMap = new HashMap<String, String>(); + // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value. + // This is for compatibility to keep the same subtype ids as pre-JellyBean. + private static final HashMap<String,String> sLocaleAndExtraValueToKeyboardLayoutSetMap = + new HashMap<String,String>(); private SubtypeLocale() { // Intentional empty constructor for utility class. @@ -97,6 +101,14 @@ public class SubtypeLocale { final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resId); } + + final String[] keyboardLayoutSetMap = res.getStringArray( + R.array.locale_and_extra_value_to_keyboard_layout_set_map); + for (int i = 0; i < keyboardLayoutSetMap.length; i += 2) { + final String key = keyboardLayoutSetMap[i]; + final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1]; + sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet); + } } public static String[] getPredefinedKeyboardLayoutSet() { @@ -193,7 +205,14 @@ public class SubtypeLocale { } public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) { - final String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); + String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); + if (keyboardLayoutSet == null) { + // This subtype doesn't have a keyboardLayoutSet extra value, so lookup its keyboard + // layout set in sLocaleAndExtraValueToKeyboardLayoutSetMap to keep it compatible with + // pre-JellyBean. + final String key = subtype.getLocale() + ":" + subtype.getExtraValue(); + keyboardLayoutSet = sLocaleAndExtraValueToKeyboardLayoutSetMap.get(key); + } // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is // fixed. if (keyboardLayoutSet == null) { diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 5aecc13717..f810eccf48 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -18,7 +18,6 @@ package com.android.inputmethod.latin; import android.content.Context; import android.text.TextUtils; -import android.util.Log; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; @@ -26,6 +25,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.io.File; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashSet; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; @@ -34,80 +34,47 @@ import java.util.concurrent.ConcurrentHashMap; * This class loads a dictionary and provides a list of suggestions for a given sequence of * characters. This includes corrections and completions. */ -public class Suggest implements Dictionary.WordCallback { +public class Suggest { public static final String TAG = Suggest.class.getSimpleName(); - public static final int APPROX_MAX_WORD_LENGTH = 32; - // TODO: rename this to CORRECTION_OFF public static final int CORRECTION_NONE = 0; // TODO: rename this to CORRECTION_ON public static final int CORRECTION_FULL = 1; - // It seems the following values are only used for logging. - public static final int DIC_USER_TYPED = 0; - public static final int DIC_MAIN = 1; - public static final int DIC_USER = 2; - public static final int DIC_USER_HISTORY = 3; - public static final int DIC_CONTACTS = 4; - public static final int DIC_WHITELIST = 6; - // If you add a type of dictionary, increment DIC_TYPE_LAST_ID - // TODO: this value seems unused. Remove it? - public static final int DIC_TYPE_LAST_ID = 6; - public static final String DICT_KEY_MAIN = "main"; - public static final String DICT_KEY_CONTACTS = "contacts"; - // User dictionary, the system-managed one. - public static final String DICT_KEY_USER = "user"; - // User history dictionary for the unigram map, internal to LatinIME - public static final String DICT_KEY_USER_HISTORY_UNIGRAM = "history_unigram"; - // User history dictionary for the bigram map, internal to LatinIME - public static final String DICT_KEY_USER_HISTORY_BIGRAM = "history_bigram"; - public static final String DICT_KEY_WHITELIST ="whitelist"; - private static final boolean DBG = LatinImeLogger.sDBG; private Dictionary mMainDictionary; private ContactsBinaryDictionary mContactsDict; private WhitelistDictionary mWhiteListDictionary; - private final ConcurrentHashMap<String, Dictionary> mUnigramDictionaries = - new ConcurrentHashMap<String, Dictionary>(); - private final ConcurrentHashMap<String, Dictionary> mBigramDictionaries = + private final ConcurrentHashMap<String, Dictionary> mDictionaries = new ConcurrentHashMap<String, Dictionary>(); public static final int MAX_SUGGESTIONS = 18; - private static final int PREF_MAX_BIGRAMS = 60; - private float mAutoCorrectionThreshold; - private ArrayList<SuggestedWordInfo> mSuggestions = new ArrayList<SuggestedWordInfo>(); - private ArrayList<SuggestedWordInfo> mBigramSuggestions = new ArrayList<SuggestedWordInfo>(); - private CharSequence mConsideredWord; - - // TODO: Remove these member variables by passing more context to addWord() callback method - private boolean mIsFirstCharCapitalized; - private boolean mIsAllUpperCase; - private int mTrailingSingleQuotesCount; - - private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; + // Locale used for upper- and title-casing words + final private Locale mLocale; public Suggest(final Context context, final Locale locale) { initAsynchronously(context, locale); + mLocale = locale; } /* package for test */ Suggest(final Context context, final File dictionary, final long startOffset, final long length, final Locale locale) { final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset, length /* useFullEditDistance */, false, locale); + mLocale = locale; mMainDictionary = mainDict; - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, mainDict); initWhitelistAndAutocorrectAndPool(context, locale); } private void initWhitelistAndAutocorrectAndPool(final Context context, final Locale locale) { mWhiteListDictionary = new WhitelistDictionary(context, locale); - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_WHITELIST, mWhiteListDictionary); } private void initAsynchronously(final Context context, final Locale locale) { @@ -136,8 +103,7 @@ public class Suggest implements Dictionary.WordCallback { public void run() { final DictionaryCollection newMainDict = DictionaryFactory.createMainDictionaryFromManager(context, locale); - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, newMainDict); mMainDictionary = newMainDict; } }.start(); @@ -158,11 +124,7 @@ public class Suggest implements Dictionary.WordCallback { } public ConcurrentHashMap<String, Dictionary> getUnigramDictionaries() { - return mUnigramDictionaries; - } - - public static int getApproxMaxWordLength() { - return APPROX_MAX_WORD_LENGTH; + return mDictionaries; } /** @@ -170,7 +132,7 @@ public class Suggest implements Dictionary.WordCallback { * before the main dictionary, if set. This refers to the system-managed user dictionary. */ public void setUserDictionary(UserBinaryDictionary userDictionary) { - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER, userDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER, userDictionary); } /** @@ -180,213 +142,147 @@ public class Suggest implements Dictionary.WordCallback { */ public void setContactsDictionary(ContactsBinaryDictionary contactsDictionary) { mContactsDict = contactsDictionary; - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary); } public void setUserHistoryDictionary(UserHistoryDictionary userHistoryDictionary) { - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER_HISTORY_UNIGRAM, - userHistoryDictionary); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_USER_HISTORY_BIGRAM, - userHistoryDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, userHistoryDictionary); } public void setAutoCorrectionThreshold(float threshold) { mAutoCorrectionThreshold = threshold; } - private static CharSequence capitalizeWord(final boolean all, final boolean first, - final CharSequence word) { - if (TextUtils.isEmpty(word) || !(all || first)) return word; - final int wordLength = word.length(); - final StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); - // TODO: Must pay attention to locale when changing case. - if (all) { - sb.append(word.toString().toUpperCase()); - } else if (first) { - sb.append(Character.toUpperCase(word.charAt(0))); - if (wordLength > 1) { - sb.append(word.subSequence(1, wordLength)); - } - } - return sb; - } - - protected void addBigramToSuggestions(SuggestedWordInfo bigram) { - mSuggestions.add(bigram); - } - - private static final WordComposer sEmptyWordComposer = new WordComposer(); - public SuggestedWords getBigramPredictions(CharSequence prevWordForBigram) { - LatinImeLogger.onStartSuggestion(prevWordForBigram); - mIsFirstCharCapitalized = false; - mIsAllUpperCase = false; - mTrailingSingleQuotesCount = 0; - mSuggestions = new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); - - // Treating USER_TYPED as UNIGRAM suggestion for logging now. - LatinImeLogger.onAddSuggestedWord("", Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); - mConsideredWord = ""; - - mBigramSuggestions = new ArrayList<SuggestedWordInfo>(PREF_MAX_BIGRAMS); - - getAllBigrams(prevWordForBigram, sEmptyWordComposer); - - // Nothing entered: return all bigrams for the previous word - int insertCount = Math.min(mBigramSuggestions.size(), MAX_SUGGESTIONS); - for (int i = 0; i < insertCount; ++i) { - addBigramToSuggestions(mBigramSuggestions.get(i)); - } - - SuggestedWordInfo.removeDups(mSuggestions); - - return new SuggestedWords(mSuggestions, - false /* typedWordValid */, - false /* hasAutoCorrectionCandidate */, - false /* allowsToBeAutoCorrected */, - false /* isPunctuationSuggestions */, - false /* isObsoleteSuggestions */, - true /* isPrediction */); - } - // TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder public SuggestedWords getSuggestedWords( final WordComposer wordComposer, CharSequence prevWordForBigram, - final ProximityInfo proximityInfo, final boolean isCorrectionEnabled) { + final ProximityInfo proximityInfo, final boolean isCorrectionEnabled, + // TODO: remove isPrediction parameter. It effectively means the same thing + // as wordComposer.size() <= 1 + final boolean isPrediction) { LatinImeLogger.onStartSuggestion(prevWordForBigram); - mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); - mIsAllUpperCase = wordComposer.isAllUpperCase(); - mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); - mSuggestions = new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); + final boolean isFirstCharCapitalized = + !isPrediction && wordComposer.isFirstCharCapitalized(); + final boolean isAllUpperCase = !isPrediction && wordComposer.isAllUpperCase(); + final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); + final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator, + MAX_SUGGESTIONS); final String typedWord = wordComposer.getTypedWord(); - final String consideredWord = mTrailingSingleQuotesCount > 0 - ? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount) + final String consideredWord = trailingSingleQuotesCount > 0 + ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount) : typedWord; - // Treating USER_TYPED as UNIGRAM suggestion for logging now. - LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); - mConsideredWord = consideredWord; + LatinImeLogger.onAddSuggestedWord(typedWord, Dictionary.TYPE_USER_TYPED); if (wordComposer.size() <= 1 && isCorrectionEnabled) { // At first character typed, search only the bigrams - mBigramSuggestions = new ArrayList<SuggestedWordInfo>(PREF_MAX_BIGRAMS); - if (!TextUtils.isEmpty(prevWordForBigram)) { for (final String key : mDictionaries.keySet()) { final Dictionary dictionary = mDictionaries.get(key); suggestionsSet.addAll(dictionary.getBigrams(wordComposer, prevWordForBigram)); } } - } else if (wordComposer.size() > 1) { final WordComposer wordComposerForLookup; - if (mTrailingSingleQuotesCount > 0) { + if (trailingSingleQuotesCount > 0) { wordComposerForLookup = new WordComposer(wordComposer); - for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { + for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) { wordComposerForLookup.deleteLast(); } } else { wordComposerForLookup = wordComposer; } // At second character typed, search the unigrams (scores being affected by bigrams) - for (final String key : mUnigramDictionaries.keySet()) { + for (final String key : mDictionaries.keySet()) { // Skip UserUnigramDictionary and WhitelistDictionary to lookup - if (key.equals(DICT_KEY_USER_HISTORY_UNIGRAM) || key.equals(DICT_KEY_WHITELIST)) + if (key.equals(Dictionary.TYPE_USER_HISTORY) + || key.equals(Dictionary.TYPE_WHITELIST)) continue; - final Dictionary dictionary = mUnigramDictionaries.get(key); - dictionary.getWords(wordComposerForLookup, prevWordForBigram, this, proximityInfo); + final Dictionary dictionary = mDictionaries.get(key); + suggestionsSet.addAll(dictionary.getWords( + wordComposerForLookup, prevWordForBigram, proximityInfo)); } } - final CharSequence whitelistedWord = capitalizeWord(mIsAllUpperCase, - mIsFirstCharCapitalized, mWhiteListDictionary.getWhitelistedWord(consideredWord)); + // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid" + // but still autocorrected from - in the case the whitelist only capitalizes the word. + // The whitelist should be case-insensitive, so it's not possible to be consistent with + // a boolean flag. Right now this is handled with a slight hack in + // WhitelistDictionary#shouldForciblyAutoCorrectFrom. + final boolean allowsToBeAutoCorrected = AutoCorrection.isWhitelistedOrNotAWord( + mDictionaries, consideredWord, wordComposer.isFirstCharCapitalized()); + + final CharSequence whitelistedWord = + mWhiteListDictionary.getWhitelistedWord(consideredWord); final boolean hasAutoCorrection; - if (isCorrectionEnabled) { - final CharSequence autoCorrection = - AutoCorrection.computeAutoCorrectionWord(mUnigramDictionaries, wordComposer, - mSuggestions, consideredWord, mAutoCorrectionThreshold, - whitelistedWord); - hasAutoCorrection = (null != autoCorrection); + if (!isCorrectionEnabled || !allowsToBeAutoCorrected || wordComposer.isMostlyCaps() + || wordComposer.isResumed() || !hasMainDictionary()) { + // If we don't have a main dictionary, we never want to auto-correct. The reason for + // this is, the user may have a contact whose name happens to match a valid word in + // their language, and it will unexpectedly auto-correct. For example, if the user + // types in English with no dictionary and has a "Will" in their contact list, "will" + // would always auto-correct to "Will" which is unwanted. Hence, no main dict => no + // auto-correct. + hasAutoCorrection = false; + } else if (null != whitelistedWord) { + hasAutoCorrection = true; + } else if (suggestionsSet.isEmpty()) { + hasAutoCorrection = false; + } else if (AutoCorrection.suggestionExceedsAutoCorrectionThreshold(suggestionsSet.first(), + consideredWord, mAutoCorrectionThreshold)) { + hasAutoCorrection = true; } else { hasAutoCorrection = false; } if (whitelistedWord != null) { - if (mTrailingSingleQuotesCount > 0) { - final StringBuilder sb = new StringBuilder(whitelistedWord); - for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { - sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); - } - mSuggestions.add(0, new SuggestedWordInfo(sb.toString(), - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); - } else { - mSuggestions.add(0, new SuggestedWordInfo(whitelistedWord, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); + suggestionsSet.add(new SuggestedWordInfo(whitelistedWord, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST, + Dictionary.TYPE_WHITELIST)); + } + + final ArrayList<SuggestedWordInfo> suggestionsContainer = + new ArrayList<SuggestedWordInfo>(suggestionsSet); + final int suggestionsCount = suggestionsContainer.size(); + if (isFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) { + for (int i = 0; i < suggestionsCount; ++i) { + final SuggestedWordInfo wordInfo = suggestionsContainer.get(i); + final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo( + wordInfo, mLocale, isAllUpperCase, isFirstCharCapitalized, + trailingSingleQuotesCount); + suggestionsContainer.set(i, transformedWordInfo); } } - mSuggestions.add(0, new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_TYPED)); - SuggestedWordInfo.removeDups(mSuggestions); + for (int i = 0; i < suggestionsCount; ++i) { + final SuggestedWordInfo wordInfo = suggestionsContainer.get(i); + LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(), wordInfo.mSourceDict); + } + + if (!TextUtils.isEmpty(typedWord)) { + suggestionsContainer.add(0, new SuggestedWordInfo(typedWord, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, + Dictionary.TYPE_USER_TYPED)); + } + SuggestedWordInfo.removeDups(suggestionsContainer); final ArrayList<SuggestedWordInfo> suggestionsList; - if (DBG) { - suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, mSuggestions); + if (DBG && !suggestionsContainer.isEmpty()) { + suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, suggestionsContainer); } else { - suggestionsList = mSuggestions; + suggestionsList = suggestionsContainer; } - // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid" - // but still autocorrected from - in the case the whitelist only capitalizes the word. - // The whitelist should be case-insensitive, so it's not possible to be consistent with - // a boolean flag. Right now this is handled with a slight hack in - // WhitelistDictionary#shouldForciblyAutoCorrectFrom. - final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected( - getUnigramDictionaries(), consideredWord, wordComposer.isFirstCharCapitalized()) - // If we don't have a main dictionary, we never want to auto-correct. The reason for this - // is, the user may have a contact whose name happens to match a valid word in their - // language, and it will unexpectedly auto-correct. For example, if the user types in - // English with no dictionary and has a "Will" in their contact list, "will" would - // always auto-correct to "Will" which is unwanted. Hence, no main dict => no auto-correct. - && hasMainDictionary(); - - boolean autoCorrectionAvailable = hasAutoCorrection; - if (isCorrectionEnabled) { - autoCorrectionAvailable |= !allowsToBeAutoCorrected; - } - // Don't auto-correct words with multiple capital letter - autoCorrectionAvailable &= !wordComposer.isMostlyCaps(); - autoCorrectionAvailable &= !wordComposer.isResumed(); - if (allowsToBeAutoCorrected && suggestionsList.size() > 1 && mAutoCorrectionThreshold > 0 - && Suggest.shouldBlockAutoCorrectionBySafetyNet(typedWord, - suggestionsList.get(1).mWord)) { - autoCorrectionAvailable = false; - } return new SuggestedWords(suggestionsList, - !allowsToBeAutoCorrected /* typedWordValid */, - autoCorrectionAvailable /* hasAutoCorrectionCandidate */, - allowsToBeAutoCorrected /* allowsToBeAutoCorrected */, + // TODO: this first argument is lying. If this is a whitelisted word which is an + // actual word, it says typedWordValid = false, which looks wrong. We should either + // rename the attribute or change the value. + !isPrediction && !allowsToBeAutoCorrected /* typedWordValid */, + !isPrediction && hasAutoCorrection, /* willAutoCorrect */ false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, - false /* isPrediction */); - } - - /** - * Adds all bigram predictions for prevWord. Also checks the lower case version of prevWord if - * it contains any upper case characters. - */ - private void getAllBigrams(final CharSequence prevWord, final WordComposer wordComposer) { - if (StringUtils.hasUpperCase(prevWord)) { - // TODO: Must pay attention to locale when changing case. - final CharSequence lowerPrevWord = prevWord.toString().toLowerCase(); - for (final Dictionary dictionary : mBigramDictionaries.values()) { - dictionary.getBigrams(wordComposer, lowerPrevWord, this); - } - } - for (final Dictionary dictionary : mBigramDictionaries.values()) { - dictionary.getBigrams(wordComposer, prevWord, this); - } + isPrediction); } private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo( @@ -415,120 +311,44 @@ public class Suggest implements Dictionary.WordCallback { return suggestionsList; } - // TODO: Use codepoint instead of char - @Override - public boolean addWord(final char[] word, final int offset, final int length, int score, - final int dicTypeId, final int dataType) { - int dataTypeForLog = dataType; - final ArrayList<SuggestedWordInfo> suggestions; - final int prefMaxSuggestions; - if (dataType == Dictionary.BIGRAM) { - suggestions = mBigramSuggestions; - prefMaxSuggestions = PREF_MAX_BIGRAMS; - } else { - suggestions = mSuggestions; - prefMaxSuggestions = MAX_SUGGESTIONS; + private static class SuggestedWordInfoComparator implements Comparator<SuggestedWordInfo> { + // This comparator ranks the word info with the higher frequency first. That's because + // that's the order we want our elements in. + @Override + public int compare(final SuggestedWordInfo o1, final SuggestedWordInfo o2) { + if (o1.mScore > o2.mScore) return -1; + if (o1.mScore < o2.mScore) return 1; + if (o1.mCodePointCount < o2.mCodePointCount) return -1; + if (o1.mCodePointCount > o2.mCodePointCount) return 1; + return o1.mWord.toString().compareTo(o2.mWord.toString()); } - - int pos = 0; - - // Check if it's the same word, only caps are different - if (StringUtils.equalsIgnoreCase(mConsideredWord, word, offset, length)) { - // TODO: remove this surrounding if clause and move this logic to - // getSuggestedWordBuilder. - if (suggestions.size() > 0) { - final SuggestedWordInfo currentHighestWord = suggestions.get(0); - // If the current highest word is also equal to typed word, we need to compare - // frequency to determine the insertion position. This does not ensure strictly - // correct ordering, but ensures the top score is on top which is enough for - // removing duplicates correctly. - if (StringUtils.equalsIgnoreCase(currentHighestWord.mWord, word, offset, length) - && score <= currentHighestWord.mScore) { - pos = 1; - } - } - } else { - // Check the last one's score and bail - if (suggestions.size() >= prefMaxSuggestions - && suggestions.get(prefMaxSuggestions - 1).mScore >= score) return true; - while (pos < suggestions.size()) { - final int curScore = suggestions.get(pos).mScore; - if (curScore < score - || (curScore == score && length < suggestions.get(pos).codePointCount())) { - break; - } - pos++; - } - } - if (pos >= prefMaxSuggestions) { - return true; - } - - final StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); - // TODO: Must pay attention to locale when changing case. - if (mIsAllUpperCase) { - sb.append(new String(word, offset, length).toUpperCase()); - } else if (mIsFirstCharCapitalized) { - sb.append(Character.toUpperCase(word[offset])); - if (length > 1) { - sb.append(word, offset + 1, length - 1); - } + } + private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator = + new SuggestedWordInfoComparator(); + + private static SuggestedWordInfo getTransformedSuggestedWordInfo( + final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase, + final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) { + final StringBuilder sb = new StringBuilder(wordInfo.mWord.length()); + if (isAllUpperCase) { + sb.append(wordInfo.mWord.toString().toUpperCase(locale)); + } else if (isFirstCharCapitalized) { + sb.append(StringUtils.toTitleCase(wordInfo.mWord.toString(), locale)); } else { - sb.append(word, offset, length); + sb.append(wordInfo.mWord); } - for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { + for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) { sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); } - // TODO: figure out what type of suggestion this is - suggestions.add(pos, new SuggestedWordInfo(sb, score, SuggestedWordInfo.KIND_CORRECTION)); - if (suggestions.size() > prefMaxSuggestions) { - suggestions.remove(prefMaxSuggestions); - } else { - LatinImeLogger.onAddSuggestedWord(sb.toString(), dicTypeId, dataTypeForLog); - } - return true; + return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind, wordInfo.mSourceDict); } public void close() { final HashSet<Dictionary> dictionaries = new HashSet<Dictionary>(); - dictionaries.addAll(mUnigramDictionaries.values()); - dictionaries.addAll(mBigramDictionaries.values()); + dictionaries.addAll(mDictionaries.values()); for (final Dictionary dictionary : dictionaries) { dictionary.close(); } mMainDictionary = null; } - - // TODO: Resolve the inconsistencies between the native auto correction algorithms and - // this safety net - public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord, - final CharSequence suggestion) { - // Safety net for auto correction. - // Actually if we hit this safety net, it's a bug. - // If user selected aggressive auto correction mode, there is no need to use the safety - // net. - // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, - // we should not use net because relatively edit distance can be big. - final int typedWordLength = typedWord.length(); - if (typedWordLength < Suggest.MINIMUM_SAFETY_NET_CHAR_LENGTH) { - return false; - } - final int maxEditDistanceOfNativeDictionary = - (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; - final int distance = BinaryDictionary.editDistance(typedWord, suggestion.toString()); - if (DBG) { - Log.d(TAG, "Autocorrected edit distance = " + distance - + ", " + maxEditDistanceOfNativeDictionary); - } - if (distance > maxEditDistanceOfNativeDictionary) { - if (DBG) { - Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestion); - Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " - + "Turning off auto-correction."); - } - return true; - } else { - return false; - } - } } diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 45ac9ff536..f079c21123 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -25,27 +25,27 @@ import java.util.HashSet; public class SuggestedWords { public static final SuggestedWords EMPTY = new SuggestedWords( - new ArrayList<SuggestedWordInfo>(0), false, false, false, false, false, false); + new ArrayList<SuggestedWordInfo>(0), false, false, false, false, false); public final boolean mTypedWordValid; - public final boolean mHasAutoCorrectionCandidate; + // Note: this INCLUDES cases where the word will auto-correct to itself. A good definition + // of what this flag means would be "the top suggestion is strong enough to auto-correct", + // whether this exactly matches the user entry or not. + public final boolean mWillAutoCorrect; public final boolean mIsPunctuationSuggestions; - public final boolean mAllowsToBeAutoCorrected; public final boolean mIsObsoleteSuggestions; public final boolean mIsPrediction; private final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList; public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, final boolean typedWordValid, - final boolean hasAutoCorrectionCandidate, - final boolean allowsToBeAutoCorrected, + final boolean willAutoCorrect, final boolean isPunctuationSuggestions, final boolean isObsoleteSuggestions, final boolean isPrediction) { mSuggestedWordInfoList = suggestedWordInfoList; mTypedWordValid = typedWordValid; - mHasAutoCorrectionCandidate = hasAutoCorrectionCandidate; - mAllowsToBeAutoCorrected = allowsToBeAutoCorrected; + mWillAutoCorrect = willAutoCorrect; mIsPunctuationSuggestions = isPunctuationSuggestions; mIsObsoleteSuggestions = isObsoleteSuggestions; mIsPrediction = isPrediction; @@ -55,7 +55,7 @@ public class SuggestedWords { return mSuggestedWordInfoList.size(); } - public CharSequence getWord(int pos) { + public String getWord(int pos) { return mSuggestedWordInfoList.get(pos).mWord; } @@ -67,12 +67,8 @@ public class SuggestedWords { return mSuggestedWordInfoList.get(pos); } - public boolean hasAutoCorrectionWord() { - return mHasAutoCorrectionCandidate && size() > 1 && !mTypedWordValid; - } - public boolean willAutoCorrect() { - return !mTypedWordValid && mHasAutoCorrectionCandidate; + return mWillAutoCorrect; } @Override @@ -80,8 +76,7 @@ public class SuggestedWords { // Pretty-print method to help debug return "SuggestedWords:" + " mTypedWordValid=" + mTypedWordValid - + " mHasAutoCorrectionCandidate=" + mHasAutoCorrectionCandidate - + " mAllowsToBeAutoCorrected=" + mAllowsToBeAutoCorrected + + " mWillAutoCorrect=" + mWillAutoCorrect + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray()); } @@ -92,7 +87,7 @@ public class SuggestedWords { for (CompletionInfo info : infos) { if (null != info && info.getText() != null) { result.add(new SuggestedWordInfo(info.getText(), SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_APP_DEFINED)); + SuggestedWordInfo.KIND_APP_DEFINED, Dictionary.TYPE_APPLICATION_DEFINED)); } } return result; @@ -105,7 +100,7 @@ public class SuggestedWords { final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<SuggestedWordInfo>(); final HashSet<String> alreadySeen = new HashSet<String>(); suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_TYPED)); + SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED)); alreadySeen.add(typedWord.toString()); final int previousSize = previousSuggestions.size(); for (int pos = 1; pos < previousSize; pos++) { @@ -130,19 +125,20 @@ public class SuggestedWords { public static final int KIND_HARDCODED = 5; // Hardcoded suggestion, e.g. punctuation public static final int KIND_APP_DEFINED = 6; // Suggested by the application public static final int KIND_SHORTCUT = 7; // A shortcut - private final String mWordStr; - public final CharSequence mWord; + public final String mWord; public final int mScore; public final int mKind; // one of the KIND_* constants above public final int mCodePointCount; + public final String mSourceDict; private String mDebugString = ""; - public SuggestedWordInfo(final CharSequence word, final int score, final int kind) { - mWordStr = word.toString(); - mWord = word; + public SuggestedWordInfo(final CharSequence word, final int score, final int kind, + final String sourceDict) { + mWord = word.toString(); mScore = score; mKind = kind; - mCodePointCount = mWordStr.codePointCount(0, mWordStr.length()); + mSourceDict = sourceDict; + mCodePointCount = StringUtils.codePointCount(mWord); } @@ -160,15 +156,15 @@ public class SuggestedWords { } public int codePointAt(int i) { - return mWordStr.codePointAt(i); + return mWord.codePointAt(i); } @Override public String toString() { if (TextUtils.isEmpty(mDebugString)) { - return mWordStr; + return mWord; } else { - return mWordStr + " (" + mDebugString.toString() + ")"; + return mWord + " (" + mDebugString.toString() + ")"; } } @@ -182,7 +178,7 @@ public class SuggestedWords { final SuggestedWordInfo cur = candidates.get(i); for (int j = 0; j < i; ++j) { final SuggestedWordInfo previous = candidates.get(j); - if (TextUtils.equals(cur.mWord, previous.mWord)) { + if (cur.mWord.equals(previous.mWord)) { candidates.remove(cur.mScore < previous.mScore ? i : j); --i; break; diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java index 673b545008..9b20bd6903 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java @@ -19,22 +19,23 @@ package com.android.inputmethod.latin; import android.content.Context; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import java.util.ArrayList; import java.util.Locale; public class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryDictionary { private boolean mClosed; public SynchronouslyLoadedContactsBinaryDictionary(final Context context, final Locale locale) { - super(context, Suggest.DIC_CONTACTS, locale); + super(context, locale); } @Override - public synchronized void getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + public synchronized ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { syncReloadDictionaryIfRequired(); - getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); + return getWordsInner(codes, prevWordForBigrams, proximityInfo); } @Override diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java index 1606a34e07..5b2a6edec3 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java @@ -19,6 +19,9 @@ package com.android.inputmethod.latin; import android.content.Context; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; + +import java.util.ArrayList; public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary { @@ -32,11 +35,10 @@ public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionar } @Override - public synchronized void getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + public synchronized ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { syncReloadDictionaryIfRequired(); - getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); + return getWordsInner(codes, prevWordForBigrams, proximityInfo); } @Override diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java index 5bcdb57b5e..60e6fa1279 100644 --- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java @@ -34,7 +34,10 @@ import java.util.Arrays; */ public class UserBinaryDictionary extends ExpandableBinaryDictionary { - // TODO: use Words.SHORTCUT when it's public in the SDK + // The user dictionary provider uses an empty string to mean "all languages". + private static final String USER_DICTIONARY_ALL_LANGUAGES = ""; + + // TODO: use Words.SHORTCUT when we target JellyBean or above final static String SHORTCUT = "shortcut"; private static final String[] PROJECTION_QUERY; static { @@ -69,9 +72,14 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { public UserBinaryDictionary(final Context context, final String locale, final boolean alsoUseMoreRestrictiveLocales) { - super(context, getFilenameWithLocale(NAME, locale), Suggest.DIC_USER); + super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER); if (null == locale) throw new NullPointerException(); // Catch the error earlier - mLocale = locale; + if (SubtypeLocale.NO_LANGUAGE.equals(locale)) { + // If we don't have a locale, insert into the "all locales" user dictionary. + mLocale = USER_DICTIONARY_ALL_LANGUAGES; + } else { + mLocale = locale; + } mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales; // Perform a managed query. The Activity will handle closing and re-querying the cursor // when needed. diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java index 5095f65822..73fa83f9ad 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java @@ -115,8 +115,7 @@ public class UserHistoryDictionary extends ExpandableDictionary { } public synchronized static UserHistoryDictionary getInstance( - final Context context, final String locale, - final int dictTypeId, final SharedPreferences sp) { + final Context context, final String locale, final SharedPreferences sp) { if (sLangDictCache.containsKey(locale)) { final SoftReference<UserHistoryDictionary> ref = sLangDictCache.get(locale); final UserHistoryDictionary dict = ref == null ? null : ref.get(); @@ -128,14 +127,14 @@ public class UserHistoryDictionary extends ExpandableDictionary { } } final UserHistoryDictionary dict = - new UserHistoryDictionary(context, locale, dictTypeId, sp); + new UserHistoryDictionary(context, locale, sp); sLangDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict)); return dict; } - private UserHistoryDictionary(final Context context, final String locale, final int dicTypeId, - SharedPreferences sp) { - super(context, dicTypeId); + private UserHistoryDictionary(final Context context, final String locale, + final SharedPreferences sp) { + super(context, Dictionary.TYPE_USER_HISTORY); mLocale = locale; mPrefs = sp; if (sOpenHelper == null) { diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index a44b1f9ad7..8f71de0e7a 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -531,14 +531,4 @@ public class Utils { } return builder.toString(); } - - public static void addAllSuggestions(final int dicTypeId, final int dataType, - final ArrayList<SuggestedWords.SuggestedWordInfo> suggestions, - final Dictionary.WordCallback callback) { - for (SuggestedWordInfo suggestion : suggestions) { - final String suggestionStr = suggestion.mWord.toString(); - callback.addWord(suggestionStr.toCharArray(), 0, suggestionStr.length(), - suggestion.mScore, dicTypeId, dataType); - } - } } diff --git a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java index a0de2f9707..3af22140ec 100644 --- a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java +++ b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java @@ -37,7 +37,7 @@ public class WhitelistDictionary extends ExpandableDictionary { // TODO: Conform to the async load contact of ExpandableDictionary public WhitelistDictionary(final Context context, final Locale locale) { - super(context, Suggest.DIC_WHITELIST); + super(context, Dictionary.TYPE_WHITELIST); // TODO: Move whitelist dictionary into main dictionary. final RunInLocale<Void> job = new RunInLocale<Void>() { @Override diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 43b92337af..bf5e05e9ba 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -33,8 +33,7 @@ public class WordComposer { private static final int N = BinaryDictionary.MAX_WORD_LENGTH; private int[] mPrimaryKeyCodes; - private int[] mXCoordinates; - private int[] mYCoordinates; + private final InputPointers mInputPointers = new InputPointers(); private StringBuilder mTypedWord; private CharSequence mAutoCorrection; private boolean mIsResumed; @@ -53,8 +52,6 @@ public class WordComposer { public WordComposer() { mPrimaryKeyCodes = new int[N]; mTypedWord = new StringBuilder(N); - mXCoordinates = new int[N]; - mYCoordinates = new int[N]; mAutoCorrection = null; mTrailingSingleQuotesCount = 0; mIsResumed = false; @@ -68,8 +65,7 @@ public class WordComposer { public void init(WordComposer source) { mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length); mTypedWord = new StringBuilder(source.mTypedWord); - mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length); - mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length); + mInputPointers.copy(source.mInputPointers); mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; @@ -91,7 +87,7 @@ public class WordComposer { refreshSize(); } - public final void refreshSize() { + private final void refreshSize() { mCodePointSize = mTypedWord.codePointCount(0, mTypedWord.length()); } @@ -115,12 +111,8 @@ public class WordComposer { return mPrimaryKeyCodes[index]; } - public int[] getXCoordinates() { - return mXCoordinates; - } - - public int[] getYCoordinates() { - return mYCoordinates; + public InputPointers getInputPointers() { + return mInputPointers; } private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { @@ -138,8 +130,8 @@ public class WordComposer { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { mPrimaryKeyCodes[newIndex] = primaryCode >= Keyboard.CODE_SPACE ? Character.toLowerCase(primaryCode) : primaryCode; - mXCoordinates[newIndex] = keyX; - mYCoordinates[newIndex] = keyY; + // TODO: Set correct pointer id and time + mInputPointers.addPointer(newIndex, keyX, keyY, 0, 0); } mIsFirstCharCapitalized = isFirstCharCapitalized( newIndex, primaryCode, mIsFirstCharCapitalized); @@ -298,14 +290,11 @@ public class WordComposer { // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate // the last composed word to ensure this does not happen. final int[] primaryKeyCodes = mPrimaryKeyCodes; - final int[] xCoordinates = mXCoordinates; - final int[] yCoordinates = mYCoordinates; mPrimaryKeyCodes = new int[N]; - mXCoordinates = new int[N]; - mYCoordinates = new int[N]; final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes, - xCoordinates, yCoordinates, mTypedWord.toString(), committedWord, separatorCode, + mInputPointers, mTypedWord.toString(), committedWord, separatorCode, prevWord); + mInputPointers.reset(); if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD && type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) { lastComposedWord.deactivate(); @@ -319,8 +308,7 @@ public class WordComposer { public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { mPrimaryKeyCodes = lastComposedWord.mPrimaryKeyCodes; - mXCoordinates = lastComposedWord.mXCoordinates; - mYCoordinates = lastComposedWord.mYCoordinates; + mInputPointers.set(lastComposedWord.mInputPointers); mTypedWord.setLength(0); mTypedWord.append(lastComposedWord.mTypedWord); refreshSize(); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 69b48cecc1..5332c066a0 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -32,12 +32,12 @@ import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.ContactsBinaryDictionary; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.Dictionary.WordCallback; import com.android.inputmethod.latin.DictionaryCollection; import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SynchronouslyLoadedContactsBinaryDictionary; import com.android.inputmethod.latin.SynchronouslyLoadedUserBinaryDictionary; import com.android.inputmethod.latin.UserBinaryDictionary; @@ -203,7 +203,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService EMPTY_STRING_ARRAY); } - private static class SuggestionsGatherer implements WordCallback { + // TODO: remove this class and replace it by storage local to the session. + private static class SuggestionsGatherer { public static class Result { public final String[] mSuggestions; public final boolean mHasRecommendedSuggestions; @@ -237,9 +238,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService mScores = new int[mMaxLength]; } - @Override - synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score, - int dicTypeId, int dataType) { + synchronized public boolean addWord(char[] word, int[] spaceIndices, int wordOffset, + int wordLength, int score) { final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score); // binarySearch returns the index if the element exists, and -<insertion index> - 1 // if it doesn't. See documentation for binarySearch. @@ -780,8 +780,13 @@ public class AndroidSpellCheckerService extends SpellCheckerService try { dictInfo = mDictionaryPool.takeOrGetNull(); if (null == dictInfo) return getNotInDictEmptySuggestions(); - dictInfo.mDictionary.getWords(composer, prevWord, suggestionsGatherer, - dictInfo.mProximityInfo); + final ArrayList<SuggestedWordInfo> suggestions = dictInfo.mDictionary.getWords( + composer, prevWord, dictInfo.mProximityInfo); + for (final SuggestedWordInfo suggestion : suggestions) { + final String suggestionStr = suggestion.mWord.toString(); + suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0, + suggestionStr.length(), suggestion.mScore); + } isInDict = dictInfo.mDictionary.isValidWord(text); if (!isInDict && CAPITALIZE_NONE != capitalizeType) { // We want to test the word again if it's all caps or first caps only. diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java index e86390b11d..642a551cee 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java @@ -57,11 +57,11 @@ import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.MoreKeysPanel; import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.keyboard.ViewLayoutUtils; +import com.android.inputmethod.latin.AutoCorrection; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResearchLogger; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; -import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.define.ProductionFlag; @@ -336,8 +336,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, if (LatinImeLogger.sDBG && suggestedWords.size() > 1) { // If we auto-correct, then the autocorrection is in slot 0 and the typed word // is in slot 1. - if (index == mCenterSuggestionIndex && suggestedWords.mHasAutoCorrectionCandidate - && Suggest.shouldBlockAutoCorrectionBySafetyNet( + if (index == mCenterSuggestionIndex + && AutoCorrection.shouldBlockAutoCorrectionBySafetyNet( suggestedWords.getWord(1).toString(), suggestedWords.getWord(0))) { return 0xFFFF0000; } diff --git a/native/jni/Android.mk b/native/jni/Android.mk index 14b1e6454e..d40063ed5a 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -17,15 +17,16 @@ LOCAL_PATH := $(call my-dir) ############ some local flags # If you change any of those flags, you need to rebuild both libjni_latinime_static # and the shared library. -#FLAG_DBG := true +FLAG_DBG ?= false FLAG_DO_PROFILE ?= false ###################################### include $(CLEAR_VARS) LATIN_IME_SRC_DIR := src +LATIN_IME_SRC_FULLPATH_DIR := $(LOCAL_PATH)/$(LATIN_IME_SRC_DIR) -LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(LATIN_IME_SRC_DIR) +LOCAL_C_INCLUDES += $(LATIN_IME_SRC_FULLPATH_DIR) $(LATIN_IME_SRC_FULLPATH_DIR)/gesture LOCAL_CFLAGS += -Werror -Wall @@ -47,11 +48,12 @@ LATIN_IME_CORE_SRC_FILES := \ dictionary.cpp \ proximity_info.cpp \ proximity_info_state.cpp \ - unigram_dictionary.cpp + unigram_dictionary.cpp \ + gesture/gesture_decoder_wrapper.cpp LOCAL_SRC_FILES := \ $(LATIN_IME_JNI_SRC_FILES) \ - $(addprefix $(LATIN_IME_SRC_DIR)/,$(LATIN_IME_CORE_SRC_FILES)) + $(addprefix $(LATIN_IME_SRC_DIR)/, $(LATIN_IME_CORE_SRC_FILES)) ifeq ($(FLAG_DO_PROFILE), true) $(warning Making profiling version of native library) @@ -73,12 +75,11 @@ LOCAL_C_INCLUDES += external/stlport/stlport bionic endif include $(BUILD_STATIC_LIBRARY) - ###################################### include $(CLEAR_VARS) # All code in LOCAL_WHOLE_STATIC_LIBRARIES will be built into this shared library. -LOCAL_WHOLE_STATIC_LIBRARIES := libjni_latinime_static +LOCAL_WHOLE_STATIC_LIBRARIES := libjni_latinime_common_static ifdef HISTORICAL_NDK_VERSIONS_ROOT # In the platform build system LOCAL_SHARED_LIBRARIES := libstlport @@ -108,5 +109,6 @@ include $(BUILD_SHARED_LIBRARY) #################### Clean up the tmp vars LATIN_IME_CORE_SRC_FILES := LATIN_IME_JNI_SRC_FILES := +LATIN_IME_GESTURE_IMPL_SRC_FILES := LATIN_IME_SRC_DIR := -TARGETING_UNBUNDLED_FROYO := +LATIN_IME_SRC_FULLPATH_DIR := diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index d10dc962e5..bee0662eeb 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -128,28 +128,37 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object, static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict, jlong proximityInfo, jintArray xCoordinatesArray, jintArray yCoordinatesArray, - jintArray inputArray, jint arraySize, jintArray prevWordForBigrams, - jboolean useFullEditDistance, jcharArray outputArray, jintArray frequencyArray) { - Dictionary *dictionary = (Dictionary*)dict; + jintArray timesArray, jintArray pointerIdArray, jintArray inputArray, jint arraySize, + jint commitPoint, jboolean isGesture, + jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray, + jintArray frequencyArray, jintArray spaceIndexArray) { + Dictionary *dictionary = (Dictionary*) dict; if (!dictionary) return 0; ProximityInfo *pInfo = (ProximityInfo*)proximityInfo; int *xCoordinates = env->GetIntArrayElements(xCoordinatesArray, 0); int *yCoordinates = env->GetIntArrayElements(yCoordinatesArray, 0); + int *times = env->GetIntArrayElements(timesArray, 0); + int *pointerIds = env->GetIntArrayElements(pointerIdArray, 0); int *frequencies = env->GetIntArrayElements(frequencyArray, 0); int *inputCodes = env->GetIntArrayElements(inputArray, 0); jchar *outputChars = env->GetCharArrayElements(outputArray, 0); + int *spaceIndices = env->GetIntArrayElements(spaceIndexArray, 0); jint *prevWordChars = prevWordForBigrams ? env->GetIntArrayElements(prevWordForBigrams, 0) : 0; jsize prevWordLength = prevWordChars ? env->GetArrayLength(prevWordForBigrams) : 0; - int count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, inputCodes, - arraySize, prevWordChars, prevWordLength, useFullEditDistance, - (unsigned short*) outputChars, frequencies); + int count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, times, pointerIds, + inputCodes, arraySize, prevWordChars, prevWordLength, commitPoint, isGesture, + useFullEditDistance, (unsigned short*) outputChars, + frequencies, spaceIndices); if (prevWordChars) { env->ReleaseIntArrayElements(prevWordForBigrams, prevWordChars, JNI_ABORT); } + env->ReleaseIntArrayElements(spaceIndexArray, spaceIndices, 0); env->ReleaseCharArrayElements(outputArray, outputChars, 0); env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT); env->ReleaseIntArrayElements(frequencyArray, frequencies, 0); + env->ReleaseIntArrayElements(pointerIdArray, pointerIds, 0); + env->ReleaseIntArrayElements(timesArray, times, 0); env->ReleaseIntArrayElements(yCoordinatesArray, yCoordinates, 0); env->ReleaseIntArrayElements(xCoordinatesArray, xCoordinates, 0); return count; @@ -251,8 +260,8 @@ void releaseDictBuf(void* dictBuf, const size_t length, int fd) { static JNINativeMethod sMethods[] = { {"openNative", "(Ljava/lang/String;JJIIII)J", (void*)latinime_BinaryDictionary_open}, {"closeNative", "(J)V", (void*)latinime_BinaryDictionary_close}, - {"getSuggestionsNative", "(JJ[I[I[II[IZ[C[I)I", - (void*)latinime_BinaryDictionary_getSuggestions}, + {"getSuggestionsNative", "(JJ[I[I[I[I[IIIZ[IZ[C[I[I)I", + (void*) latinime_BinaryDictionary_getSuggestions}, {"getFrequencyNative", "(J[II)I", (void*)latinime_BinaryDictionary_getFrequency}, {"isValidBigramNative", "(J[I[I)Z", (void*)latinime_BinaryDictionary_isValidBigram}, {"getBigramsNative", "(J[II[II[C[III)I", (void*)latinime_BinaryDictionary_getBigrams}, diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index 8bcadcbe9d..c7d3bf3136 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -255,6 +255,8 @@ static inline void prof_out(void) { #define FIRST_WORD_INDEX 0 +#define MAX_SPACES_INTERNAL 16 + // TODO: Reduce this constant if possible; check the maximum number of digraphs in the same // word in the dictionary for languages with digraphs, like German and French #define DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH 5 diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp index 83bb267311..628a169330 100644 --- a/native/jni/src/dictionary.cpp +++ b/native/jni/src/dictionary.cpp @@ -22,6 +22,7 @@ #include "binary_format.h" #include "defines.h" #include "dictionary.h" +#include "gesture_decoder_wrapper.h" namespace latinime { @@ -43,11 +44,15 @@ Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, mUnigramDictionary = new UnigramDictionary(mDict + headerSize, typedLetterMultiplier, fullWordMultiplier, maxWordLength, maxWords, options); mBigramDictionary = new BigramDictionary(mDict + headerSize, maxWordLength); + mGestureDecoder = new GestureDecoderWrapper(maxWordLength, maxWords); + mGestureDecoder->setDict(mUnigramDictionary, mBigramDictionary, + mDict + headerSize /* dict root */, 0 /* root pos */); } Dictionary::~Dictionary() { delete mUnigramDictionary; delete mBigramDictionary; + delete mGestureDecoder; } int Dictionary::getFrequency(const int32_t *word, int length) const { diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h index fd69f79e36..431f10337f 100644 --- a/native/jni/src/dictionary.h +++ b/native/jni/src/dictionary.h @@ -22,6 +22,7 @@ #include "bigram_dictionary.h" #include "char_utils.h" #include "defines.h" +#include "incremental_decoder_interface.h" #include "proximity_info.h" #include "unigram_dictionary.h" #include "words_priority_queue_pool.h" @@ -34,15 +35,27 @@ class Dictionary { int fullWordMultiplier, int maxWordLength, int maxWords); int getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates, - int *codes, int codesSize, const int32_t* prevWordChars, const int prevWordLength, - bool useFullEditDistance, unsigned short *outWords, int *frequencies) const { - std::map<int, int> bigramMap; - uint8_t bigramFilter[BIGRAM_FILTER_BYTE_SIZE]; - mBigramDictionary->fillBigramAddressToFrequencyMapAndFilter(prevWordChars, - prevWordLength, &bigramMap, bigramFilter); - return mUnigramDictionary->getSuggestions(proximityInfo, - xcoordinates, ycoordinates, codes, codesSize, &bigramMap, - bigramFilter, useFullEditDistance, outWords, frequencies); + int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars, + int prevWordLength, int commitPoint, bool isGesture, + bool useFullEditDistance, unsigned short *outWords, + int *frequencies, int *spaceIndices) { + int result = 0; + if (isGesture) { + mGestureDecoder->setPrevWord(prevWordChars, prevWordLength); + result = mGestureDecoder->getSuggestions(proximityInfo, xcoordinates, ycoordinates, + times, pointerIds, codes, codesSize, commitPoint, + outWords, frequencies, spaceIndices); + return result; + } else { + std::map<int, int> bigramMap; + uint8_t bigramFilter[BIGRAM_FILTER_BYTE_SIZE]; + mBigramDictionary->fillBigramAddressToFrequencyMapAndFilter(prevWordChars, + prevWordLength, &bigramMap, bigramFilter); + result = mUnigramDictionary->getSuggestions(proximityInfo, xcoordinates, + ycoordinates, codes, codesSize, &bigramMap, bigramFilter, + useFullEditDistance, outWords, frequencies); + return result; + } } int getBigrams(const int32_t *word, int length, int *codes, int codesSize, @@ -75,6 +88,7 @@ class Dictionary { const UnigramDictionary *mUnigramDictionary; const BigramDictionary *mBigramDictionary; + IncrementalDecoderInterface *mGestureDecoder; }; // public static utility methods diff --git a/native/jni/src/gesture/gesture_decoder_wrapper.cpp b/native/jni/src/gesture/gesture_decoder_wrapper.cpp new file mode 100644 index 0000000000..afbe0c5c3e --- /dev/null +++ b/native/jni/src/gesture/gesture_decoder_wrapper.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gesture_decoder_wrapper.h" + +namespace latinime { + IncrementalDecoderInterface * + (*GestureDecoderWrapper::sGestureDecoderFactoryMethod)(int, int) = 0; +} // namespace latinime diff --git a/native/jni/src/gesture/gesture_decoder_wrapper.h b/native/jni/src/gesture/gesture_decoder_wrapper.h new file mode 100644 index 0000000000..35982f03d8 --- /dev/null +++ b/native/jni/src/gesture/gesture_decoder_wrapper.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_GESTURE_DECODER_WRAPPER_H +#define LATINIME_GESTURE_DECODER_WRAPPER_H + +#include <stdint.h> +#include "defines.h" +#include "incremental_decoder_interface.h" + +namespace latinime { + +class UnigramDictionary; +class BigramDictionary; +class ProximityInfo; + +class GestureDecoderWrapper : public IncrementalDecoderInterface { + public: + GestureDecoderWrapper(const int maxWordLength, const int maxWords) { + mIncrementalDecoderInterface = getGestureDecoderInstance(maxWordLength, maxWords); + } + + virtual ~GestureDecoderWrapper() { + delete mIncrementalDecoderInterface; + } + + int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times, + int *pointerIds, int *codes, int inputSize, int commitPoint, + unsigned short *outWords, int *frequencies, int *outputIndices) { + if (!mIncrementalDecoderInterface) { + return 0; + } + return mIncrementalDecoderInterface->getSuggestions( + pInfo, inputXs, inputYs, times, pointerIds, codes, inputSize, commitPoint, + outWords, frequencies, outputIndices); + } + + void reset() { + if (!mIncrementalDecoderInterface) { + return; + } + mIncrementalDecoderInterface->reset(); + } + + void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram, + const uint8_t *dictRoot, int rootPos) { + if (!mIncrementalDecoderInterface) { + return; + } + mIncrementalDecoderInterface->setDict(dict, bigram, dictRoot, rootPos); + } + + void setPrevWord(const int32_t *prevWord, int prevWordLength) { + if (!mIncrementalDecoderInterface) { + return; + } + mIncrementalDecoderInterface->setPrevWord(prevWord, prevWordLength); + } + + static void setGestureDecoderFactoryMethod( + IncrementalDecoderInterface *(*factoryMethod)(int, int)) { + sGestureDecoderFactoryMethod = factoryMethod; + } + + private: + DISALLOW_COPY_AND_ASSIGN(GestureDecoderWrapper); + static IncrementalDecoderInterface *getGestureDecoderInstance(int maxWordLength, int maxWords) { + if (sGestureDecoderFactoryMethod) { + return sGestureDecoderFactoryMethod(maxWordLength, maxWords); + } + return 0; + } + + static IncrementalDecoderInterface *(*sGestureDecoderFactoryMethod)(int, int); + IncrementalDecoderInterface *mIncrementalDecoderInterface; +}; +} // namespace latinime +#endif // LATINIME_GESTURE_DECODER_WRAPPER_H diff --git a/native/jni/src/gesture/incremental_decoder_interface.h b/native/jni/src/gesture/incremental_decoder_interface.h new file mode 100644 index 0000000000..957f1ebbe5 --- /dev/null +++ b/native/jni/src/gesture/incremental_decoder_interface.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_INCREMENTAL_DECODER_INTERFACE_H +#define LATINIME_INCREMENTAL_DECODER_INTERFACE_H + +#include <stdint.h> +#include "defines.h" + +namespace latinime { + +class UnigramDictionary; +class BigramDictionary; +class ProximityInfo; + +class IncrementalDecoderInterface { + public: + virtual int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times, + int *pointerIds, int *codes, int inputSize, int commitPoint, + unsigned short *outWords, int *frequencies, int *outputIndices) = 0; + virtual void reset() = 0; + virtual void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram, + const uint8_t *dictRoot, int rootPos) = 0; + virtual void setPrevWord(const int32_t *prevWord, int prevWordLength) = 0; + virtual ~IncrementalDecoderInterface() { }; +}; +} // namespace latinime +#endif // LATINIME_INCREMENTAL_DECODER_INTERFACE_H diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp index 2ba244a7c9..a4a641160b 100644 --- a/native/jni/src/proximity_info.cpp +++ b/native/jni/src/proximity_info.cpp @@ -15,6 +15,7 @@ */ #include <assert.h> +#include <math.h> #include <stdio.h> #include <string> @@ -210,4 +211,25 @@ int ProximityInfo::getKeyIndex(const int c) const { } return mCodeToKeyIndex[baseLowerC]; } + +// TODO: [Staging] Optimize +void ProximityInfo::getCenters(int *centerXs, int *centerYs, int *codeToKeyIndex, + int *keyToCodeIndex, int *keyCount, int *keyWidth) const { + *keyCount = KEY_COUNT; + *keyWidth = sqrt((float)MOST_COMMON_KEY_WIDTH_SQUARE); + + for (int i = 0; i < KEY_COUNT; ++i) { + const int code = mKeyCharCodes[i]; + const int lowerCode = toBaseLowerCase(code); + centerXs[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2; + centerYs[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2; + codeToKeyIndex[code] = i; + if (code != lowerCode && lowerCode >= 0 && lowerCode <= MAX_CHAR_CODE) { + codeToKeyIndex[lowerCode] = i; + keyToCodeIndex[i] = lowerCode; + } else { + keyToCodeIndex[i] = code; + } + } +} } // namespace latinime diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h index fec6555ea5..d58935c6b0 100644 --- a/native/jni/src/proximity_info.h +++ b/native/jni/src/proximity_info.h @@ -98,6 +98,10 @@ class ProximityInfo { return GRID_HEIGHT; } + // Returns the keyboard key-center information. + void getCenters(int *centersX, int *centersY, int *codeToKeyIndex, int *keyToCodeIndex, + int *keyCount, int *keyWidth) const; + private: DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfo); // The max number of the keys in one keyboard layout -- GitLab