UserDictionarySettings.java revision 1feaa85791b3b5cc66a16142afc2259a2356bc9e
1/** 2 * Copyright (C) 2007 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17package com.android.settings; 18 19import android.app.AlertDialog; 20import android.app.Dialog; 21import android.app.ListActivity; 22import android.content.Context; 23import android.content.DialogInterface; 24import android.content.Intent; 25import android.database.Cursor; 26import android.os.Bundle; 27import android.provider.UserDictionary; 28import android.view.ContextMenu; 29import android.view.Menu; 30import android.view.MenuItem; 31import android.view.View; 32import android.view.ContextMenu.ContextMenuInfo; 33import android.widget.AlphabetIndexer; 34import android.widget.EditText; 35import android.widget.ListAdapter; 36import android.widget.ListView; 37import android.widget.SectionIndexer; 38import android.widget.SimpleCursorAdapter; 39import android.widget.TextView; 40import android.widget.AdapterView.AdapterContextMenuInfo; 41 42import java.util.Locale; 43 44public class UserDictionarySettings extends ListActivity { 45 46 private static final String INSTANCE_KEY_DIALOG_EDITING_WORD = "DIALOG_EDITING_WORD"; 47 48 private static final String[] QUERY_PROJECTION = { 49 UserDictionary.Words._ID, UserDictionary.Words.WORD 50 }; 51 52 // Either the locale is empty (means the word is applicable to all locales) 53 // or the word equals our current locale 54 private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=? OR " 55 + UserDictionary.Words.LOCALE + " is null"; 56 57 private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?"; 58 59 private static final String EXTRA_WORD = "word"; 60 61 private static final int CONTEXT_MENU_EDIT = Menu.FIRST; 62 private static final int CONTEXT_MENU_DELETE = Menu.FIRST + 1; 63 64 private static final int OPTIONS_MENU_ADD = Menu.FIRST; 65 66 private static final int DIALOG_ADD_OR_EDIT = 0; 67 68 /** The word being edited in the dialog (null means the user is adding a word). */ 69 private String mDialogEditingWord; 70 71 private Cursor mCursor; 72 73 @Override 74 protected void onCreate(Bundle savedInstanceState) { 75 super.onCreate(savedInstanceState); 76 77 setContentView(R.layout.list_content_with_empty_view); 78 79 mCursor = createCursor(); 80 setListAdapter(createAdapter()); 81 82 TextView emptyView = (TextView) findViewById(R.id.empty); 83 emptyView.setText(R.string.user_dict_settings_empty_text); 84 85 ListView listView = getListView(); 86 listView.setFastScrollEnabled(true); 87 listView.setEmptyView(emptyView); 88 89 registerForContextMenu(listView); 90 } 91 92 @Override 93 protected void onResume() { 94 super.onResume(); 95 if (getIntent().getAction().equals("com.android.settings.USER_DICTIONARY_INSERT")) { 96 String word = getIntent().getStringExtra(EXTRA_WORD); 97 if (word != null) { 98 showAddOrEditDialog(word); 99 } 100 } 101 } 102 @Override 103 protected void onRestoreInstanceState(Bundle state) { 104 super.onRestoreInstanceState(state); 105 mDialogEditingWord = state.getString(INSTANCE_KEY_DIALOG_EDITING_WORD); 106 } 107 108 @Override 109 protected void onSaveInstanceState(Bundle outState) { 110 super.onSaveInstanceState(outState); 111 outState.putString(INSTANCE_KEY_DIALOG_EDITING_WORD, mDialogEditingWord); 112 } 113 114 private Cursor createCursor() { 115 String currentLocale = Locale.getDefault().toString(); 116 // Case-insensitive sort 117 return managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, 118 QUERY_SELECTION, new String[] { currentLocale }, 119 "UPPER(" + UserDictionary.Words.WORD + ")"); 120 } 121 122 private ListAdapter createAdapter() { 123 return new MyAdapter(this, 124 android.R.layout.simple_list_item_1, mCursor, 125 new String[] { UserDictionary.Words.WORD }, 126 new int[] { android.R.id.text1 }); 127 } 128 129 @Override 130 protected void onListItemClick(ListView l, View v, int position, long id) { 131 showAddOrEditDialog(getWord(position)); 132 } 133 134 @Override 135 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 136 if (!(menuInfo instanceof AdapterContextMenuInfo)) return; 137 138 AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo; 139 menu.setHeaderTitle(getWord(adapterMenuInfo.position)); 140 menu.add(0, CONTEXT_MENU_EDIT, 0, R.string.user_dict_settings_context_menu_edit_title); 141 menu.add(0, CONTEXT_MENU_DELETE, 0, R.string.user_dict_settings_context_menu_delete_title); 142 } 143 144 @Override 145 public boolean onContextItemSelected(MenuItem item) { 146 ContextMenuInfo menuInfo = item.getMenuInfo(); 147 if (!(menuInfo instanceof AdapterContextMenuInfo)) return false; 148 149 AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo; 150 String word = getWord(adapterMenuInfo.position); 151 152 switch (item.getItemId()) { 153 case CONTEXT_MENU_DELETE: 154 deleteWord(word); 155 return true; 156 157 case CONTEXT_MENU_EDIT: 158 showAddOrEditDialog(word); 159 return true; 160 } 161 162 return false; 163 } 164 165 @Override 166 public boolean onCreateOptionsMenu(Menu menu) { 167 menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title) 168 .setIcon(R.drawable.ic_menu_add); 169 return true; 170 } 171 172 @Override 173 public boolean onOptionsItemSelected(MenuItem item) { 174 showAddOrEditDialog(null); 175 return true; 176 } 177 178 private void showAddOrEditDialog(String editingWord) { 179 mDialogEditingWord = editingWord; 180 showDialog(DIALOG_ADD_OR_EDIT); 181 } 182 183 private String getWord(int position) { 184 mCursor.moveToPosition(position); 185 return mCursor.getString( 186 mCursor.getColumnIndexOrThrow(UserDictionary.Words.WORD)); 187 } 188 189 @Override 190 protected Dialog onCreateDialog(int id) { 191 View content = getLayoutInflater().inflate(R.layout.dialog_edittext, null); 192 final EditText editText = (EditText) content.findViewById(R.id.edittext); 193 194 return new AlertDialog.Builder(this) 195 .setTitle(R.string.user_dict_settings_add_dialog_title) 196 .setView(content) 197 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 198 public void onClick(DialogInterface dialog, int which) { 199 onAddOrEditFinished(editText.getText().toString()); 200 }}) 201 .setNegativeButton(android.R.string.cancel, null) 202 .create(); 203 } 204 205 @Override 206 protected void onPrepareDialog(int id, Dialog d) { 207 AlertDialog dialog = (AlertDialog) d; 208 EditText editText = (EditText) dialog.findViewById(R.id.edittext); 209 editText.setText(mDialogEditingWord); 210 } 211 212 private void onAddOrEditFinished(String word) { 213 if (mDialogEditingWord != null) { 214 // The user was editing a word, so do a delete/add 215 deleteWord(mDialogEditingWord); 216 } 217 218 // Disallow duplicates 219 deleteWord(word); 220 221 // TODO: present UI for picking whether to add word to all locales, or current. 222 UserDictionary.Words.addWord(this, word.toString(), 223 128, UserDictionary.Words.LOCALE_TYPE_ALL); 224 mCursor.requery(); 225 } 226 227 private void deleteWord(String word) { 228 getContentResolver().delete(UserDictionary.Words.CONTENT_URI, DELETE_SELECTION, 229 new String[] { word }); 230 } 231 232 private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer { 233 private AlphabetIndexer mIndexer; 234 235 public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { 236 super(context, layout, c, from, to); 237 238 int wordColIndex = c.getColumnIndexOrThrow(UserDictionary.Words.WORD); 239 String alphabet = context.getString(com.android.internal.R.string.fast_scroll_alphabet); 240 mIndexer = new AlphabetIndexer(c, wordColIndex, alphabet); 241 } 242 243 public int getPositionForSection(int section) { 244 return mIndexer.getPositionForSection(section); 245 } 246 247 public int getSectionForPosition(int position) { 248 return mIndexer.getSectionForPosition(position); 249 } 250 251 public Object[] getSections() { 252 return mIndexer.getSections(); 253 } 254 } 255} 256