UserDictionarySettings.java revision afc4ab2ffbb8327ddce9907961295a32cbf49d0f
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.database.Cursor; 25import android.os.Bundle; 26import android.provider.UserDictionary; 27import android.text.InputType; 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 private static final String INSTANCE_KEY_ADDED_WORD = "DIALOG_ADDED_WORD"; 48 49 private static final String[] QUERY_PROJECTION = { 50 UserDictionary.Words._ID, UserDictionary.Words.WORD 51 }; 52 53 // Either the locale is empty (means the word is applicable to all locales) 54 // or the word equals our current locale 55 private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=? OR " 56 + UserDictionary.Words.LOCALE + " is null"; 57 58 private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?"; 59 60 private static final String EXTRA_WORD = "word"; 61 62 private static final int CONTEXT_MENU_EDIT = Menu.FIRST; 63 private static final int CONTEXT_MENU_DELETE = Menu.FIRST + 1; 64 65 private static final int OPTIONS_MENU_ADD = Menu.FIRST; 66 67 private static final int DIALOG_ADD_OR_EDIT = 0; 68 69 /** The word being edited in the dialog (null means the user is adding a word). */ 70 private String mDialogEditingWord; 71 72 private Cursor mCursor; 73 74 private boolean mAddedWordAlready; 75 private boolean mAutoReturn; 76 77 @Override 78 protected void onCreate(Bundle savedInstanceState) { 79 super.onCreate(savedInstanceState); 80 81 setContentView(R.layout.list_content_with_empty_view); 82 83 mCursor = createCursor(); 84 setListAdapter(createAdapter()); 85 86 TextView emptyView = (TextView) findViewById(R.id.empty); 87 emptyView.setText(R.string.user_dict_settings_empty_text); 88 89 ListView listView = getListView(); 90 listView.setFastScrollEnabled(true); 91 listView.setEmptyView(emptyView); 92 93 registerForContextMenu(listView); 94 } 95 96 @Override 97 protected void onResume() { 98 super.onResume(); 99 if (!mAddedWordAlready 100 && getIntent().getAction().equals("com.android.settings.USER_DICTIONARY_INSERT")) { 101 String word = getIntent().getStringExtra(EXTRA_WORD); 102 mAutoReturn = true; 103 if (word != null) { 104 showAddOrEditDialog(word); 105 } 106 } 107 } 108 @Override 109 protected void onRestoreInstanceState(Bundle state) { 110 super.onRestoreInstanceState(state); 111 mDialogEditingWord = state.getString(INSTANCE_KEY_DIALOG_EDITING_WORD); 112 mAddedWordAlready = state.getBoolean(INSTANCE_KEY_ADDED_WORD, false); 113 } 114 115 @Override 116 protected void onSaveInstanceState(Bundle outState) { 117 super.onSaveInstanceState(outState); 118 outState.putString(INSTANCE_KEY_DIALOG_EDITING_WORD, mDialogEditingWord); 119 outState.putBoolean(INSTANCE_KEY_ADDED_WORD, mAddedWordAlready); 120 } 121 122 private Cursor createCursor() { 123 String currentLocale = Locale.getDefault().toString(); 124 // Case-insensitive sort 125 return managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION, 126 QUERY_SELECTION, new String[] { currentLocale }, 127 "UPPER(" + UserDictionary.Words.WORD + ")"); 128 } 129 130 private ListAdapter createAdapter() { 131 return new MyAdapter(this, 132 android.R.layout.simple_list_item_1, mCursor, 133 new String[] { UserDictionary.Words.WORD }, 134 new int[] { android.R.id.text1 }); 135 } 136 137 @Override 138 protected void onListItemClick(ListView l, View v, int position, long id) { 139 showAddOrEditDialog(getWord(position)); 140 } 141 142 @Override 143 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 144 if (!(menuInfo instanceof AdapterContextMenuInfo)) return; 145 146 AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo; 147 menu.setHeaderTitle(getWord(adapterMenuInfo.position)); 148 menu.add(0, CONTEXT_MENU_EDIT, 0, R.string.user_dict_settings_context_menu_edit_title); 149 menu.add(0, CONTEXT_MENU_DELETE, 0, R.string.user_dict_settings_context_menu_delete_title); 150 } 151 152 @Override 153 public boolean onContextItemSelected(MenuItem item) { 154 ContextMenuInfo menuInfo = item.getMenuInfo(); 155 if (!(menuInfo instanceof AdapterContextMenuInfo)) return false; 156 157 AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo; 158 String word = getWord(adapterMenuInfo.position); 159 160 switch (item.getItemId()) { 161 case CONTEXT_MENU_DELETE: 162 deleteWord(word); 163 return true; 164 165 case CONTEXT_MENU_EDIT: 166 showAddOrEditDialog(word); 167 return true; 168 } 169 170 return false; 171 } 172 173 @Override 174 public boolean onCreateOptionsMenu(Menu menu) { 175 menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title) 176 .setIcon(R.drawable.ic_menu_add); 177 return true; 178 } 179 180 @Override 181 public boolean onOptionsItemSelected(MenuItem item) { 182 showAddOrEditDialog(null); 183 return true; 184 } 185 186 private void showAddOrEditDialog(String editingWord) { 187 mDialogEditingWord = editingWord; 188 showDialog(DIALOG_ADD_OR_EDIT); 189 } 190 191 private String getWord(int position) { 192 mCursor.moveToPosition(position); 193 return mCursor.getString( 194 mCursor.getColumnIndexOrThrow(UserDictionary.Words.WORD)); 195 } 196 197 @Override 198 protected Dialog onCreateDialog(int id) { 199 View content = getLayoutInflater().inflate(R.layout.dialog_edittext, null); 200 final EditText editText = (EditText) content.findViewById(R.id.edittext); 201 // No prediction in soft keyboard mode. TODO: Create a better way to disable prediction 202 editText.setInputType(InputType.TYPE_CLASS_TEXT 203 | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); 204 205 return new AlertDialog.Builder(this) 206 .setTitle(R.string.user_dict_settings_add_dialog_title) 207 .setView(content) 208 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 209 public void onClick(DialogInterface dialog, int which) { 210 onAddOrEditFinished(editText.getText().toString()); 211 if (mAutoReturn) finish(); 212 }}) 213 .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 214 public void onClick(DialogInterface dialog, int which) { 215 if (mAutoReturn) finish(); 216 }}) 217 .create(); 218 } 219 220 @Override 221 protected void onPrepareDialog(int id, Dialog d) { 222 AlertDialog dialog = (AlertDialog) d; 223 EditText editText = (EditText) dialog.findViewById(R.id.edittext); 224 editText.setText(mDialogEditingWord); 225 } 226 227 private void onAddOrEditFinished(String word) { 228 if (mDialogEditingWord != null) { 229 // The user was editing a word, so do a delete/add 230 deleteWord(mDialogEditingWord); 231 } 232 233 // Disallow duplicates 234 deleteWord(word); 235 236 // TODO: present UI for picking whether to add word to all locales, or current. 237 UserDictionary.Words.addWord(this, word.toString(), 238 250, UserDictionary.Words.LOCALE_TYPE_ALL); 239 mCursor.requery(); 240 mAddedWordAlready = true; 241 } 242 243 private void deleteWord(String word) { 244 getContentResolver().delete(UserDictionary.Words.CONTENT_URI, DELETE_SELECTION, 245 new String[] { word }); 246 } 247 248 private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer { 249 private AlphabetIndexer mIndexer; 250 251 public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { 252 super(context, layout, c, from, to); 253 254 int wordColIndex = c.getColumnIndexOrThrow(UserDictionary.Words.WORD); 255 String alphabet = context.getString(com.android.internal.R.string.fast_scroll_alphabet); 256 mIndexer = new AlphabetIndexer(c, wordColIndex, alphabet); 257 } 258 259 public int getPositionForSection(int section) { 260 return mIndexer.getPositionForSection(section); 261 } 262 263 public int getSectionForPosition(int position) { 264 return mIndexer.getSectionForPosition(position); 265 } 266 267 public Object[] getSections() { 268 return mIndexer.getSections(); 269 } 270 } 271} 272