blob: 57ab39a803a8d4c37ac954d04ee9b4a1b96a4669 [file] [log] [blame]
Alexandre Lision064e1e02013-10-01 16:18:42 -04001package org.sflphone.adapters;
alisiond295ec22013-05-17 10:12:13 -04002
Alexandre Lisione1c96db2013-10-04 14:34:21 -04003import java.lang.ref.WeakReference;
alisiond295ec22013-05-17 10:12:13 -04004import java.util.ArrayList;
alisionf7053602013-07-09 10:25:20 -04005import java.util.Collections;
6import java.util.HashMap;
7import java.util.Locale;
8import java.util.Set;
alisiond295ec22013-05-17 10:12:13 -04009import java.util.concurrent.ExecutorService;
10import java.util.concurrent.Executors;
11
Alexandre Lisione1c96db2013-10-04 14:34:21 -040012import org.sflphone.R;
13import org.sflphone.fragments.ContactListFragment;
Alexandre Lision064e1e02013-10-01 16:18:42 -040014import org.sflphone.model.CallContact;
15
alisiond295ec22013-05-17 10:12:13 -040016import android.content.Context;
alisionf7053602013-07-09 10:25:20 -040017import android.util.SparseArray;
alisiond295ec22013-05-17 10:12:13 -040018import android.view.LayoutInflater;
19import android.view.View;
Alexandre Lisione1c96db2013-10-04 14:34:21 -040020import android.view.View.OnClickListener;
alisiond295ec22013-05-17 10:12:13 -040021import android.view.ViewGroup;
22import android.widget.BaseAdapter;
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040023import android.widget.ImageButton;
alisiond295ec22013-05-17 10:12:13 -040024import android.widget.ImageView;
alisionf7053602013-07-09 10:25:20 -040025import android.widget.SectionIndexer;
alisiond295ec22013-05-17 10:12:13 -040026import android.widget.TextView;
Alexandre Lisionc59685a2013-10-04 16:36:36 -040027import android.widget.Toast;
alisiond295ec22013-05-17 10:12:13 -040028
alisionf7053602013-07-09 10:25:20 -040029public class ContactsAdapter extends BaseAdapter implements SectionIndexer {
alisiond295ec22013-05-17 10:12:13 -040030
31 private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
alisiond295ec22013-05-17 10:12:13 -040032 Context mContext;
33
alisionf7053602013-07-09 10:25:20 -040034 HashMap<String, Integer> alphaIndexer;
35 String[] sections;
Alexandre Lisione1c96db2013-10-04 14:34:21 -040036 WeakReference<ContactListFragment> parent;
alisionf7053602013-07-09 10:25:20 -040037
Alexandre Lisione1c96db2013-10-04 14:34:21 -040038 // private static final String TAG = ContactsAdapter.class.getSimpleName();
alisiond295ec22013-05-17 10:12:13 -040039
Alexandre Lisione1c96db2013-10-04 14:34:21 -040040 public ContactsAdapter(ContactListFragment contactListFragment) {
alisiond295ec22013-05-17 10:12:13 -040041 super();
Alexandre Lisione1c96db2013-10-04 14:34:21 -040042 mContext = contactListFragment.getActivity();
alisionf7053602013-07-09 10:25:20 -040043 alphaIndexer = new HashMap<String, Integer>();
44 headers = new HeadersHolder(new ArrayList<CallContact>());
Alexandre Lisione1c96db2013-10-04 14:34:21 -040045 parent = new WeakReference<ContactListFragment>(contactListFragment);
alisiond295ec22013-05-17 10:12:13 -040046 }
47
alisionf7053602013-07-09 10:25:20 -040048 HeadersHolder headers;
49 private static final int TYPE_HEADER = 0;
50 private static final int TYPE_TRACK = 1;
51
52 @Override
53 public View getView(int position, View convertView, ViewGroup parent) {
54 int type = getItemViewType(position);
55
Alexandre Lisione1c96db2013-10-04 14:34:21 -040056 // Log.i(TAG, "positon" + position + " type " + type);
alisionf7053602013-07-09 10:25:20 -040057 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
58
59 switch (type) {
60 case TYPE_TRACK:
Alexandre Lisione1c96db2013-10-04 14:34:21 -040061 return getViewContact(position, inflater, convertView);
alisionf7053602013-07-09 10:25:20 -040062 case TYPE_HEADER:
63 return getViewHeader(position, inflater, convertView);
64 }
65 return null;
alisiond295ec22013-05-17 10:12:13 -040066 }
67
alisionf7053602013-07-09 10:25:20 -040068 private View getViewHeader(int position, LayoutInflater inflater, View convertView) {
69 if (convertView == null) {
70 convertView = inflater.inflate(R.layout.header, null);
71 }
72 TextView name = (TextView) convertView.findViewById(R.id.header_letter);
73 name.setText(headers.getSection(position));
74 return convertView;
75 }
76
Alexandre Lisione1c96db2013-10-04 14:34:21 -040077 private View getViewContact(int position, LayoutInflater inflater, View convertView) {
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040078 ContactView entryView;
79
alisionf7053602013-07-09 10:25:20 -040080 if (convertView == null) {
81 convertView = inflater.inflate(R.layout.item_contact, null);
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040082
83 entryView = new ContactView();
84 entryView.quick_starred = (ImageButton) convertView.findViewById(R.id.quick_starred);
85 entryView.quick_edit = (ImageButton) convertView.findViewById(R.id.quick_edit);
86 entryView.quick_discard = (ImageButton) convertView.findViewById(R.id.quick_discard);
87 entryView.quick_call = (ImageButton) convertView.findViewById(R.id.quick_call);
88 entryView.quick_msg = (ImageButton) convertView.findViewById(R.id.quick_message);
89 entryView.photo = (ImageView) convertView.findViewById(R.id.photo);
90 entryView.display_name = (TextView) convertView.findViewById(R.id.display_name);
91 convertView.setTag(entryView);
92 } else {
93 entryView = (ContactView) convertView.getTag();
alisionf7053602013-07-09 10:25:20 -040094 }
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040095
alisionf7053602013-07-09 10:25:20 -040096
Alexandre Lisione1c96db2013-10-04 14:34:21 -040097 final CallContact item = headers.getCallContact(position);
alisionf7053602013-07-09 10:25:20 -040098
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040099 entryView.display_name.setText(item.getmDisplayName());
alisionf7053602013-07-09 10:25:20 -0400100
alisionf7053602013-07-09 10:25:20 -0400101
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400102 infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item.getId()));
103
104 entryView.quick_call.setOnClickListener(new OnClickListener() {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400105
106 @Override
107 public void onClick(View v) {
108 parent.get().mCallbacks.onCallContact(item);
109
110 }
111 });
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400112
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400113 entryView.quick_starred.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400114
115 @Override
116 public void onClick(View v) {
117 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
118 }
119 });
120
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400121 entryView.quick_edit.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400122
123 @Override
124 public void onClick(View v) {
125 parent.get().mCallbacks.onEditContact(item);
126
127 }
128 });
129
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400130 entryView.quick_discard.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400131
132 @Override
133 public void onClick(View v) {
134 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
135
136 }
137 });
138
139
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400140
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400141 entryView.quick_msg.setOnClickListener(new OnClickListener() {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400142
143 @Override
144 public void onClick(View v) {
145 parent.get().mCallbacks.onTextContact(item);
146 }
147 });
148
alisionf7053602013-07-09 10:25:20 -0400149 return convertView;
alisiond295ec22013-05-17 10:12:13 -0400150 }
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400151
152 /*********************
153 * ViewHolder Pattern
154 *********************/
155 public class ContactView {
156 ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg;
157 ImageView photo;
158 TextView display_name;
159 }
alisiond295ec22013-05-17 10:12:13 -0400160
161 @Override
162 public int getCount() {
alisionf7053602013-07-09 10:25:20 -0400163 return headers.size() + headers.getSections().size();
164 }
165
166 @Override
167 public int getItemViewType(int pos) {
168 return (headers.contains(pos) ? TYPE_HEADER : TYPE_TRACK);
169 }
170
171 @Override
172 public int getViewTypeCount() {
173 return 2;
174 }
175
alisionf7053602013-07-09 10:25:20 -0400176 @Override
177 public long getItemId(int position) {
178 return 0;
179 }
180
181 public void removeAll() {
182 headers.clear();
183 notifyDataSetChanged();
184 }
185
186 public void add(CallContact tr) {
187 headers.add(tr);
188 headers.buildIndex();
189 }
190
191 public void addAll(ArrayList<CallContact> tr) {
192 headers = new HeadersHolder(tr);
193 notifyDataSetChanged();
194 }
195
alisionf7053602013-07-09 10:25:20 -0400196 @Override
197 public int getPositionForSection(int section) {
198 return headers.getPositionFor(section);
199 }
200
201 @Override
202 public int getSectionForPosition(int position) {
203 return headers.getSectionFor(position);
204 }
205
206 @Override
207 public Object[] getSections() {
208 return headers.getSectionsArray();
209 }
210
211 public int getRealPosition(int pos) {
212 return headers.getTrackPosition(pos);
alisiond295ec22013-05-17 10:12:13 -0400213 }
214
215 @Override
216 public CallContact getItem(int index) {
alisionf7053602013-07-09 10:25:20 -0400217 return headers.getCallContact(index);
alisiond295ec22013-05-17 10:12:13 -0400218 }
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400219
alisionf7053602013-07-09 10:25:20 -0400220 public class HeadersHolder {
alisiond295ec22013-05-17 10:12:13 -0400221
alisionf7053602013-07-09 10:25:20 -0400222 public static final String TAG = "HeadersHolder";
223 HashMap<String, Integer> alphaIndexer;
224 ArrayList<CallContact> contacts;
alisiond295ec22013-05-17 10:12:13 -0400225
alisionf7053602013-07-09 10:25:20 -0400226 String[] sectionsArray;
alisiond295ec22013-05-17 10:12:13 -0400227
alisionf7053602013-07-09 10:25:20 -0400228 public String[] getSectionsArray() {
229 return sectionsArray;
alisiond295ec22013-05-17 10:12:13 -0400230 }
231
alisionf7053602013-07-09 10:25:20 -0400232 int headersCount;
233 private SparseArray<Item> items = new SparseArray<Item>();
alisiond295ec22013-05-17 10:12:13 -0400234
alisionf7053602013-07-09 10:25:20 -0400235 public SparseArray<Item> getItems() {
236 return items;
237 }
alisiond295ec22013-05-17 10:12:13 -0400238
alisionf7053602013-07-09 10:25:20 -0400239 public void setItems(SparseArray<Item> items) {
240 this.items = items;
241 }
alisiond295ec22013-05-17 10:12:13 -0400242
alisionf7053602013-07-09 10:25:20 -0400243 public SparseArray<Section> getSections() {
244 return sections;
245 }
246
247 public void setSections(SparseArray<Section> sections) {
248 this.sections = sections;
249 }
250
251 private SparseArray<Section> sections = new SparseArray<Section>();
252
253 public HeadersHolder(ArrayList<CallContact> a) {
254 alphaIndexer = new HashMap<String, Integer>();
255 contacts = a;
256 headersCount = 0;
257 buildIndex();
258 }
259
260 // public int getHeadersCount() {
261 // return headersCount;
262 // }
263
264 private class Item {
265 public Item(int rpos, int headersCount2, CallContact track) {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400266 // Log.i(TAG, "Creating Item");
alisionf7053602013-07-09 10:25:20 -0400267
268 sectionNumber = headersCount2;
269 realPos = rpos;
270 tr = track;
271
272 }
273
274 public int realPos;
275 public int sectionNumber;
276 public CallContact tr;
277 }
278
279 private class Section {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400280 // public int startPosition;
alisionf7053602013-07-09 10:25:20 -0400281 public int number;
282 public String header;
283
284 public Section(int i, int headersCount, String str) {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400285 // Log.i(TAG, "Creating section");
alisionf7053602013-07-09 10:25:20 -0400286
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400287 // startPosition = i + headersCount;
alisionf7053602013-07-09 10:25:20 -0400288 number = headersCount;
289 header = str;
290
291 }
292
293 @Override
294 public String toString() {
295 return header;
296 }
297 }
298
299 public void buildIndex() {
300
301 for (int x = 0; x < contacts.size(); x++) {
302 String s = contacts.get(x).getmDisplayName();
303 String ch = s.substring(0, 1);
304 ch = ch.toUpperCase(Locale.CANADA);
305 if (!alphaIndexer.containsKey(ch)) {
306 sections.put(x + headersCount, new Section(x, headersCount, ch));
307 headersCount++;
308 }
309 Integer result = alphaIndexer.put(ch, x + headersCount);
310 items.put(x + headersCount, new Item(x, headersCount, contacts.get(x)));
311 if (result == null) {
312
313 }
314 }
315
316 Set<String> sect = alphaIndexer.keySet();
317
318 // create a list from the set to sort
319 ArrayList<String> sectionList = new ArrayList<String>(sect);
320 Collections.sort(sectionList);
321 sectionsArray = new String[sectionList.size()];
322 sectionList.toArray(sectionsArray);
323
324 }
325
326 public HashMap<String, Integer> getAlphaIndexer() {
327 return alphaIndexer;
328 }
329
330 public int getPositionFor(int section) {
331 if (section == sectionsArray.length)
332 return sectionsArray.length;
333 return alphaIndexer.get(sectionsArray[section]);
334 }
335
336 public int getSectionFor(int position) {
337 return (null != items.get(position)) ? items.get(position).sectionNumber : sections.get(position).number;
338 }
339
340 public boolean contains(int pos) {
341 if (sections.get(pos) != null) {
342 return true;
343 }
344 return false;
345 }
346
347 public CallContact getCallContact(int position) {
348
349 if (items.get(position) == null)
350 return null;
351
352 return items.get(position).tr;
353
354 }
355
356 public int size() {
357 return contacts.size();
358 }
359
360 public void clear() {
361 contacts.clear();
362
363 }
364
365 public void add(CallContact tr) {
366 contacts.add(tr);
367
368 }
369
370 public void addAll(ArrayList<CallContact> tr) {
371 contacts.clear();
372 contacts.addAll(tr);
373
374 }
375
376 public ArrayList<CallContact> getTracks() {
377 return contacts;
378 }
379
380 public int getTrackPosition(int pos) {
381 if (sections.get(pos) != null) {
382 return items.get(pos + 1).realPos;
383 }
384 return items.get(pos).realPos;
385 }
386
387 public CharSequence getSection(int position) {
388 return sections.get(position).header;
389 }
390
alisiond295ec22013-05-17 10:12:13 -0400391 }
392
393}