OSDN Git Service

am 28539897: am 8815f032: Merge "Always set right auth_type value in apn."
[android-x86/packages-apps-Settings.git] / src / com / android / settings / UserDictionarySettings.java
1 /**
2  * Copyright (C) 2009 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
17 package com.android.settings;
18
19 import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
20
21 import android.app.Activity;
22 import android.app.AlertDialog;
23 import android.app.Dialog;
24 import android.app.ListFragment;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.content.Intent;
28 import android.database.Cursor;
29 import android.os.Bundle;
30 import android.provider.UserDictionary;
31 import android.text.InputType;
32 import android.util.Log;
33 import android.view.ContextMenu;
34 import android.view.LayoutInflater;
35 import android.view.Menu;
36 import android.view.MenuInflater;
37 import android.view.MenuItem;
38 import android.view.View;
39 import android.view.ViewGroup;
40 import android.view.WindowManager;
41 import android.view.ContextMenu.ContextMenuInfo;
42 import android.widget.AlphabetIndexer;
43 import android.widget.EditText;
44 import android.widget.ImageView;
45 import android.widget.ListAdapter;
46 import android.widget.ListView;
47 import android.widget.SectionIndexer;
48 import android.widget.SimpleCursorAdapter;
49 import android.widget.TextView;
50 import android.widget.AdapterView.AdapterContextMenuInfo;
51
52 import java.util.Locale;
53
54 public class UserDictionarySettings extends ListFragment implements DialogCreatable {
55     private static final String TAG = "UserDictionarySettings";
56
57     private static final String INSTANCE_KEY_DIALOG_EDITING_WORD = "DIALOG_EDITING_WORD";
58     private static final String INSTANCE_KEY_ADDED_WORD = "DIALOG_ADDED_WORD";
59
60     private static final String[] QUERY_PROJECTION = {
61         UserDictionary.Words._ID, UserDictionary.Words.WORD
62     };
63
64     private static final int INDEX_ID = 0;
65     private static final int INDEX_WORD = 1;
66
67     // Either the locale is empty (means the word is applicable to all locales)
68     // or the word equals our current locale
69     private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=? OR "
70             + UserDictionary.Words.LOCALE + " is null";
71
72     private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?";
73
74     private static final String EXTRA_WORD = "word";
75     
76     private static final int CONTEXT_MENU_EDIT = Menu.FIRST;
77     private static final int CONTEXT_MENU_DELETE = Menu.FIRST + 1;
78     
79     private static final int OPTIONS_MENU_ADD = Menu.FIRST;
80
81     private static final int DIALOG_ADD_OR_EDIT = 0;
82     
83     /** The word being edited in the dialog (null means the user is adding a word). */
84     private String mDialogEditingWord;
85
86     private View mView;
87     private Cursor mCursor;
88     
89     private boolean mAddedWordAlready;
90     private boolean mAutoReturn;
91
92     private SettingsDialogFragment mDialogFragment;
93
94     @Override
95     public void onCreate(Bundle savedInstanceState) {
96         super.onCreate(savedInstanceState);
97     }
98
99     @Override
100     public View onCreateView(LayoutInflater inflater, ViewGroup container,
101             Bundle savedInstanceState) {
102         mView = inflater.inflate(R.layout.list_content_with_empty_view, container, false);
103         return mView;
104     }
105
106     @Override
107     public void onActivityCreated(Bundle savedInstanceState) {
108         super.onActivityCreated(savedInstanceState);
109
110         mCursor = createCursor();
111         TextView emptyView = (TextView)mView.findViewById(R.id.empty);
112         emptyView.setText(R.string.user_dict_settings_empty_text);
113
114         final ListView listView = getListView();
115         listView.setAdapter(createAdapter());
116         listView.setFastScrollEnabled(true);
117         listView.setEmptyView(emptyView);
118
119         registerForContextMenu(listView);
120         setHasOptionsMenu(true);
121
122         if (savedInstanceState != null) {
123             mDialogEditingWord = savedInstanceState.getString(INSTANCE_KEY_DIALOG_EDITING_WORD);
124             mAddedWordAlready = savedInstanceState.getBoolean(INSTANCE_KEY_ADDED_WORD, false);
125         }
126     }
127     
128     @Override
129     public void onResume() {
130         super.onResume();
131         final Intent intent = getActivity().getIntent();
132         if (!mAddedWordAlready 
133                 && intent.getAction().equals("com.android.settings.USER_DICTIONARY_INSERT")) {
134             final String word = intent.getStringExtra(EXTRA_WORD);
135             mAutoReturn = true;
136             if (word != null) {
137                 showAddOrEditDialog(word);
138             }
139         }
140     }
141
142     @Override
143     public void onSaveInstanceState(Bundle outState) {
144         super.onSaveInstanceState(outState);
145         outState.putString(INSTANCE_KEY_DIALOG_EDITING_WORD, mDialogEditingWord);
146         outState.putBoolean(INSTANCE_KEY_ADDED_WORD, mAddedWordAlready);
147     }
148
149     private Cursor createCursor() {
150         String currentLocale = Locale.getDefault().toString();
151         // Case-insensitive sort
152         return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
153                 QUERY_SELECTION, new String[] { currentLocale },
154                 "UPPER(" + UserDictionary.Words.WORD + ")");
155     }
156
157     private ListAdapter createAdapter() {
158         return new MyAdapter(getActivity(),
159                 R.layout.user_dictionary_item, mCursor,
160                 new String[] { UserDictionary.Words.WORD, UserDictionary.Words._ID },
161                 new int[] { android.R.id.text1, R.id.delete_button }, this);
162     }
163     
164     @Override
165     public void onListItemClick(ListView l, View v, int position, long id) {
166         getActivity().openContextMenu(v);
167     }
168
169     @Override
170     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
171         if (!(menuInfo instanceof AdapterContextMenuInfo)) return;
172         
173         AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
174         menu.setHeaderTitle(getWord(adapterMenuInfo.position));
175         menu.add(0, CONTEXT_MENU_EDIT, 0, 
176                 R.string.user_dict_settings_context_menu_edit_title);
177         menu.add(0, CONTEXT_MENU_DELETE, 0, 
178                 R.string.user_dict_settings_context_menu_delete_title);
179     }
180     
181     @Override
182     public boolean onContextItemSelected(MenuItem item) {
183         ContextMenuInfo menuInfo = item.getMenuInfo();
184         if (!(menuInfo instanceof AdapterContextMenuInfo)) return false;
185         
186         AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
187         String word = getWord(adapterMenuInfo.position);
188         if (word == null) return true;
189
190         switch (item.getItemId()) {
191             case CONTEXT_MENU_DELETE:
192                 deleteWord(word);
193                 return true;
194                 
195             case CONTEXT_MENU_EDIT:
196                 showAddOrEditDialog(word);
197                 return true;
198         }
199         
200         return false;
201     }
202
203     @Override
204     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
205         MenuItem actionItem =
206                 menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title)
207                 .setIcon(R.drawable.ic_menu_add);
208         actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
209     }
210
211     @Override
212     public boolean onOptionsItemSelected(MenuItem item) {
213         showAddOrEditDialog(null);
214         return true;
215     }
216
217     private void showAddOrEditDialog(String editingWord) {
218         mDialogEditingWord = editingWord;
219         showDialog(DIALOG_ADD_OR_EDIT);
220     }
221
222     private String getWord(int position) {
223         mCursor.moveToPosition(position);
224         // Handle a possible race-condition
225         if (mCursor.isAfterLast()) return null;
226
227         return mCursor.getString(
228                 mCursor.getColumnIndexOrThrow(UserDictionary.Words.WORD));
229     }
230
231     @Override
232     public Dialog onCreateDialog(int id) {
233         final Activity activity = getActivity();
234         final View content = activity.getLayoutInflater().inflate(R.layout.dialog_edittext, null);
235         final EditText editText = (EditText) content.findViewById(R.id.edittext);
236         editText.setText(mDialogEditingWord);
237         // No prediction in soft keyboard mode. TODO: Create a better way to disable prediction
238         editText.setInputType(InputType.TYPE_CLASS_TEXT 
239                 | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
240
241         AlertDialog dialog =  new AlertDialog.Builder(activity)
242                 .setTitle(mDialogEditingWord != null 
243                         ? R.string.user_dict_settings_edit_dialog_title 
244                         : R.string.user_dict_settings_add_dialog_title)
245                 .setView(content)
246                 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
247                     public void onClick(DialogInterface dialog, int which) {
248                         onAddOrEditFinished(editText.getText().toString());
249                         if (mAutoReturn) activity.onBackPressed();
250                     }})
251                 .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
252                     public void onClick(DialogInterface dialog, int which) {
253                         if (mAutoReturn) activity.onBackPressed();
254                     }})
255                 .create();
256         dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
257                 WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
258         return dialog;
259     }
260
261     private void showDialog(int dialogId) {
262         if (mDialogFragment != null) {
263             Log.e(TAG, "Old dialog fragment not null!");
264         }
265         mDialogFragment = new SettingsDialogFragment(this, dialogId);
266         mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
267     }
268
269     private void onAddOrEditFinished(String word) {
270         if (mDialogEditingWord != null) {
271             // The user was editing a word, so do a delete/add
272             deleteWord(mDialogEditingWord);
273         }
274         
275         // Disallow duplicates
276         deleteWord(word);
277         
278         // TODO: present UI for picking whether to add word to all locales, or current.
279         UserDictionary.Words.addWord(getActivity(), word.toString(),
280                 250, UserDictionary.Words.LOCALE_TYPE_ALL);
281         if (!mCursor.requery()) {
282             throw new IllegalStateException("can't requery on already-closed cursor.");
283         }
284         mAddedWordAlready = true;
285     }
286
287     private void deleteWord(String word) {
288         getActivity().getContentResolver().delete(
289                 UserDictionary.Words.CONTENT_URI, DELETE_SELECTION, new String[] { word });
290     }
291
292     private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer,
293             View.OnClickListener {
294
295         private AlphabetIndexer mIndexer;
296         private UserDictionarySettings mSettings;
297
298         private ViewBinder mViewBinder = new ViewBinder() {
299
300             public boolean setViewValue(View v, Cursor c, int columnIndex) {
301                 if (v instanceof ImageView && columnIndex == INDEX_ID) {
302                     v.setOnClickListener(MyAdapter.this);
303                     v.setTag(c.getString(INDEX_WORD));
304                     return true;
305                 }
306
307                 return false;
308             }
309         };
310
311         public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to,
312                 UserDictionarySettings settings) {
313             super(context, layout, c, from, to);
314
315             mSettings = settings;
316             int wordColIndex = c.getColumnIndexOrThrow(UserDictionary.Words.WORD);
317             String alphabet = context.getString(
318                     com.android.internal.R.string.fast_scroll_alphabet);
319             mIndexer = new AlphabetIndexer(c, wordColIndex, alphabet);
320             setViewBinder(mViewBinder);
321         }
322
323         public int getPositionForSection(int section) {
324             return mIndexer.getPositionForSection(section);
325         }
326
327         public int getSectionForPosition(int position) {
328             return mIndexer.getSectionForPosition(position);
329         }
330
331         public Object[] getSections() {
332             return mIndexer.getSections();
333         }
334
335         public void onClick(View v) {
336             mSettings.deleteWord((String) v.getTag());
337         }
338     }
339 }