blob: 981b4bcc50cb444c0b65e838d35db1a787327e27 [file] [log] [blame]
The Android Open Source Project5dc3b4f2008-10-21 07:00:00 -07001/*
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
17package com.android.contacts;
18
19import android.content.Context;
20import android.net.Uri;
21import android.os.Parcel;
22import android.provider.Contacts.Organizations;
23import android.provider.Contacts.People;
24import android.view.LayoutInflater;
25import android.view.View;
26import android.view.ViewGroup;
27import android.widget.BaseAdapter;
28
29import java.util.ArrayList;
30
31public abstract class ContactEntryAdapter<E extends ContactEntryAdapter.Entry>
32 extends BaseAdapter {
33
34 public static final String[] CONTACT_PROJECTION = new String[] {
35 People._ID, // 0
36 People.NAME, // 1
37 People.NOTES, // 2
38 People.PRIMARY_PHONE_ID, // 3
39 People.PRESENCE_STATUS, // 4
40 People.STARRED, // 5
41 People.CUSTOM_RINGTONE, // 6
42 People.SEND_TO_VOICEMAIL, // 7
43 };
44 public static final int CONTACT_ID_COLUMN = 0;
45 public static final int CONTACT_NAME_COLUMN = 1;
46 public static final int CONTACT_NOTES_COLUMN = 2;
47 public static final int CONTACT_PREFERRED_PHONE_COLUMN = 3;
48 public static final int CONTACT_SERVER_STATUS_COLUMN = 4;
49 public static final int CONTACT_STARRED_COLUMN = 5;
50 public static final int CONTACT_CUSTOM_RINGTONE_COLUMN = 6;
51 public static final int CONTACT_SEND_TO_VOICEMAIL_COLUMN = 7;
52
53 public static final String[] PHONES_PROJECTION = new String[] {
54 People.Phones._ID, // 0
55 People.Phones.NUMBER, // 1
56 People.Phones.TYPE, // 2
57 People.Phones.LABEL, // 3
58 People.Phones.ISPRIMARY, // 4
59 };
60 public static final int PHONES_ID_COLUMN = 0;
61 public static final int PHONES_NUMBER_COLUMN = 1;
62 public static final int PHONES_TYPE_COLUMN = 2;
63 public static final int PHONES_LABEL_COLUMN = 3;
64 public static final int PHONES_ISPRIMARY_COLUMN = 4;
65
66 public static final String[] METHODS_PROJECTION = new String[] {
67 People.ContactMethods._ID, // 0
68 People.ContactMethods.KIND, // 1
69 People.ContactMethods.DATA, // 2
70 People.ContactMethods.TYPE, // 3
71 People.ContactMethods.LABEL, // 4
72 People.ContactMethods.ISPRIMARY, // 5
73 People.ContactMethods.AUX_DATA, // 6
74 };
75 public static final String[] METHODS_WITH_PRESENCE_PROJECTION = new String[] {
76 People.ContactMethods._ID, // 0
77 People.ContactMethods.KIND, // 1
78 People.ContactMethods.DATA, // 2
79 People.ContactMethods.TYPE, // 3
80 People.ContactMethods.LABEL, // 4
81 People.ContactMethods.ISPRIMARY, // 5
82 People.ContactMethods.AUX_DATA, // 6
83 People.PRESENCE_STATUS, // 7
84 };
85 public static final int METHODS_ID_COLUMN = 0;
86 public static final int METHODS_KIND_COLUMN = 1;
87 public static final int METHODS_DATA_COLUMN = 2;
88 public static final int METHODS_TYPE_COLUMN = 3;
89 public static final int METHODS_LABEL_COLUMN = 4;
90 public static final int METHODS_ISPRIMARY_COLUMN = 5;
91 public static final int METHODS_AUX_DATA_COLUMN = 6;
92 public static final int METHODS_STATUS_COLUMN = 7;
93
94 public static final String[] ORGANIZATIONS_PROJECTION = new String[] {
95 Organizations._ID, // 0
96 Organizations.TYPE, // 1
97 Organizations.LABEL, // 2
98 Organizations.COMPANY, // 3
99 Organizations.TITLE, // 4
100 Organizations.ISPRIMARY, // 5
101 };
102 public static final int ORGANIZATIONS_ID_COLUMN = 0;
103 public static final int ORGANIZATIONS_TYPE_COLUMN = 1;
104 public static final int ORGANIZATIONS_LABEL_COLUMN = 2;
105 public static final int ORGANIZATIONS_COMPANY_COLUMN = 3;
106 public static final int ORGANIZATIONS_TITLE_COLUMN = 4;
107 public static final int ORGANIZATIONS_ISPRIMARY_COLUMN = 5;
108
109 protected ArrayList<ArrayList<E>> mSections;
110 protected LayoutInflater mInflater;
111 protected Context mContext;
112 protected boolean mSeparators;
113
114 /**
115 * Base class for adapter entries.
116 */
117 public static class Entry {
118 /** Details from the person table */
119 public static final int KIND_CONTACT = -1;
120 /** Synthesized phone entry that will send an SMS instead of call the number */
121 public static final int KIND_SMS = -2;
122 /** A section separator */
123 public static final int KIND_SEPARATOR = -3;
124
125 public String label;
126 public String data;
127 public Uri uri;
128 public long id = 0;
129 public int maxLines = 1;
130 public int kind;
131
132 /**
133 * Helper for making subclasses parcelable.
134 */
135 protected void writeToParcel(Parcel p) {
136 p.writeString(label);
137 p.writeString(data);
138 p.writeParcelable(uri, 0);
139 p.writeLong(id);
140 p.writeInt(maxLines);
141 p.writeInt(kind);
142 }
143
144 /**
145 * Helper for making subclasses parcelable.
146 */
147 protected void readFromParcel(Parcel p) {
148 label = p.readString();
149 data = p.readString();
150 uri = p.readParcelable(null);
151 id = p.readLong();
152 maxLines = p.readInt();
153 kind = p.readInt();
154 }
155 }
156
157 ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
158 mContext = context;
159 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
160 mSections = sections;
161 mSeparators = separators;
162 }
163
164 /**
165 * Resets the section data.
166 *
167 * @param sections the section data
168 */
169 public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
170 mSections = sections;
171 mSeparators = separators;
172 notifyDataSetChanged();
173 }
174
175 /**
176 * Resets the section data and returns the position of the given entry.
177 *
178 * @param sections the section data
179 * @param entry the entry to return the position for
180 * @return the position of entry, or -1 if it isn't found
181 */
182 public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
183 mSections = sections;
184 notifyDataSetChanged();
185
186 int numSections = mSections.size();
187 int position = 0;
188 for (int i = 0; i < numSections; i++) {
189 ArrayList<E> section = mSections.get(i);
190 int sectionSize = section.size();
191 for (int j = 0; j < sectionSize; j++) {
192 E e = section.get(j);
193 if (e.equals(entry)) {
194 position += j;
195 return position;
196 }
197 }
198 position += sectionSize;
199 }
200 return -1;
201 }
202
203 /**
204 * @see android.widget.ListAdapter#getCount()
205 */
206 public final int getCount() {
207 return countEntries(mSections, mSeparators);
208 }
209
210 /**
211 * @see android.widget.ListAdapter#hasSeparators()
212 */
213 @Override
214 public final boolean areAllItemsEnabled() {
215 return mSeparators == false;
216 }
217
218 /**
219 * @see android.widget.ListAdapter#isSeparator(int)
220 */
221 @Override
222 public final boolean isEnabled(int position) {
223 if (!mSeparators) {
224 return true;
225 }
226
227 int numSections = mSections.size();
228 for (int i = 0; i < numSections; i++) {
229 ArrayList<E> section = mSections.get(i);
230 int sectionSize = section.size();
231 if (sectionSize == 1) {
232 // The section only contains a separator and nothing else, skip it
233 continue;
234 }
235 if (position == 0) {
236 // The first item in a section is always the separator
237 return false;
238 }
239 position -= sectionSize;
240 }
241 return true;
242 }
243
244 /**
245 * @see android.widget.ListAdapter#getItem(int)
246 */
247 public final Object getItem(int position) {
248 return getEntry(mSections, position, mSeparators);
249 }
250
251 /**
252 * Get the entry for the given position.
253 *
254 * @param sections the list of sections
255 * @param position the position for the desired entry
256 * @return the ContactEntry for the given position
257 */
258 public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
259 int position, boolean separators) {
260 int numSections = sections.size();
261 for (int i = 0; i < numSections; i++) {
262 ArrayList<T> section = sections.get(i);
263 int sectionSize = section.size();
264 if (separators && sectionSize == 1) {
265 // The section only contains a separator and nothing else, skip it
266 continue;
267 }
268 if (position < section.size()) {
269 return section.get(position);
270 }
271 position -= section.size();
272 }
273 return null;
274 }
275
276 /**
277 * Get the count of entries in all sections
278 *
279 * @param sections the list of sections
280 * @return the count of entries in all sections
281 */
282 public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
283 boolean separators) {
284 int count = 0;
285 int numSections = sections.size();
286 for (int i = 0; i < numSections; i++) {
287 ArrayList<T> section = sections.get(i);
288 int sectionSize = section.size();
289 if (separators && sectionSize == 1) {
290 // The section only contains a separator and nothing else, skip it
291 continue;
292 }
293 count += sections.get(i).size();
294 }
295 return count;
296 }
297
298 /**
299 * @see android.widget.ListAdapter#getItemId(int)
300 */
301 public final long getItemId(int position) {
302 Entry entry = getEntry(mSections, position, mSeparators);
303 if (entry != null) {
304 return entry.id;
305 } else {
306 return -1;
307 }
308 }
309
310 /**
311 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
312 */
313 public View getView(int position, View convertView, ViewGroup parent) {
314 View v;
315 if (convertView == null) {
316 v = newView(position, parent);
317 } else {
318 v = convertView;
319 }
320 bindView(v, getEntry(mSections, position, mSeparators));
321 return v;
322 }
323
324 /**
325 * Create a new view for an entry.
326 *
327 * @parent the parent ViewGroup
328 * @return the newly created view
329 */
330 protected abstract View newView(int position, ViewGroup parent);
331
332 /**
333 * Binds the data from an entry to a view.
334 *
335 * @param view the view to display the entry in
336 * @param entry the data to bind
337 */
338 protected abstract void bindView(View view, E entry);
339}