blob: 1f70c050baccecd200d7d0175b8b4630c9cd9dd1 [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
Alexandre Lision35c3cbb2013-11-04 17:11:54 -0500101 if(item.hasPhoto()){
102 entryView.photo.setImageBitmap(item.getPhoto());
103 } else {
104 infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item));
105 }
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400106
107 entryView.quick_call.setOnClickListener(new OnClickListener() {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400108
109 @Override
110 public void onClick(View v) {
111 parent.get().mCallbacks.onCallContact(item);
112
113 }
114 });
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400115
Alexandre Lisione168d4a2013-10-24 12:32:59 -0400116 entryView.quick_msg.setOnClickListener(new OnClickListener() {
117
118 @Override
119 public void onClick(View v) {
120 parent.get().mCallbacks.onTextContact(item);
121 }
122 });
123
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400124 entryView.quick_starred.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400125
126 @Override
127 public void onClick(View v) {
128 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
129 }
130 });
131
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400132 entryView.quick_edit.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400133
134 @Override
135 public void onClick(View v) {
136 parent.get().mCallbacks.onEditContact(item);
137
138 }
139 });
140
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400141 entryView.quick_discard.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400142
143 @Override
144 public void onClick(View v) {
145 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
146
147 }
148 });
149
Alexandre Lisione168d4a2013-10-24 12:32:59 -0400150 entryView.quick_edit.setClickable(false);
151 entryView.quick_discard.setClickable(false);
152 entryView.quick_starred.setClickable(false);
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400153
alisionf7053602013-07-09 10:25:20 -0400154 return convertView;
alisiond295ec22013-05-17 10:12:13 -0400155 }
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400156
157 /*********************
158 * ViewHolder Pattern
159 *********************/
160 public class ContactView {
161 ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg;
162 ImageView photo;
163 TextView display_name;
164 }
alisiond295ec22013-05-17 10:12:13 -0400165
166 @Override
167 public int getCount() {
alisionf7053602013-07-09 10:25:20 -0400168 return headers.size() + headers.getSections().size();
169 }
170
171 @Override
172 public int getItemViewType(int pos) {
173 return (headers.contains(pos) ? TYPE_HEADER : TYPE_TRACK);
174 }
175
176 @Override
177 public int getViewTypeCount() {
178 return 2;
179 }
180
alisionf7053602013-07-09 10:25:20 -0400181 @Override
182 public long getItemId(int position) {
183 return 0;
184 }
185
186 public void removeAll() {
187 headers.clear();
188 notifyDataSetChanged();
189 }
190
191 public void add(CallContact tr) {
192 headers.add(tr);
193 headers.buildIndex();
194 }
195
196 public void addAll(ArrayList<CallContact> tr) {
197 headers = new HeadersHolder(tr);
198 notifyDataSetChanged();
199 }
200
alisionf7053602013-07-09 10:25:20 -0400201 @Override
202 public int getPositionForSection(int section) {
203 return headers.getPositionFor(section);
204 }
205
206 @Override
207 public int getSectionForPosition(int position) {
208 return headers.getSectionFor(position);
209 }
210
211 @Override
212 public Object[] getSections() {
213 return headers.getSectionsArray();
214 }
215
216 public int getRealPosition(int pos) {
217 return headers.getTrackPosition(pos);
alisiond295ec22013-05-17 10:12:13 -0400218 }
219
220 @Override
221 public CallContact getItem(int index) {
alisionf7053602013-07-09 10:25:20 -0400222 return headers.getCallContact(index);
alisiond295ec22013-05-17 10:12:13 -0400223 }
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400224
alisionf7053602013-07-09 10:25:20 -0400225 public class HeadersHolder {
alisiond295ec22013-05-17 10:12:13 -0400226
alisionf7053602013-07-09 10:25:20 -0400227 public static final String TAG = "HeadersHolder";
228 HashMap<String, Integer> alphaIndexer;
229 ArrayList<CallContact> contacts;
alisiond295ec22013-05-17 10:12:13 -0400230
alisionf7053602013-07-09 10:25:20 -0400231 String[] sectionsArray;
alisiond295ec22013-05-17 10:12:13 -0400232
alisionf7053602013-07-09 10:25:20 -0400233 public String[] getSectionsArray() {
234 return sectionsArray;
alisiond295ec22013-05-17 10:12:13 -0400235 }
236
alisionf7053602013-07-09 10:25:20 -0400237 int headersCount;
238 private SparseArray<Item> items = new SparseArray<Item>();
alisiond295ec22013-05-17 10:12:13 -0400239
alisionf7053602013-07-09 10:25:20 -0400240 public SparseArray<Item> getItems() {
241 return items;
242 }
alisiond295ec22013-05-17 10:12:13 -0400243
alisionf7053602013-07-09 10:25:20 -0400244 public void setItems(SparseArray<Item> items) {
245 this.items = items;
246 }
alisiond295ec22013-05-17 10:12:13 -0400247
alisionf7053602013-07-09 10:25:20 -0400248 public SparseArray<Section> getSections() {
249 return sections;
250 }
251
252 public void setSections(SparseArray<Section> sections) {
253 this.sections = sections;
254 }
255
256 private SparseArray<Section> sections = new SparseArray<Section>();
257
258 public HeadersHolder(ArrayList<CallContact> a) {
259 alphaIndexer = new HashMap<String, Integer>();
260 contacts = a;
261 headersCount = 0;
262 buildIndex();
263 }
264
265 // public int getHeadersCount() {
266 // return headersCount;
267 // }
268
269 private class Item {
270 public Item(int rpos, int headersCount2, CallContact track) {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400271 // Log.i(TAG, "Creating Item");
alisionf7053602013-07-09 10:25:20 -0400272
273 sectionNumber = headersCount2;
274 realPos = rpos;
275 tr = track;
276
277 }
278
279 public int realPos;
280 public int sectionNumber;
281 public CallContact tr;
282 }
283
284 private class Section {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400285 // public int startPosition;
alisionf7053602013-07-09 10:25:20 -0400286 public int number;
287 public String header;
288
289 public Section(int i, int headersCount, String str) {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400290 // Log.i(TAG, "Creating section");
alisionf7053602013-07-09 10:25:20 -0400291
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400292 // startPosition = i + headersCount;
alisionf7053602013-07-09 10:25:20 -0400293 number = headersCount;
294 header = str;
295
296 }
297
298 @Override
299 public String toString() {
300 return header;
301 }
302 }
303
304 public void buildIndex() {
305
306 for (int x = 0; x < contacts.size(); x++) {
307 String s = contacts.get(x).getmDisplayName();
308 String ch = s.substring(0, 1);
309 ch = ch.toUpperCase(Locale.CANADA);
310 if (!alphaIndexer.containsKey(ch)) {
311 sections.put(x + headersCount, new Section(x, headersCount, ch));
312 headersCount++;
313 }
314 Integer result = alphaIndexer.put(ch, x + headersCount);
315 items.put(x + headersCount, new Item(x, headersCount, contacts.get(x)));
316 if (result == null) {
317
318 }
319 }
320
321 Set<String> sect = alphaIndexer.keySet();
322
323 // create a list from the set to sort
324 ArrayList<String> sectionList = new ArrayList<String>(sect);
325 Collections.sort(sectionList);
326 sectionsArray = new String[sectionList.size()];
327 sectionList.toArray(sectionsArray);
328
329 }
330
331 public HashMap<String, Integer> getAlphaIndexer() {
332 return alphaIndexer;
333 }
334
335 public int getPositionFor(int section) {
336 if (section == sectionsArray.length)
337 return sectionsArray.length;
338 return alphaIndexer.get(sectionsArray[section]);
339 }
340
341 public int getSectionFor(int position) {
342 return (null != items.get(position)) ? items.get(position).sectionNumber : sections.get(position).number;
343 }
344
345 public boolean contains(int pos) {
346 if (sections.get(pos) != null) {
347 return true;
348 }
349 return false;
350 }
351
352 public CallContact getCallContact(int position) {
353
354 if (items.get(position) == null)
355 return null;
356
357 return items.get(position).tr;
358
359 }
360
361 public int size() {
362 return contacts.size();
363 }
364
365 public void clear() {
366 contacts.clear();
367
368 }
369
370 public void add(CallContact tr) {
371 contacts.add(tr);
372
373 }
374
375 public void addAll(ArrayList<CallContact> tr) {
376 contacts.clear();
377 contacts.addAll(tr);
378
379 }
380
381 public ArrayList<CallContact> getTracks() {
382 return contacts;
383 }
384
385 public int getTrackPosition(int pos) {
386 if (sections.get(pos) != null) {
387 return items.get(pos + 1).realPos;
388 }
389 return items.get(pos).realPos;
390 }
391
392 public CharSequence getSection(int position) {
393 return sections.get(position).header;
394 }
395
alisiond295ec22013-05-17 10:12:13 -0400396 }
397
398}