blob: 83492f9bddfb34d19e4127bef37033786fe28974 [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 Lisione168d4a2013-10-24 12:32:59 -0400113 entryView.quick_msg.setOnClickListener(new OnClickListener() {
114
115 @Override
116 public void onClick(View v) {
117 parent.get().mCallbacks.onTextContact(item);
118 }
119 });
120
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400121 entryView.quick_starred.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400122
123 @Override
124 public void onClick(View v) {
125 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
126 }
127 });
128
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400129 entryView.quick_edit.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400130
131 @Override
132 public void onClick(View v) {
133 parent.get().mCallbacks.onEditContact(item);
134
135 }
136 });
137
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400138 entryView.quick_discard.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400139
140 @Override
141 public void onClick(View v) {
142 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
143
144 }
145 });
146
Alexandre Lisione168d4a2013-10-24 12:32:59 -0400147 entryView.quick_edit.setClickable(false);
148 entryView.quick_discard.setClickable(false);
149 entryView.quick_starred.setClickable(false);
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400150
alisionf7053602013-07-09 10:25:20 -0400151 return convertView;
alisiond295ec22013-05-17 10:12:13 -0400152 }
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400153
154 /*********************
155 * ViewHolder Pattern
156 *********************/
157 public class ContactView {
158 ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg;
159 ImageView photo;
160 TextView display_name;
161 }
alisiond295ec22013-05-17 10:12:13 -0400162
163 @Override
164 public int getCount() {
alisionf7053602013-07-09 10:25:20 -0400165 return headers.size() + headers.getSections().size();
166 }
167
168 @Override
169 public int getItemViewType(int pos) {
170 return (headers.contains(pos) ? TYPE_HEADER : TYPE_TRACK);
171 }
172
173 @Override
174 public int getViewTypeCount() {
175 return 2;
176 }
177
alisionf7053602013-07-09 10:25:20 -0400178 @Override
179 public long getItemId(int position) {
180 return 0;
181 }
182
183 public void removeAll() {
184 headers.clear();
185 notifyDataSetChanged();
186 }
187
188 public void add(CallContact tr) {
189 headers.add(tr);
190 headers.buildIndex();
191 }
192
193 public void addAll(ArrayList<CallContact> tr) {
194 headers = new HeadersHolder(tr);
195 notifyDataSetChanged();
196 }
197
alisionf7053602013-07-09 10:25:20 -0400198 @Override
199 public int getPositionForSection(int section) {
200 return headers.getPositionFor(section);
201 }
202
203 @Override
204 public int getSectionForPosition(int position) {
205 return headers.getSectionFor(position);
206 }
207
208 @Override
209 public Object[] getSections() {
210 return headers.getSectionsArray();
211 }
212
213 public int getRealPosition(int pos) {
214 return headers.getTrackPosition(pos);
alisiond295ec22013-05-17 10:12:13 -0400215 }
216
217 @Override
218 public CallContact getItem(int index) {
alisionf7053602013-07-09 10:25:20 -0400219 return headers.getCallContact(index);
alisiond295ec22013-05-17 10:12:13 -0400220 }
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400221
alisionf7053602013-07-09 10:25:20 -0400222 public class HeadersHolder {
alisiond295ec22013-05-17 10:12:13 -0400223
alisionf7053602013-07-09 10:25:20 -0400224 public static final String TAG = "HeadersHolder";
225 HashMap<String, Integer> alphaIndexer;
226 ArrayList<CallContact> contacts;
alisiond295ec22013-05-17 10:12:13 -0400227
alisionf7053602013-07-09 10:25:20 -0400228 String[] sectionsArray;
alisiond295ec22013-05-17 10:12:13 -0400229
alisionf7053602013-07-09 10:25:20 -0400230 public String[] getSectionsArray() {
231 return sectionsArray;
alisiond295ec22013-05-17 10:12:13 -0400232 }
233
alisionf7053602013-07-09 10:25:20 -0400234 int headersCount;
235 private SparseArray<Item> items = new SparseArray<Item>();
alisiond295ec22013-05-17 10:12:13 -0400236
alisionf7053602013-07-09 10:25:20 -0400237 public SparseArray<Item> getItems() {
238 return items;
239 }
alisiond295ec22013-05-17 10:12:13 -0400240
alisionf7053602013-07-09 10:25:20 -0400241 public void setItems(SparseArray<Item> items) {
242 this.items = items;
243 }
alisiond295ec22013-05-17 10:12:13 -0400244
alisionf7053602013-07-09 10:25:20 -0400245 public SparseArray<Section> getSections() {
246 return sections;
247 }
248
249 public void setSections(SparseArray<Section> sections) {
250 this.sections = sections;
251 }
252
253 private SparseArray<Section> sections = new SparseArray<Section>();
254
255 public HeadersHolder(ArrayList<CallContact> a) {
256 alphaIndexer = new HashMap<String, Integer>();
257 contacts = a;
258 headersCount = 0;
259 buildIndex();
260 }
261
262 // public int getHeadersCount() {
263 // return headersCount;
264 // }
265
266 private class Item {
267 public Item(int rpos, int headersCount2, CallContact track) {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400268 // Log.i(TAG, "Creating Item");
alisionf7053602013-07-09 10:25:20 -0400269
270 sectionNumber = headersCount2;
271 realPos = rpos;
272 tr = track;
273
274 }
275
276 public int realPos;
277 public int sectionNumber;
278 public CallContact tr;
279 }
280
281 private class Section {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400282 // public int startPosition;
alisionf7053602013-07-09 10:25:20 -0400283 public int number;
284 public String header;
285
286 public Section(int i, int headersCount, String str) {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400287 // Log.i(TAG, "Creating section");
alisionf7053602013-07-09 10:25:20 -0400288
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400289 // startPosition = i + headersCount;
alisionf7053602013-07-09 10:25:20 -0400290 number = headersCount;
291 header = str;
292
293 }
294
295 @Override
296 public String toString() {
297 return header;
298 }
299 }
300
301 public void buildIndex() {
302
303 for (int x = 0; x < contacts.size(); x++) {
304 String s = contacts.get(x).getmDisplayName();
305 String ch = s.substring(0, 1);
306 ch = ch.toUpperCase(Locale.CANADA);
307 if (!alphaIndexer.containsKey(ch)) {
308 sections.put(x + headersCount, new Section(x, headersCount, ch));
309 headersCount++;
310 }
311 Integer result = alphaIndexer.put(ch, x + headersCount);
312 items.put(x + headersCount, new Item(x, headersCount, contacts.get(x)));
313 if (result == null) {
314
315 }
316 }
317
318 Set<String> sect = alphaIndexer.keySet();
319
320 // create a list from the set to sort
321 ArrayList<String> sectionList = new ArrayList<String>(sect);
322 Collections.sort(sectionList);
323 sectionsArray = new String[sectionList.size()];
324 sectionList.toArray(sectionsArray);
325
326 }
327
328 public HashMap<String, Integer> getAlphaIndexer() {
329 return alphaIndexer;
330 }
331
332 public int getPositionFor(int section) {
333 if (section == sectionsArray.length)
334 return sectionsArray.length;
335 return alphaIndexer.get(sectionsArray[section]);
336 }
337
338 public int getSectionFor(int position) {
339 return (null != items.get(position)) ? items.get(position).sectionNumber : sections.get(position).number;
340 }
341
342 public boolean contains(int pos) {
343 if (sections.get(pos) != null) {
344 return true;
345 }
346 return false;
347 }
348
349 public CallContact getCallContact(int position) {
350
351 if (items.get(position) == null)
352 return null;
353
354 return items.get(position).tr;
355
356 }
357
358 public int size() {
359 return contacts.size();
360 }
361
362 public void clear() {
363 contacts.clear();
364
365 }
366
367 public void add(CallContact tr) {
368 contacts.add(tr);
369
370 }
371
372 public void addAll(ArrayList<CallContact> tr) {
373 contacts.clear();
374 contacts.addAll(tr);
375
376 }
377
378 public ArrayList<CallContact> getTracks() {
379 return contacts;
380 }
381
382 public int getTrackPosition(int pos) {
383 if (sections.get(pos) != null) {
384 return items.get(pos + 1).realPos;
385 }
386 return items.get(pos).realPos;
387 }
388
389 public CharSequence getSection(int position) {
390 return sections.get(position).header;
391 }
392
alisiond295ec22013-05-17 10:12:13 -0400393 }
394
395}