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