diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
7 files changed, 110 insertions, 62 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index c43683f2d..92019c0ed 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -17,10 +17,14 @@ package com.android.inputmethod.latin; import android.content.Context; +import android.content.res.AssetFileDescriptor; +import android.content.res.Resources; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.LocaleUtils.RunInLocale; import java.util.Arrays; +import java.util.Locale; /** * Implements a static, compacted, binary dictionary of standard words. @@ -94,14 +98,23 @@ public class BinaryDictionary extends Dictionary { * @param flagArray the flags to limit the dictionary to, or null for default. */ public BinaryDictionary(final Context context, - final String filename, final long offset, final long length, Flag[] flagArray) { + final String filename, final long offset, final long length, final Flag[] flagArray, + 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; // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter - mFlags = Flag.initFlags(null == flagArray ? ALL_CONFIG_FLAGS : flagArray, context, - SubtypeSwitcher.getInstance()); + final RunInLocale<Void> job = new RunInLocale<Void>() { + @Override + protected Void job(Resources res) { + // TODO: remove this when all flags are moved to the native code + mFlags = Flag.initFlags(null == flagArray ? ALL_CONFIG_FLAGS : flagArray, context, + SubtypeSwitcher.getInstance()); + return null; + } + }; + job.runInLocale(context.getResources(), locale); loadDictionary(filename, offset, length); } diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 7be374db5..7a59d80f1 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -59,7 +59,8 @@ public class DictionaryFactory { if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = - new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, flagArray); + new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, flagArray, + locale); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); } @@ -119,7 +120,7 @@ public class DictionaryFactory { return null; } return new BinaryDictionary(context, - sourceDir, afd.getStartOffset(), afd.getLength(), null); + sourceDir, afd.getStartOffset(), afd.getLength(), null, locale); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource. resId=" + resId); return null; @@ -147,7 +148,7 @@ public class DictionaryFactory { long startOffset, long length, Flag[] flagArray) { if (dictionary.isFile()) { return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length, - flagArray); + flagArray, null); } else { Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath()); return null; diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java index 7b34cae63..7000e4633 100644 --- a/java/src/com/android/inputmethod/latin/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -22,7 +22,6 @@ import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Keyboard; import java.util.ArrayList; -import java.util.Locale; public class StringUtils { private StringUtils() { @@ -150,41 +149,4 @@ public class StringUtils { i++; } } - - public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { - if (returnsNameInThisLocale) { - return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); - } else { - return toTitleCase(locale.getDisplayName(), locale); - } - } - - public static String getDisplayLanguage(Locale locale) { - return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); - } - - public static String getMiddleDisplayLanguage(Locale locale) { - return toTitleCase((LocaleUtils.constructLocaleFromString( - locale.getLanguage()).getDisplayLanguage(locale)), locale); - } - - public static String getShortDisplayLanguage(Locale locale) { - return toTitleCase(locale.getLanguage(), locale); - } - - public static String toTitleCase(String s, Locale locale) { - if (s.length() <= 1) { - // TODO: is this really correct? Shouldn't this be s.toUpperCase()? - return s; - } - // TODO: fix the bugs below - // - This does not work for Greek, because it returns upper case instead of title case. - // - It does not work for Serbian, because it fails to account for the "lj" character, - // which should be "Lj" in title case and "LJ" in upper case. - // - It does not work for Dutch, because it fails to account for the "ij" digraph, which - // are two different characters but both should be capitalized as "IJ" as if they were - // a single letter. - // - It also does not work with unicode surrogate code points. - return s.toUpperCase(locale).charAt(0) + s.substring(1); - } } diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index 66c13bd2e..ba67f3358 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -22,6 +22,13 @@ import android.content.res.Resources; import java.util.Locale; public class SubtypeLocale { + // Special language code to represent "no language". + public static final String NO_LANGUAGE = "zz"; + // Special country code to represent "QWERTY". + /* package for test */ static final String QWERTY = "QY"; + + public static final Locale LOCALE_NO_LANGUAGE_QWERTY = new Locale(NO_LANGUAGE, QWERTY); + private static String[] sExceptionKeys; private static String[] sExceptionValues; @@ -35,18 +42,82 @@ public class SubtypeLocale { sExceptionValues = res.getStringArray(R.array.subtype_locale_exception_values); } - public static String getFullDisplayName(Locale locale) { - final String localeCode = locale.toString(); + private static String lookupExceptionalLocale(String key) { for (int index = 0; index < sExceptionKeys.length; index++) { - if (sExceptionKeys[index].equals(localeCode)) { - final String value = sExceptionValues[index]; - if (value.indexOf("%s") >= 0) { - final String languageName = locale.getDisplayLanguage(locale); - return String.format(value, languageName); - } - return value; + if (sExceptionKeys[index].equals(key)) { + return sExceptionValues[index]; } } - return locale.getDisplayName(locale); + return null; + } + + // Get Locale's full display name in its locale. + // For example: + // "fr_CH" is converted to "Français (Suisse)". + // "de_QY" is converted to "Deutsche (QWERTY)". (Any locale that has country code "QY") + // "zz_QY" is converted to "QWERTY". (The language code "zz" means "No language", thus just + // ends up with the keyboard layout name.) + public static String getFullDisplayName(Locale locale) { + final String key; + if (locale.getLanguage().equals(NO_LANGUAGE)) { + key = locale.getCountry(); + } else if (locale.getCountry().equals(QWERTY)) { + key = "*_" + QWERTY; + } else { + key = locale.toString(); + } + final String value = lookupExceptionalLocale(key); + if (value == null) { + return toTitleCase(locale.getDisplayName(locale), locale); + } + if (value.indexOf("%s") >= 0) { + final String languageName = toTitleCase(locale.getDisplayLanguage(locale), locale); + return String.format(value, languageName); + } + return value; + } + + // Get Locale's middle display name in its locale. + // For example: + // "fr_CH" is converted to "Français". + // "de_QY" is converted to "Deutsche". (Any locale that has country code "QY") + // "zz_QY" is converted to "QWERTY". (The language code "zz" means "No language", thus just + // ends up with the keyboard layout name.) + public static String getMiddleDisplayName(Locale locale) { + if (NO_LANGUAGE.equals(locale.getLanguage())) { + return lookupExceptionalLocale(locale.getCountry()); + } else { + return toTitleCase(locale.getDisplayLanguage(locale), locale); + } + } + + // Get Locale's short display name in its locale. + // For example: + // "fr_CH" is converted to "Fr". + // "de_QY" is converted to "De". (Any locale that has country code "QY") + // "zz_QY" is converter to "QY". (The language code "zz" means "No language", thus just ends + // up with the keyboard layout name.) + public static String getShortDisplayName(Locale locale) { + if (NO_LANGUAGE.equals(locale.getLanguage())) { + return locale.getCountry(); + } else { + return toTitleCase(locale.getLanguage(), locale); + } + } + + public static String toTitleCase(String s, Locale locale) { + if (s.length() <= 1) { + // TODO: is this really correct? Shouldn't this be s.toUpperCase()? + return s; + } + // TODO: fix the bugs below + // - This does not work for Greek, because it returns upper case instead of title case. + // - It does not work for Serbian, because it fails to account for the "lj" character, + // which should be "Lj" in title case and "LJ" in upper case. + // - It does not work for Dutch, because it fails to account for the "ij" digraph, which + // are two different characters but both should be capitalized as "IJ" as if they were + // a single letter. + // - It also does not work with unicode surrogate code points. + return s.toUpperCase(locale).charAt(0) + s.substring(1); } } diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index e35364420..7541bd31b 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -375,6 +375,9 @@ public class SubtypeSwitcher { } public boolean needsToDisplayLanguage(Locale keyboardLocale) { + if (keyboardLocale.equals(SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY)) { + return true; + } if (!keyboardLocale.equals(mInputLocale)) { return false; } @@ -420,10 +423,6 @@ public class SubtypeSwitcher { return KEYBOARD_MODE.equals(getCurrentSubtypeMode()); } - public String getInputLanguageName() { - return StringUtils.getDisplayLanguage(getInputLocale()); - } - ///////////////////////////// // Other utility functions // ///////////////////////////// diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 0c0ce182f..91110d888 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -87,8 +87,9 @@ public class SuggestedWords { final CompletionInfo[] infos) { final ArrayList<SuggestedWordInfo> result = new ArrayList<SuggestedWordInfo>(); for (CompletionInfo info : infos) { - if (null != info) result.add(new SuggestedWordInfo(info.getText(), - SuggestedWordInfo.MAX_SCORE)); + if (null != info && info.getText() != null) { + result.add(new SuggestedWordInfo(info.getText(), SuggestedWordInfo.MAX_SCORE)); + } } return result; } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 7b13e40c2..cd01bb146 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -37,6 +37,7 @@ import com.android.inputmethod.latin.Flag; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; +import com.android.inputmethod.latin.SubtypeLocale; import com.android.inputmethod.latin.SynchronouslyLoadedContactsDictionary; import com.android.inputmethod.latin.SynchronouslyLoadedUserDictionary; import com.android.inputmethod.latin.WhitelistDictionary; @@ -325,8 +326,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService } else if (CAPITALIZE_FIRST == capitalizeType) { for (int i = 0; i < mSuggestions.size(); ++i) { // Likewise - mSuggestions.set(i, StringUtils.toTitleCase(mSuggestions.get(i).toString(), - locale)); + mSuggestions.set(i, SubtypeLocale.toTitleCase( + mSuggestions.get(i).toString(), locale)); } } // This returns a String[], while toArray() returns an Object[] which cannot be cast |