diff options
Diffstat (limited to 'src/com/android/settings/inputmethod')
3 files changed, 238 insertions, 149 deletions
diff --git a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java index 620bc65281..716226db4c 100644 --- a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java +++ b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java @@ -60,8 +60,8 @@ public class UserDictionaryAddWordContents { private String mSavedShortcut; /* package */ UserDictionaryAddWordContents(final View view, final Bundle args) { - mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text); - mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut); + mWordEditText = (EditText) view.findViewById(R.id.user_dictionary_add_word_text); + mShortcutEditText = (EditText) view.findViewById(R.id.user_dictionary_add_shortcut); final String word = args.getString(EXTRA_WORD); if (null != word) { mWordEditText.setText(word); @@ -81,8 +81,8 @@ public class UserDictionaryAddWordContents { /* package */ UserDictionaryAddWordContents(final View view, final UserDictionaryAddWordContents oldInstanceToBeEdited) { - mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text); - mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut); + mWordEditText = (EditText) view.findViewById(R.id.user_dictionary_add_word_text); + mShortcutEditText = (EditText) view.findViewById(R.id.user_dictionary_add_shortcut); mMode = MODE_EDIT; mOldWord = oldInstanceToBeEdited.mSavedWord; mOldShortcut = oldInstanceToBeEdited.mSavedShortcut; @@ -167,23 +167,24 @@ public class UserDictionaryAddWordContents { return UserDictionaryAddWordActivity.CODE_WORD_ADDED; } - private static final String[] HAS_WORD_PROJECTION = { UserDictionary.Words.WORD }; + private static final String[] HAS_WORD_PROJECTION = {UserDictionary.Words.WORD}; private static final String HAS_WORD_SELECTION_ONE_LOCALE = UserDictionary.Words.WORD + "=? AND " + UserDictionary.Words.LOCALE + "=?"; private static final String HAS_WORD_SELECTION_ALL_LOCALES = UserDictionary.Words.WORD + "=? AND " + UserDictionary.Words.LOCALE + " is null"; + private boolean hasWord(final String word, final Context context) { final Cursor cursor; // mLocale == "" indicates this is an entry for all languages. Here, mLocale can't // be null at all (it's ensured by the updateLocale method). if ("".equals(mLocale)) { cursor = context.getContentResolver().query(UserDictionary.Words.CONTENT_URI, - HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ALL_LOCALES, - new String[] { word }, null /* sort order */); + HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ALL_LOCALES, + new String[] {word}, null /* sort order */); } else { cursor = context.getContentResolver().query(UserDictionary.Words.CONTENT_URI, - HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ONE_LOCALE, - new String[] { word, mLocale }, null /* sort order */); + HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ONE_LOCALE, + new String[] {word, mLocale}, null /* sort order */); } try { if (null == cursor) return false; @@ -196,6 +197,7 @@ public class UserDictionaryAddWordContents { public static class LocaleRenderer { private final String mLocaleString; private final String mDescription; + // LocaleString may NOT be null. public LocaleRenderer(final Context context, final String localeString) { mLocaleString = localeString; @@ -207,13 +209,16 @@ public class UserDictionaryAddWordContents { mDescription = Utils.createLocaleFromString(localeString).getDisplayName(); } } + @Override public String toString() { return mDescription; } + public String getLocaleString() { return mLocaleString; } + // "More languages..." is null ; "All languages" is the empty string. public boolean isMoreLanguages() { return null == mLocaleString; @@ -229,7 +234,8 @@ public class UserDictionaryAddWordContents { // Helper method to get the list of locales to display for this word public ArrayList<LocaleRenderer> getLocalesList(final Activity activity) { - final TreeSet<String> locales = UserDictionaryList.getUserDictionaryLocalesSet(activity); + final TreeSet<String> locales = + UserDictionaryListPreferenceController.getUserDictionaryLocalesSet(activity); // Remove our locale if it's in, because we're always gonna put it at the top locales.remove(mLocale); // mLocale may not be null final String systemLocale = Locale.getDefault().toString(); diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java index 2f59dc90da..46723bc461 100644 --- a/src/com/android/settings/inputmethod/UserDictionaryList.java +++ b/src/com/android/settings/inputmethod/UserDictionaryList.java @@ -16,33 +16,17 @@ package com.android.settings.inputmethod; -import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.database.Cursor; import android.os.Bundle; -import android.provider.UserDictionary; -import android.support.annotation.NonNull; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceGroup; -import android.text.TextUtils; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.InputMethodSubtype; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.Utils; +import com.android.settings.dashboard.DashboardFragment; -import java.util.List; -import java.util.Locale; -import java.util.TreeSet; +public class UserDictionaryList extends DashboardFragment { -public class UserDictionaryList extends SettingsPreferenceFragment { - public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION = - "android.settings.USER_DICTIONARY_SETTINGS"; - private String mLocale; + private static final String TAG = "UserDictionaryList"; @Override public int getMetricsCategory() { @@ -50,15 +34,8 @@ public class UserDictionaryList extends SettingsPreferenceFragment { } @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity())); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getActivity().getActionBar().setTitle(R.string.user_dict_settings_title); + public void onAttach(Context context) { + super.onAttach(context); final Intent intent = getActivity().getIntent(); final String localeFromIntent = @@ -76,122 +53,17 @@ public class UserDictionaryList extends SettingsPreferenceFragment { } else { locale = null; } - mLocale = locale; - } - - @NonNull - public static TreeSet<String> getUserDictionaryLocalesSet(Context context) { - final Cursor cursor = context.getContentResolver().query( - UserDictionary.Words.CONTENT_URI, new String[]{UserDictionary.Words.LOCALE}, - null, null, null); - final TreeSet<String> localeSet = new TreeSet<>(); - if (cursor == null) { - // The user dictionary service is not present or disabled. Return empty set. - return localeSet; - } - try { - if (cursor.moveToFirst()) { - final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE); - do { - final String locale = cursor.getString(columnIndex); - localeSet.add(null != locale ? locale : ""); - } while (cursor.moveToNext()); - } - } finally { - cursor.close(); - } - - // CAVEAT: Keep this for consistency of the implementation between Keyboard and Settings - // if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { - // // For ICS, we need to show "For all languages" in case that the keyboard locale - // // is different from the system locale - // localeSet.add(""); - // } - - final InputMethodManager imm = - (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - final List<InputMethodInfo> imis = imm.getEnabledInputMethodList(); - for (final InputMethodInfo imi : imis) { - final List<InputMethodSubtype> subtypes = - imm.getEnabledInputMethodSubtypeList( - imi, true /* allowsImplicitlySelectedSubtypes */); - for (InputMethodSubtype subtype : subtypes) { - final String locale = subtype.getLocale(); - if (!TextUtils.isEmpty(locale)) { - localeSet.add(locale); - } - } - } - - // We come here after we have collected locales from existing user dictionary entries and - // enabled subtypes. If we already have the locale-without-country version of the system - // locale, we don't add the system locale to avoid confusion even though it's technically - // correct to add it. - if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) { - localeSet.add(Locale.getDefault().toString()); - } - return localeSet; + use(UserDictionaryListPreferenceController.class).setLocale(locale); } - /** - * Creates the entries that allow the user to go into the user dictionary for each locale. - * - * @param userDictGroup The group to put the settings in. - */ - protected void createUserDictSettings(PreferenceGroup userDictGroup) { - final Activity activity = getActivity(); - userDictGroup.removeAll(); - final TreeSet<String> localeSet = - UserDictionaryList.getUserDictionaryLocalesSet(activity); - if (mLocale != null) { - // If the caller explicitly specify empty string as a locale, we'll show "all languages" - // in the list. - localeSet.add(mLocale); - } - if (localeSet.size() > 1) { - // Have an "All languages" entry in the languages list if there are two or more active - // languages - localeSet.add(""); - } - - if (localeSet.isEmpty()) { - userDictGroup.addPreference(createUserDictionaryPreference(null, activity)); - } else { - for (String locale : localeSet) { - userDictGroup.addPreference(createUserDictionaryPreference(locale, activity)); - } - } - } - - /** - * Create a single User Dictionary Preference object, with its parameters set. - * - * @param locale The locale for which this user dictionary is for. - * @return The corresponding preference. - */ - protected Preference createUserDictionaryPreference(String locale, Activity activity) { - final Preference newPref = new Preference(getPrefContext()); - final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION); - if (null == locale) { - newPref.setTitle(Locale.getDefault().getDisplayName()); - } else { - if ("".equals(locale)) { - newPref.setTitle(getString(R.string.user_dict_settings_all_languages)); - } else { - newPref.setTitle(Utils.createLocaleFromString(locale).getDisplayName()); - } - intent.putExtra("locale", locale); - newPref.getExtras().putString("locale", locale); - } - newPref.setIntent(intent); - newPref.setFragment(UserDictionarySettings.class.getName()); - return newPref; + @Override + protected int getPreferenceScreenResId() { + return R.xml.user_dictionary_list_fragment; } @Override - public void onResume() { - super.onResume(); - createUserDictSettings(getPreferenceScreen()); + protected String getLogTag() { + return TAG; } } diff --git a/src/com/android/settings/inputmethod/UserDictionaryListPreferenceController.java b/src/com/android/settings/inputmethod/UserDictionaryListPreferenceController.java new file mode 100644 index 0000000000..715246aa17 --- /dev/null +++ b/src/com/android/settings/inputmethod/UserDictionaryListPreferenceController.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 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.settings.inputmethod; + +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.provider.UserDictionary; +import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.text.TextUtils; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; + +import java.util.List; +import java.util.Locale; +import java.util.TreeSet; + +public class UserDictionaryListPreferenceController extends BasePreferenceController implements + LifecycleObserver, OnStart { + + public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION = + "android.settings.USER_DICTIONARY_SETTINGS"; + private final String KEY_ALL_LANGUAGE = "all_languages"; + private String mLocale; + private PreferenceScreen mScreen; + + public UserDictionaryListPreferenceController(Context context, String key) { + super(context, key); + } + + public void setLocale(String locale) { + mLocale = locale; + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + // This is to make newly inserted languages being sorted alphabetically when updating + // the existing preferenceScreen, and for "For all languages" to be always on the top. + screen.setOrderingAsAdded(false); + mScreen = screen; + } + + @Override + public void onStart() { + createUserDictSettings(); + } + + @NonNull + public static TreeSet<String> getUserDictionaryLocalesSet(Context context) { + final Cursor cursor = context.getContentResolver().query( + UserDictionary.Words.CONTENT_URI, new String[] {UserDictionary.Words.LOCALE}, + null, null, null); + final TreeSet<String> localeSet = new TreeSet<>(); + if (cursor == null) { + // The user dictionary service is not present or disabled. Return empty set. + return localeSet; + } + try { + if (cursor.moveToFirst()) { + final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE); + do { + final String locale = cursor.getString(columnIndex); + localeSet.add(null != locale ? locale : ""); + } while (cursor.moveToNext()); + } + } finally { + cursor.close(); + } + + // CAVEAT: Keep this for consistency of the implementation between Keyboard and Settings + // if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { + // // For ICS, we need to show "For all languages" in case that the keyboard locale + // // is different from the system locale + // localeSet.add(""); + // } + + final InputMethodManager imm = + (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + final List<InputMethodInfo> imis = imm.getEnabledInputMethodList(); + for (final InputMethodInfo imi : imis) { + final List<InputMethodSubtype> subtypes = + imm.getEnabledInputMethodSubtypeList( + imi, true /* allowsImplicitlySelectedSubtypes */); + for (InputMethodSubtype subtype : subtypes) { + final String locale = subtype.getLocale(); + if (!TextUtils.isEmpty(locale)) { + localeSet.add(locale); + } + } + } + + // We come here after we have collected locales from existing user dictionary entries and + // enabled subtypes. If we already have the locale-without-country version of the system + // locale, we don't add the system locale to avoid confusion even though it's technically + // correct to add it. + if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) { + localeSet.add(Locale.getDefault().toString()); + } + + return localeSet; + } + + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + TreeSet<String> getUserDictLocalesSet(Context context) { + return getUserDictionaryLocalesSet(context); + } + + /** + * Creates the entries that allow the user to go into the user dictionary for each locale. + */ + private void createUserDictSettings() { + + final TreeSet<String> localeSet = getUserDictLocalesSet(mContext); + final int prefCount = mScreen.getPreferenceCount(); + String prefKey; + + if (mLocale != null) { + // If the caller explicitly specify empty string as a locale, we'll show "all languages" + // in the list. + localeSet.add(mLocale); + } + if (localeSet.size() > 1) { + // Have an "All languages" entry in the languages list if there are two or more active + // languages + localeSet.add(""); + } + + // Update the existing preferenceScreen according to the corresponding data set. + if (prefCount > 0) { + for (int i = prefCount - 1; i >= 0; i--) { + prefKey = mScreen.getPreference(i).getKey(); + if (KEY_ALL_LANGUAGE.equals(prefKey)) { + prefKey = ""; + } + if (!localeSet.isEmpty() && localeSet.contains(prefKey)) { + localeSet.remove(prefKey); + continue; + } + mScreen.removePreference(mScreen.findPreference(prefKey)); + } + } + + if (localeSet.isEmpty() && prefCount == 0) { + mScreen.addPreference(createUserDictionaryPreference(null)); + } else { + for (String locale : localeSet) { + mScreen.addPreference(createUserDictionaryPreference(locale)); + } + } + } + + /** + * Create a single User Dictionary Preference object, with its parameters set. + * + * @param locale The locale for which this user dictionary is for. + * @return The corresponding preference. + */ + private Preference createUserDictionaryPreference(String locale) { + final String KEY_LOCALE = "locale"; + final Preference newPref = new Preference(mScreen.getContext()); + final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION); + if (locale == null) { + newPref.setTitle(Locale.getDefault().getDisplayName()); + newPref.setKey(Locale.getDefault().toString()); + } else { + if (TextUtils.isEmpty(locale)) { + newPref.setTitle(mContext.getString(R.string.user_dict_settings_all_languages)); + newPref.setKey(KEY_ALL_LANGUAGE); + newPref.setOrder(0); + } else { + newPref.setTitle(Utils.createLocaleFromString(locale).getDisplayName()); + newPref.setKey(locale); + } + intent.putExtra(KEY_LOCALE, locale); + newPref.getExtras().putString(KEY_LOCALE, locale); + } + newPref.setIntent(intent); + newPref.setFragment(UserDictionarySettings.class.getName()); + return newPref; + } +} |