blob: ab47b5c0d6f18a0acd065aed3588ccb1e12156c1 [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;
Evan Millar66388be2009-05-28 15:41:07 -070022import android.provider.ContactsContract.Aggregates;
23import android.provider.ContactsContract.Data;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080024import 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
Evan Millar66388be2009-05-28 15:41:07 -070034 public static final String[] AGGREGATE_PROJECTION = new String[] {
35 Aggregates.DISPLAY_NAME, // 0
36 Aggregates.STARRED, //1
37 Data._ID, // 2
38 Data.PACKAGE, //3
39 Data.MIMETYPE, //4
Evan Millar45e0ed32009-06-01 16:44:38 -070040 Data.IS_PRIMARY, //5
41 Data.IS_SUPER_PRIMARY, //6
42 Data.DATA1, //7
43 Data.DATA2, //8
44 Data.DATA3, //9
45 Data.DATA4, //10
46 Data.DATA5, //11
47 Data.DATA6, //12
48 Data.DATA7, //13
49 Data.DATA8, //14
50 Data.DATA9, //15
51 Data.DATA10, //16
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080052 };
Evan Millar66388be2009-05-28 15:41:07 -070053 public static final int AGGREGATE_DISPLAY_NAME_COLUMN = 0;
54 public static final int AGGREGATE_STARRED_COLUMN = 1;
55 public static final int DATA_ID_COLUMN = 2;
56 public static final int DATA_PACKAGE_COLUMN = 3;
57 public static final int DATA_MIMETYPE_COLUMN = 4;
Evan Millar45e0ed32009-06-01 16:44:38 -070058 public static final int DATA_IS_PRIMARY_COLUMN = 5;
59 public static final int DATA_IS_SUPER_PRIMARY_COLUMN = 6;
60 public static final int DATA_1_COLUMN = 7;
61 public static final int DATA_2_COLUMN = 8;
62 public static final int DATA_3_COLUMN = 9;
63 public static final int DATA_4_COLUMN = 10;
64 public static final int DATA_5_COLUMN = 11;
65 public static final int DATA_6_COLUMN = 12;
66 public static final int DATA_7_COLUMN = 13;
67 public static final int DATA_8_COLUMN = 14;
68 public static final int DATA_9_COLUMN = 15;
69 public static final int DATA_10_COLUMN = 16;
70
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080071 protected ArrayList<ArrayList<E>> mSections;
72 protected LayoutInflater mInflater;
73 protected Context mContext;
74 protected boolean mSeparators;
75
76 /**
77 * Base class for adapter entries.
78 */
79 public static class Entry {
80 /** Details from the person table */
81 public static final int KIND_CONTACT = -1;
82 /** Synthesized phone entry that will send an SMS instead of call the number */
83 public static final int KIND_SMS = -2;
84 /** A section separator */
The Android Open Source Projectcac191e2009-03-18 22:20:27 -070085 public static final int KIND_SEPARATOR = -3;
86 /** Signifies a group row that is stored in the group membership table */
87 public static final int KIND_GROUP = -4;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080088
89 public String label;
90 public String data;
91 public Uri uri;
92 public long id = 0;
93 public int maxLines = 1;
Evan Millar45e0ed32009-06-01 16:44:38 -070094 // TODO(emillar): remove "kind" completely once it is removed from EditContactActivity
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080095 public int kind;
Evan Millar45e0ed32009-06-01 16:44:38 -070096 public String mimetype;
97
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080098 /**
99 * Helper for making subclasses parcelable.
100 */
101 protected void writeToParcel(Parcel p) {
102 p.writeString(label);
103 p.writeString(data);
104 p.writeParcelable(uri, 0);
105 p.writeLong(id);
106 p.writeInt(maxLines);
Evan Millar45e0ed32009-06-01 16:44:38 -0700107 p.writeString(mimetype);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800108 }
Evan Millar45e0ed32009-06-01 16:44:38 -0700109
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800110 /**
111 * Helper for making subclasses parcelable.
112 */
113 protected void readFromParcel(Parcel p) {
114 label = p.readString();
115 data = p.readString();
116 uri = p.readParcelable(null);
117 id = p.readLong();
118 maxLines = p.readInt();
Evan Millar45e0ed32009-06-01 16:44:38 -0700119 mimetype = p.readString();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800120 }
121 }
122
123 ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
124 mContext = context;
125 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
126 mSections = sections;
127 mSeparators = separators;
128 }
129
130 /**
131 * Resets the section data.
Evan Millar45e0ed32009-06-01 16:44:38 -0700132 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800133 * @param sections the section data
134 */
135 public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
136 mSections = sections;
137 mSeparators = separators;
138 notifyDataSetChanged();
139 }
140
141 /**
142 * Resets the section data and returns the position of the given entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700143 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800144 * @param sections the section data
145 * @param entry the entry to return the position for
146 * @return the position of entry, or -1 if it isn't found
147 */
148 public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
149 mSections = sections;
150 notifyDataSetChanged();
151
152 int numSections = mSections.size();
153 int position = 0;
154 for (int i = 0; i < numSections; i++) {
155 ArrayList<E> section = mSections.get(i);
156 int sectionSize = section.size();
157 for (int j = 0; j < sectionSize; j++) {
158 E e = section.get(j);
159 if (e.equals(entry)) {
160 position += j;
161 return position;
162 }
163 }
164 position += sectionSize;
165 }
166 return -1;
167 }
168
169 /**
170 * @see android.widget.ListAdapter#getCount()
171 */
172 public final int getCount() {
173 return countEntries(mSections, mSeparators);
174 }
175
176 /**
177 * @see android.widget.ListAdapter#hasSeparators()
178 */
179 @Override
180 public final boolean areAllItemsEnabled() {
181 return mSeparators == false;
182 }
183
184 /**
185 * @see android.widget.ListAdapter#isSeparator(int)
186 */
187 @Override
188 public final boolean isEnabled(int position) {
189 if (!mSeparators) {
190 return true;
191 }
192
193 int numSections = mSections.size();
194 for (int i = 0; i < numSections; i++) {
195 ArrayList<E> section = mSections.get(i);
196 int sectionSize = section.size();
197 if (sectionSize == 1) {
198 // The section only contains a separator and nothing else, skip it
199 continue;
200 }
201 if (position == 0) {
202 // The first item in a section is always the separator
203 return false;
204 }
205 position -= sectionSize;
206 }
207 return true;
208 }
209
210 /**
211 * @see android.widget.ListAdapter#getItem(int)
212 */
213 public final Object getItem(int position) {
214 return getEntry(mSections, position, mSeparators);
215 }
216
217 /**
218 * Get the entry for the given position.
Evan Millar45e0ed32009-06-01 16:44:38 -0700219 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800220 * @param sections the list of sections
221 * @param position the position for the desired entry
222 * @return the ContactEntry for the given position
223 */
224 public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
225 int position, boolean separators) {
226 int numSections = sections.size();
227 for (int i = 0; i < numSections; i++) {
228 ArrayList<T> section = sections.get(i);
229 int sectionSize = section.size();
230 if (separators && sectionSize == 1) {
231 // The section only contains a separator and nothing else, skip it
232 continue;
233 }
234 if (position < section.size()) {
235 return section.get(position);
236 }
237 position -= section.size();
238 }
239 return null;
240 }
241
242 /**
243 * Get the count of entries in all sections
Evan Millar45e0ed32009-06-01 16:44:38 -0700244 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800245 * @param sections the list of sections
246 * @return the count of entries in all sections
247 */
248 public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
249 boolean separators) {
250 int count = 0;
251 int numSections = sections.size();
252 for (int i = 0; i < numSections; i++) {
253 ArrayList<T> section = sections.get(i);
254 int sectionSize = section.size();
255 if (separators && sectionSize == 1) {
256 // The section only contains a separator and nothing else, skip it
257 continue;
258 }
259 count += sections.get(i).size();
260 }
261 return count;
262 }
263
264 /**
265 * @see android.widget.ListAdapter#getItemId(int)
266 */
267 public final long getItemId(int position) {
268 Entry entry = getEntry(mSections, position, mSeparators);
269 if (entry != null) {
270 return entry.id;
271 } else {
272 return -1;
273 }
274 }
275
276 /**
277 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
278 */
279 public View getView(int position, View convertView, ViewGroup parent) {
280 View v;
281 if (convertView == null) {
282 v = newView(position, parent);
283 } else {
284 v = convertView;
285 }
286 bindView(v, getEntry(mSections, position, mSeparators));
287 return v;
288 }
289
290 /**
291 * Create a new view for an entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700292 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800293 * @parent the parent ViewGroup
294 * @return the newly created view
295 */
296 protected abstract View newView(int position, ViewGroup parent);
297
298 /**
299 * Binds the data from an entry to a view.
Evan Millar45e0ed32009-06-01 16:44:38 -0700300 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800301 * @param view the view to display the entry in
302 * @param entry the data to bind
303 */
304 protected abstract void bindView(View view, E entry);
305}