Loading src/com/android/settings/core/gateway/SettingsGateway.java +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import com.android.settings.Settings; import com.android.settings.TestingSettings; import com.android.settings.TetherSettings; import com.android.settings.TrustedCredentialsSettings; import com.android.settings.UserDictionarySettings; import com.android.settings.WifiCallingSettings; import com.android.settings.accessibility.AccessibilitySettings; import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard; Loading Loading @@ -91,6 +90,7 @@ import com.android.settings.inputmethod.KeyboardLayoutPickerFragment; import com.android.settings.inputmethod.PhysicalKeyboardFragment; import com.android.settings.inputmethod.SpellCheckersSettings; import com.android.settings.inputmethod.UserDictionaryList; import com.android.settings.inputmethod.UserDictionarySettings; import com.android.settings.language.LanguageAndInputSettings; import com.android.settings.localepicker.LocaleListEditor; import com.android.settings.location.LocationSettings; Loading src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java +0 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.view.View; import android.widget.EditText; import com.android.settings.R; import com.android.settings.UserDictionarySettings; import com.android.settings.Utils; import java.util.ArrayList; Loading src/com/android/settings/inputmethod/UserDictionaryCursorLoader.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.CursorLoader; import android.database.Cursor; import android.database.MatrixCursor; import android.provider.UserDictionary; import android.support.annotation.VisibleForTesting; import android.util.ArraySet; import java.util.Locale; import java.util.Objects; import java.util.Set; public class UserDictionaryCursorLoader extends CursorLoader { @VisibleForTesting static final String[] QUERY_PROJECTION = { UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT }; // The index of the shortcut in the above array. static final int INDEX_SHORTCUT = 2; // Either the locale is empty (means the word is applicable to all locales) // or the word equals our current locale private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=?"; private static final String QUERY_SELECTION_ALL_LOCALES = UserDictionary.Words.LOCALE + " is null"; // Locale can be any of: // - The string representation of a locale, as returned by Locale#toString() // - The empty string. This means we want a cursor returning words valid for all locales. // - null. This means we want a cursor for the current locale, whatever this is. // Note that this contrasts with the data inside the database, where NULL means "all // locales" and there should never be an empty string. The confusion is called by the // historical use of null for "all locales". // TODO: it should be easy to make this more readable by making the special values // human-readable, like "all_locales" and "current_locales" strings, provided they // can be guaranteed not to match locales that may exist. private final String mLocale; public UserDictionaryCursorLoader(Context context, String locale) { super(context); mLocale = locale; } @Override public Cursor loadInBackground() { final MatrixCursor result = new MatrixCursor(QUERY_PROJECTION); final Cursor candidate; if ("".equals(mLocale)) { // Case-insensitive sort candidate = getContext().getContentResolver().query( UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION_ALL_LOCALES, null, "UPPER(" + UserDictionary.Words.WORD + ")"); } else { final String queryLocale = null != mLocale ? mLocale : Locale.getDefault().toString(); candidate = getContext().getContentResolver().query(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION, new String[]{queryLocale}, "UPPER(" + UserDictionary.Words.WORD + ")"); } final Set<Integer> hashSet = new ArraySet<>(); for (candidate.moveToFirst(); !candidate.isAfterLast(); candidate.moveToNext()) { final int id = candidate.getInt(0); final String word = candidate.getString(1); final String shortcut = candidate.getString(2); final int hash = Objects.hash(word, shortcut); if (hashSet.contains(hash)) { continue; } hashSet.add(hash); result.addRow(new Object[]{id, word, shortcut}); } return result; } } src/com/android/settings/inputmethod/UserDictionaryList.java +1 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ public class UserDictionaryList extends SettingsPreferenceFragment { newPref.getExtras().putString("locale", locale); } newPref.setIntent(intent); newPref.setFragment(com.android.settings.UserDictionarySettings.class.getName()); newPref.setFragment(UserDictionarySettings.class.getName()); return newPref; } Loading src/com/android/settings/UserDictionarySettings.java→src/com/android/settings/inputmethod/UserDictionarySettings.java +76 −85 Original line number Diff line number Diff line /** * Copyright (C) 2009 Google Inc. /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. * 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; package com.android.settings.inputmethod; import android.annotation.Nullable; import android.app.ActionBar; import android.app.ListFragment; import android.app.LoaderManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; import android.provider.UserDictionary; Loading @@ -38,28 +42,13 @@ import android.widget.SimpleCursorAdapter; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import com.android.settings.inputmethod.UserDictionaryAddWordContents; import com.android.settings.inputmethod.UserDictionarySettingsUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.instrumentation.Instrumentable; import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import java.util.Locale; public class UserDictionarySettings extends ListFragment implements Instrumentable { private static final String[] QUERY_PROJECTION = { UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT }; // The index of the shortcut in the above array. private static final int INDEX_SHORTCUT = 2; // Either the locale is empty (means the word is applicable to all locales) // or the word equals our current locale private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=?"; private static final String QUERY_SELECTION_ALL_LOCALES = UserDictionary.Words.LOCALE + " is null"; public class UserDictionarySettings extends ListFragment implements Instrumentable, LoaderManager.LoaderCallbacks<Cursor> { private static final String DELETE_SELECTION_WITH_SHORTCUT = UserDictionary.Words.WORD + "=? AND " + UserDictionary.Words.SHORTCUT + "=?"; Loading @@ -68,12 +57,13 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab + UserDictionary.Words.SHORTCUT + "=''"; private static final int OPTIONS_MENU_ADD = Menu.FIRST; private static final int LOADER_ID = 1; private final VisibilityLoggerMixin mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory()); private Cursor mCursor; protected String mLocale; private String mLocale; @Override public int getMetricsCategory() { Loading @@ -87,16 +77,8 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate( com.android.internal.R.layout.preference_list_fragment, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActivity().getActionBar().setTitle(R.string.user_dict_settings_title); public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = getActivity().getIntent(); final String localeFromIntent = Loading @@ -116,56 +98,49 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } mLocale = locale; mCursor = createCursor(locale); TextView emptyView = (TextView) getView().findViewById(android.R.id.empty); setHasOptionsMenu(true); getLoaderManager().initLoader(LOADER_ID, null, this /* callback */); } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Show the language as a subtitle of the action bar final ActionBar actionBar = getActivity().getActionBar(); if (actionBar != null) { actionBar.setTitle(R.string.user_dict_settings_title); actionBar.setSubtitle( UserDictionarySettingsUtils.getLocaleDisplayName(getActivity(), mLocale)); } return inflater.inflate( com.android.internal.R.layout.preference_list_fragment, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); TextView emptyView = getView().findViewById(android.R.id.empty); emptyView.setText(R.string.user_dict_settings_empty_text); final ListView listView = getListView(); listView.setAdapter(createAdapter()); listView.setFastScrollEnabled(true); listView.setEmptyView(emptyView); setHasOptionsMenu(true); // Show the language as a subtitle of the action bar getActivity().getActionBar().setSubtitle( UserDictionarySettingsUtils.getLocaleDisplayName(getActivity(), mLocale)); } @Override public void onResume() { super.onResume(); mVisibilityLoggerMixin.onResume(); } private Cursor createCursor(final String locale) { // Locale can be any of: // - The string representation of a locale, as returned by Locale#toString() // - The empty string. This means we want a cursor returning words valid for all locales. // - null. This means we want a cursor for the current locale, whatever this is. // Note that this contrasts with the data inside the database, where NULL means "all // locales" and there should never be an empty string. The confusion is called by the // historical use of null for "all locales". // TODO: it should be easy to make this more readable by making the special values // human-readable, like "all_locales" and "current_locales" strings, provided they // can be guaranteed not to match locales that may exist. if ("".equals(locale)) { // Case-insensitive sort return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION_ALL_LOCALES, null, "UPPER(" + UserDictionary.Words.WORD + ")"); } else { final String queryLocale = null != locale ? locale : Locale.getDefault().toString(); return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION, new String[] { queryLocale }, "UPPER(" + UserDictionary.Words.WORD + ")"); } getLoaderManager().restartLoader(LOADER_ID, null, this /* callback */); } private ListAdapter createAdapter() { return new MyAdapter(getActivity(), R.layout.user_dictionary_item, mCursor, new String[]{UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT}, new int[] { android.R.id.text1, android.R.id.text2 }, this); new int[]{android.R.id.text1, android.R.id.text2}); } @Override Loading Loading @@ -203,6 +178,7 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab /** * Add or edit a word. If editingWord is null, it's an add; otherwise, it's an edit. * * @param editingWord the word to edit, or null if it's an add. * @param editingShortcut the shortcut for this entry, or null if none. */ Loading Loading @@ -253,6 +229,22 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new UserDictionaryCursorLoader(getContext(), mLocale); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mCursor = data; getListView().setAdapter(createAdapter()); } @Override public void onLoaderReset(Loader<Cursor> loader) { } private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer { private AlphabetIndexer mIndexer; Loading @@ -261,8 +253,8 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab @Override public boolean setViewValue(View v, Cursor c, int columnIndex) { if (columnIndex == INDEX_SHORTCUT) { final String shortcut = c.getString(INDEX_SHORTCUT); if (columnIndex == UserDictionaryCursorLoader.INDEX_SHORTCUT) { final String shortcut = c.getString(UserDictionaryCursorLoader.INDEX_SHORTCUT); if (TextUtils.isEmpty(shortcut)) { v.setVisibility(View.GONE); } else { Loading @@ -277,8 +269,7 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } }; public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to, UserDictionarySettings settings) { public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); if (null != c) { Loading Loading
src/com/android/settings/core/gateway/SettingsGateway.java +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import com.android.settings.Settings; import com.android.settings.TestingSettings; import com.android.settings.TetherSettings; import com.android.settings.TrustedCredentialsSettings; import com.android.settings.UserDictionarySettings; import com.android.settings.WifiCallingSettings; import com.android.settings.accessibility.AccessibilitySettings; import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard; Loading Loading @@ -91,6 +90,7 @@ import com.android.settings.inputmethod.KeyboardLayoutPickerFragment; import com.android.settings.inputmethod.PhysicalKeyboardFragment; import com.android.settings.inputmethod.SpellCheckersSettings; import com.android.settings.inputmethod.UserDictionaryList; import com.android.settings.inputmethod.UserDictionarySettings; import com.android.settings.language.LanguageAndInputSettings; import com.android.settings.localepicker.LocaleListEditor; import com.android.settings.location.LocationSettings; Loading
src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java +0 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.view.View; import android.widget.EditText; import com.android.settings.R; import com.android.settings.UserDictionarySettings; import com.android.settings.Utils; import java.util.ArrayList; Loading
src/com/android/settings/inputmethod/UserDictionaryCursorLoader.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.CursorLoader; import android.database.Cursor; import android.database.MatrixCursor; import android.provider.UserDictionary; import android.support.annotation.VisibleForTesting; import android.util.ArraySet; import java.util.Locale; import java.util.Objects; import java.util.Set; public class UserDictionaryCursorLoader extends CursorLoader { @VisibleForTesting static final String[] QUERY_PROJECTION = { UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT }; // The index of the shortcut in the above array. static final int INDEX_SHORTCUT = 2; // Either the locale is empty (means the word is applicable to all locales) // or the word equals our current locale private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=?"; private static final String QUERY_SELECTION_ALL_LOCALES = UserDictionary.Words.LOCALE + " is null"; // Locale can be any of: // - The string representation of a locale, as returned by Locale#toString() // - The empty string. This means we want a cursor returning words valid for all locales. // - null. This means we want a cursor for the current locale, whatever this is. // Note that this contrasts with the data inside the database, where NULL means "all // locales" and there should never be an empty string. The confusion is called by the // historical use of null for "all locales". // TODO: it should be easy to make this more readable by making the special values // human-readable, like "all_locales" and "current_locales" strings, provided they // can be guaranteed not to match locales that may exist. private final String mLocale; public UserDictionaryCursorLoader(Context context, String locale) { super(context); mLocale = locale; } @Override public Cursor loadInBackground() { final MatrixCursor result = new MatrixCursor(QUERY_PROJECTION); final Cursor candidate; if ("".equals(mLocale)) { // Case-insensitive sort candidate = getContext().getContentResolver().query( UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION_ALL_LOCALES, null, "UPPER(" + UserDictionary.Words.WORD + ")"); } else { final String queryLocale = null != mLocale ? mLocale : Locale.getDefault().toString(); candidate = getContext().getContentResolver().query(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION, new String[]{queryLocale}, "UPPER(" + UserDictionary.Words.WORD + ")"); } final Set<Integer> hashSet = new ArraySet<>(); for (candidate.moveToFirst(); !candidate.isAfterLast(); candidate.moveToNext()) { final int id = candidate.getInt(0); final String word = candidate.getString(1); final String shortcut = candidate.getString(2); final int hash = Objects.hash(word, shortcut); if (hashSet.contains(hash)) { continue; } hashSet.add(hash); result.addRow(new Object[]{id, word, shortcut}); } return result; } }
src/com/android/settings/inputmethod/UserDictionaryList.java +1 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ public class UserDictionaryList extends SettingsPreferenceFragment { newPref.getExtras().putString("locale", locale); } newPref.setIntent(intent); newPref.setFragment(com.android.settings.UserDictionarySettings.class.getName()); newPref.setFragment(UserDictionarySettings.class.getName()); return newPref; } Loading
src/com/android/settings/UserDictionarySettings.java→src/com/android/settings/inputmethod/UserDictionarySettings.java +76 −85 Original line number Diff line number Diff line /** * Copyright (C) 2009 Google Inc. /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. * 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; package com.android.settings.inputmethod; import android.annotation.Nullable; import android.app.ActionBar; import android.app.ListFragment; import android.app.LoaderManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; import android.provider.UserDictionary; Loading @@ -38,28 +42,13 @@ import android.widget.SimpleCursorAdapter; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import com.android.settings.inputmethod.UserDictionaryAddWordContents; import com.android.settings.inputmethod.UserDictionarySettingsUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.instrumentation.Instrumentable; import com.android.settings.core.instrumentation.VisibilityLoggerMixin; import java.util.Locale; public class UserDictionarySettings extends ListFragment implements Instrumentable { private static final String[] QUERY_PROJECTION = { UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT }; // The index of the shortcut in the above array. private static final int INDEX_SHORTCUT = 2; // Either the locale is empty (means the word is applicable to all locales) // or the word equals our current locale private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=?"; private static final String QUERY_SELECTION_ALL_LOCALES = UserDictionary.Words.LOCALE + " is null"; public class UserDictionarySettings extends ListFragment implements Instrumentable, LoaderManager.LoaderCallbacks<Cursor> { private static final String DELETE_SELECTION_WITH_SHORTCUT = UserDictionary.Words.WORD + "=? AND " + UserDictionary.Words.SHORTCUT + "=?"; Loading @@ -68,12 +57,13 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab + UserDictionary.Words.SHORTCUT + "=''"; private static final int OPTIONS_MENU_ADD = Menu.FIRST; private static final int LOADER_ID = 1; private final VisibilityLoggerMixin mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory()); private Cursor mCursor; protected String mLocale; private String mLocale; @Override public int getMetricsCategory() { Loading @@ -87,16 +77,8 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate( com.android.internal.R.layout.preference_list_fragment, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActivity().getActionBar().setTitle(R.string.user_dict_settings_title); public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = getActivity().getIntent(); final String localeFromIntent = Loading @@ -116,56 +98,49 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } mLocale = locale; mCursor = createCursor(locale); TextView emptyView = (TextView) getView().findViewById(android.R.id.empty); setHasOptionsMenu(true); getLoaderManager().initLoader(LOADER_ID, null, this /* callback */); } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Show the language as a subtitle of the action bar final ActionBar actionBar = getActivity().getActionBar(); if (actionBar != null) { actionBar.setTitle(R.string.user_dict_settings_title); actionBar.setSubtitle( UserDictionarySettingsUtils.getLocaleDisplayName(getActivity(), mLocale)); } return inflater.inflate( com.android.internal.R.layout.preference_list_fragment, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); TextView emptyView = getView().findViewById(android.R.id.empty); emptyView.setText(R.string.user_dict_settings_empty_text); final ListView listView = getListView(); listView.setAdapter(createAdapter()); listView.setFastScrollEnabled(true); listView.setEmptyView(emptyView); setHasOptionsMenu(true); // Show the language as a subtitle of the action bar getActivity().getActionBar().setSubtitle( UserDictionarySettingsUtils.getLocaleDisplayName(getActivity(), mLocale)); } @Override public void onResume() { super.onResume(); mVisibilityLoggerMixin.onResume(); } private Cursor createCursor(final String locale) { // Locale can be any of: // - The string representation of a locale, as returned by Locale#toString() // - The empty string. This means we want a cursor returning words valid for all locales. // - null. This means we want a cursor for the current locale, whatever this is. // Note that this contrasts with the data inside the database, where NULL means "all // locales" and there should never be an empty string. The confusion is called by the // historical use of null for "all locales". // TODO: it should be easy to make this more readable by making the special values // human-readable, like "all_locales" and "current_locales" strings, provided they // can be guaranteed not to match locales that may exist. if ("".equals(locale)) { // Case-insensitive sort return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION_ALL_LOCALES, null, "UPPER(" + UserDictionary.Words.WORD + ")"); } else { final String queryLocale = null != locale ? locale : Locale.getDefault().toString(); return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, QUERY_SELECTION, new String[] { queryLocale }, "UPPER(" + UserDictionary.Words.WORD + ")"); } getLoaderManager().restartLoader(LOADER_ID, null, this /* callback */); } private ListAdapter createAdapter() { return new MyAdapter(getActivity(), R.layout.user_dictionary_item, mCursor, new String[]{UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT}, new int[] { android.R.id.text1, android.R.id.text2 }, this); new int[]{android.R.id.text1, android.R.id.text2}); } @Override Loading Loading @@ -203,6 +178,7 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab /** * Add or edit a word. If editingWord is null, it's an add; otherwise, it's an edit. * * @param editingWord the word to edit, or null if it's an add. * @param editingShortcut the shortcut for this entry, or null if none. */ Loading Loading @@ -253,6 +229,22 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new UserDictionaryCursorLoader(getContext(), mLocale); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mCursor = data; getListView().setAdapter(createAdapter()); } @Override public void onLoaderReset(Loader<Cursor> loader) { } private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer { private AlphabetIndexer mIndexer; Loading @@ -261,8 +253,8 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab @Override public boolean setViewValue(View v, Cursor c, int columnIndex) { if (columnIndex == INDEX_SHORTCUT) { final String shortcut = c.getString(INDEX_SHORTCUT); if (columnIndex == UserDictionaryCursorLoader.INDEX_SHORTCUT) { final String shortcut = c.getString(UserDictionaryCursorLoader.INDEX_SHORTCUT); if (TextUtils.isEmpty(shortcut)) { v.setVisibility(View.GONE); } else { Loading @@ -277,8 +269,7 @@ public class UserDictionarySettings extends ListFragment implements Instrumentab } }; public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to, UserDictionarySettings settings) { public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); if (null != c) { Loading