8f8464af24de2d584a534b8d706d585202036f02
[android/platform/packages/apps/Phone.git] / src / com / android / phone / ADNList.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.phone;
18
19 import static android.view.Window.PROGRESS_VISIBILITY_OFF;
20 import static android.view.Window.PROGRESS_VISIBILITY_ON;
21
22 import android.app.ListActivity;
23 import android.content.AsyncQueryHandler;
24 import android.content.ContentResolver;
25 import android.content.Intent;
26 import android.database.Cursor;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.util.Log;
30 import android.view.Window;
31 import android.widget.CursorAdapter;
32 import android.widget.SimpleCursorAdapter;
33 import android.widget.TextView;
34
35 /**
36  * ADN List activity for the Phone app.
37  */
38 public class ADNList extends ListActivity {
39     protected static final String TAG = "ADNList";
40     protected static final boolean DBG = false;
41
42     private static final String[] COLUMN_NAMES = new String[] {
43         "name",
44         "number"
45     };
46     
47
48     protected static final int NAME_COLUMN = 0;
49     protected static final int NUMBER_COLUMN = 1;
50
51     private static final int[] VIEW_NAMES = new int[] {
52         android.R.id.text1,
53         android.R.id.text2
54     };
55
56     protected static final int QUERY_TOKEN = 0;
57     protected static final int INSERT_TOKEN = 1;
58     protected static final int UPDATE_TOKEN = 2;
59     protected static final int DELETE_TOKEN = 3;
60
61
62     protected QueryHandler mQueryHandler;
63     protected CursorAdapter mCursorAdapter;
64     protected Cursor mCursor = null;
65
66     private TextView mEmptyText;
67
68     protected int mInitialSelection = -1;
69
70     @Override
71     protected void onCreate(Bundle icicle) {
72         super.onCreate(icicle);
73         getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
74         setContentView(R.layout.adn_list);
75         mEmptyText = (TextView) findViewById(android.R.id.empty);
76         mQueryHandler = new QueryHandler(getContentResolver());
77     }
78
79     @Override
80     protected void onResume() {
81         super.onResume();
82         query();
83     }
84
85     @Override
86     protected void onStop() {
87         super.onStop();
88         if (mCursor != null) {
89             mCursor.deactivate();
90         }
91     }
92
93     protected Uri resolveIntent() {
94         Intent intent = getIntent();
95         if (intent.getData() == null) {
96             intent.setData(Uri.parse("content://sim/adn"));
97         }
98
99         return intent.getData();
100     }
101
102     private void query() {
103         Uri uri = resolveIntent();
104         if (DBG) log("query: starting an async query");
105         mQueryHandler.startQuery(QUERY_TOKEN, null, uri, COLUMN_NAMES,
106                 null, null, null);
107         displayProgress(true);
108     }
109
110     private void reQuery() {
111         query();
112     }
113
114     private void setAdapter() {
115         // NOTE: 
116         // As it it written, the positioning code below is NOT working.
117         // However, this current non-working state is in compliance with
118         // the UI paradigm, so we can't really do much to change it.
119         
120         // In the future, if we wish to get this "positioning" correct,
121         // we'll need to do the following:
122         //   1. Change the layout to in the cursor adapter to:
123         //     android.R.layout.simple_list_item_checked
124         //   2. replace the selection / focus code with:
125         //     getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
126         //     getListView().setItemChecked(mInitialSelection, true);
127         
128         // Since the positioning is really only useful for the dialer's
129         // SpecialCharSequence case (dialing '2#' to get to the 2nd
130         // contact for instance), it doesn't make sense to mess with
131         // the usability of the activity just for this case.
132         
133         // These artifacts include: 
134         //  1. UI artifacts (checkbox and highlight at the same time)
135         //  2. Allowing the user to edit / create new SIM contacts when 
136         //    the user is simply trying to retrieve a number into the d
137         //    dialer.
138         
139         if (mCursorAdapter == null) {
140             mCursorAdapter = newAdapter();
141
142             setListAdapter(mCursorAdapter);
143         } else {
144             mCursorAdapter.changeCursor(mCursor);
145         }
146
147         if (mInitialSelection >=0 && mInitialSelection < mCursorAdapter.getCount()) {
148             setSelection(mInitialSelection);
149             getListView().setFocusableInTouchMode(true);
150             boolean gotfocus = getListView().requestFocus();
151         }
152     }
153
154     protected CursorAdapter newAdapter() {
155         return new SimpleCursorAdapter(this,
156                     android.R.layout.simple_list_item_2,
157                     mCursor, COLUMN_NAMES, VIEW_NAMES);
158     }
159
160     private void displayProgress(boolean flag) {
161         if (DBG) log("displayProgress: " + flag);
162         mEmptyText.setText(flag ? R.string.simContacts_emptyLoading: R.string.simContacts_empty);
163         getWindow().setFeatureInt(
164                 Window.FEATURE_INDETERMINATE_PROGRESS,
165                 flag ? PROGRESS_VISIBILITY_ON : PROGRESS_VISIBILITY_OFF);
166     }
167
168     private class QueryHandler extends AsyncQueryHandler {
169         public QueryHandler(ContentResolver cr) {
170             super(cr);
171         }
172
173         @Override
174         protected void onQueryComplete(int token, Object cookie, Cursor c) {
175             if (DBG) log("onQueryComplete: cursor.count=" + c.getCount());
176             mCursor = c;
177             setAdapter();
178             displayProgress(false);
179         }
180
181         @Override
182         protected void onInsertComplete(int token, Object cookie,
183                                         Uri uri) {
184             if (DBG) log("onInsertComplete: requery");
185             reQuery();
186         }
187
188         @Override
189         protected void onUpdateComplete(int token, Object cookie, int result) {
190             if (DBG) log("onUpdateComplete: requery");
191             reQuery();
192         }
193
194         @Override
195         protected void onDeleteComplete(int token, Object cookie, int result) {
196             if (DBG) log("onDeleteComplete: requery");
197             reQuery();
198         }
199     }
200
201     protected void log(String msg) {
202         Log.d(TAG, "[ADNList] " + msg);
203     }
204 }