• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 
17 package com.android.loaderapp.model;
18 
19 import com.android.loaderapp.R;
20 import com.google.android.collect.Lists;
21 
22 import android.content.ContentValues;
23 import android.content.Context;
24 import android.content.res.Resources;
25 import android.database.Cursor;
26 import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
27 import android.provider.ContactsContract.CommonDataKinds.Email;
28 import android.provider.ContactsContract.CommonDataKinds.Event;
29 import android.provider.ContactsContract.CommonDataKinds.Im;
30 import android.provider.ContactsContract.CommonDataKinds.Nickname;
31 import android.provider.ContactsContract.CommonDataKinds.Note;
32 import android.provider.ContactsContract.CommonDataKinds.Organization;
33 import android.provider.ContactsContract.CommonDataKinds.Phone;
34 import android.provider.ContactsContract.CommonDataKinds.Photo;
35 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
36 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
37 import android.provider.ContactsContract.CommonDataKinds.Website;
38 import android.view.inputmethod.EditorInfo;
39 
40 import java.util.Locale;
41 
42 public class FallbackSource extends ContactsSource {
43     protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE;
44     protected static final int FLAGS_EMAIL = EditorInfo.TYPE_CLASS_TEXT
45             | EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
46     protected static final int FLAGS_PERSON_NAME = EditorInfo.TYPE_CLASS_TEXT
47             | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME;
48     protected static final int FLAGS_PHONETIC = EditorInfo.TYPE_CLASS_TEXT
49             | EditorInfo.TYPE_TEXT_VARIATION_PHONETIC;
50     protected static final int FLAGS_GENERIC_NAME = EditorInfo.TYPE_CLASS_TEXT
51             | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS;
52     protected static final int FLAGS_NOTE = EditorInfo.TYPE_CLASS_TEXT
53             | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
54     protected static final int FLAGS_WEBSITE = EditorInfo.TYPE_CLASS_TEXT
55             | EditorInfo.TYPE_TEXT_VARIATION_URI;
56     protected static final int FLAGS_POSTAL = EditorInfo.TYPE_CLASS_TEXT
57             | EditorInfo.TYPE_TEXT_VARIATION_POSTAL_ADDRESS | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS
58             | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
59 
FallbackSource()60     public FallbackSource() {
61         this.accountType = null;
62         this.titleRes = R.string.account_phone;
63         this.iconRes = R.drawable.ic_launcher_contacts;
64     }
65 
66     @Override
inflate(Context context, int inflateLevel)67     protected void inflate(Context context, int inflateLevel) {
68 
69         inflateStructuredName(context, inflateLevel);
70         inflateNickname(context, inflateLevel);
71         inflatePhone(context, inflateLevel);
72         inflateEmail(context, inflateLevel);
73         inflateStructuredPostal(context, inflateLevel);
74         inflateIm(context, inflateLevel);
75         inflateOrganization(context, inflateLevel);
76         inflatePhoto(context, inflateLevel);
77         inflateNote(context, inflateLevel);
78         inflateWebsite(context, inflateLevel);
79         inflateEvent(context, inflateLevel);
80 
81         setInflatedLevel(inflateLevel);
82 
83     }
84 
buildPhoneType(int type)85     protected EditType buildPhoneType(int type) {
86         return new EditType(type, Phone.getTypeLabelResource(type));
87     }
88 
buildEmailType(int type)89     protected EditType buildEmailType(int type) {
90         return new EditType(type, Email.getTypeLabelResource(type));
91     }
92 
buildPostalType(int type)93     protected EditType buildPostalType(int type) {
94         return new EditType(type, StructuredPostal.getTypeLabelResource(type));
95     }
96 
buildImType(int type)97     protected EditType buildImType(int type) {
98         return new EditType(type, Im.getProtocolLabelResource(type));
99     }
100 
buildOrgType(int type)101     protected EditType buildOrgType(int type) {
102         return new EditType(type, Organization.getTypeLabelResource(type));
103     }
104 
inflateStructuredName(Context context, int inflateLevel)105     protected DataKind inflateStructuredName(Context context, int inflateLevel) {
106         DataKind kind = getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
107         if (kind == null) {
108             kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
109                     R.string.nameLabelsGroup, -1, -1, true));
110         }
111 
112         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
113             boolean displayOrderPrimary =
114                     context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
115 
116             kind.fieldList = Lists.newArrayList();
117             kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
118                     FLAGS_PERSON_NAME).setOptional(true));
119             if (!displayOrderPrimary) {
120                 kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
121                         FLAGS_PERSON_NAME));
122                 kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
123                         FLAGS_PERSON_NAME).setOptional(true));
124                 kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
125                         FLAGS_PERSON_NAME));
126                 kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
127                         FLAGS_PERSON_NAME).setOptional(true));
128                 kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
129                         R.string.name_phonetic_family, FLAGS_PHONETIC).setOptional(true));
130                 kind.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME,
131                         R.string.name_phonetic_middle, FLAGS_PHONETIC).setOptional(true));
132                 kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
133                         R.string.name_phonetic_given, FLAGS_PHONETIC).setOptional(true));
134             } else {
135                 kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
136                         FLAGS_PERSON_NAME));
137                 kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
138                         FLAGS_PERSON_NAME).setOptional(true));
139                 kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
140                         FLAGS_PERSON_NAME));
141                 kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
142                         FLAGS_PERSON_NAME).setOptional(true));
143                 kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
144                         R.string.name_phonetic_given, FLAGS_PHONETIC).setOptional(true));
145                 kind.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME,
146                         R.string.name_phonetic_middle, FLAGS_PHONETIC).setOptional(true));
147                 kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
148                         R.string.name_phonetic_family, FLAGS_PHONETIC).setOptional(true));
149             }
150         }
151 
152         return kind;
153     }
154 
inflateNickname(Context context, int inflateLevel)155     protected DataKind inflateNickname(Context context, int inflateLevel) {
156         DataKind kind = getKindForMimetype(Nickname.CONTENT_ITEM_TYPE);
157         if (kind == null) {
158             kind = addKind(new DataKind(Nickname.CONTENT_ITEM_TYPE,
159                     R.string.nicknameLabelsGroup, -1, 115, true));
160             kind.secondary = true;
161             kind.isList = false;
162             kind.actionHeader = new SimpleInflater(R.string.nicknameLabelsGroup);
163             kind.actionBody = new SimpleInflater(Nickname.NAME);
164         }
165 
166         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
167             kind.defaultValues = new ContentValues();
168             kind.defaultValues.put(Nickname.TYPE, Nickname.TYPE_DEFAULT);
169 
170             kind.fieldList = Lists.newArrayList();
171             kind.fieldList.add(new EditField(Nickname.NAME, R.string.nicknameLabelsGroup,
172                     FLAGS_PERSON_NAME));
173         }
174 
175         return kind;
176     }
177 
inflatePhone(Context context, int inflateLevel)178     protected DataKind inflatePhone(Context context, int inflateLevel) {
179         DataKind kind = getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
180         if (kind == null) {
181             kind = addKind(new DataKind(Phone.CONTENT_ITEM_TYPE, R.string.phoneLabelsGroup,
182                     android.R.drawable.sym_action_call, 10, true));
183             kind.iconAltRes = R.drawable.sym_action_sms;
184             kind.actionHeader = new PhoneActionInflater();
185             kind.actionAltHeader = new PhoneActionAltInflater();
186             kind.actionBody = new SimpleInflater(Phone.NUMBER);
187         }
188 
189         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
190             kind.typeColumn = Phone.TYPE;
191             kind.typeList = Lists.newArrayList();
192             kind.typeList.add(buildPhoneType(Phone.TYPE_HOME));
193             kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE));
194             kind.typeList.add(buildPhoneType(Phone.TYPE_WORK));
195             kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true));
196             kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true));
197             kind.typeList.add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true));
198             kind.typeList.add(buildPhoneType(Phone.TYPE_OTHER));
199             kind.typeList.add(buildPhoneType(Phone.TYPE_CUSTOM).setSecondary(true).setCustomColumn(
200                     Phone.LABEL));
201             kind.typeList.add(buildPhoneType(Phone.TYPE_CALLBACK).setSecondary(true));
202             kind.typeList.add(buildPhoneType(Phone.TYPE_CAR).setSecondary(true));
203             kind.typeList.add(buildPhoneType(Phone.TYPE_COMPANY_MAIN).setSecondary(true));
204             kind.typeList.add(buildPhoneType(Phone.TYPE_ISDN).setSecondary(true));
205             kind.typeList.add(buildPhoneType(Phone.TYPE_MAIN).setSecondary(true));
206             kind.typeList.add(buildPhoneType(Phone.TYPE_OTHER_FAX).setSecondary(true));
207             kind.typeList.add(buildPhoneType(Phone.TYPE_RADIO).setSecondary(true));
208             kind.typeList.add(buildPhoneType(Phone.TYPE_TELEX).setSecondary(true));
209             kind.typeList.add(buildPhoneType(Phone.TYPE_TTY_TDD).setSecondary(true));
210             kind.typeList.add(buildPhoneType(Phone.TYPE_WORK_MOBILE).setSecondary(true));
211             kind.typeList.add(buildPhoneType(Phone.TYPE_WORK_PAGER).setSecondary(true));
212             kind.typeList.add(buildPhoneType(Phone.TYPE_ASSISTANT).setSecondary(true)
213                     .setCustomColumn(Phone.LABEL));
214             kind.typeList.add(buildPhoneType(Phone.TYPE_MMS).setSecondary(true));
215 
216             kind.fieldList = Lists.newArrayList();
217             kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE));
218         }
219 
220         return kind;
221     }
222 
inflateEmail(Context context, int inflateLevel)223     protected DataKind inflateEmail(Context context, int inflateLevel) {
224         DataKind kind = getKindForMimetype(Email.CONTENT_ITEM_TYPE);
225         if (kind == null) {
226             kind = addKind(new DataKind(Email.CONTENT_ITEM_TYPE,
227                     R.string.emailLabelsGroup, android.R.drawable.sym_action_email, 15, true));
228             kind.actionHeader = new EmailActionInflater();
229             kind.actionBody = new SimpleInflater(Email.DATA);
230         }
231 
232         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
233             kind.typeColumn = Email.TYPE;
234             kind.typeList = Lists.newArrayList();
235             kind.typeList.add(buildEmailType(Email.TYPE_HOME));
236             kind.typeList.add(buildEmailType(Email.TYPE_WORK));
237             kind.typeList.add(buildEmailType(Email.TYPE_OTHER));
238             kind.typeList.add(buildEmailType(Email.TYPE_MOBILE));
239             kind.typeList.add(buildEmailType(Email.TYPE_CUSTOM).setSecondary(true).setCustomColumn(
240                     Email.LABEL));
241 
242             kind.fieldList = Lists.newArrayList();
243             kind.fieldList.add(new EditField(Email.DATA, R.string.emailLabelsGroup, FLAGS_EMAIL));
244         }
245 
246         return kind;
247     }
248 
inflateStructuredPostal(Context context, int inflateLevel)249     protected DataKind inflateStructuredPostal(Context context, int inflateLevel) {
250         DataKind kind = getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
251         if (kind == null) {
252             kind = addKind(new DataKind(StructuredPostal.CONTENT_ITEM_TYPE,
253                     R.string.postalLabelsGroup, R.drawable.sym_action_map, 25, true));
254             kind.actionHeader = new PostalActionInflater();
255             kind.actionBody = new SimpleInflater(StructuredPostal.FORMATTED_ADDRESS);
256         }
257 
258         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
259             final boolean useJapaneseOrder =
260                 Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage());
261             kind.typeColumn = StructuredPostal.TYPE;
262             kind.typeList = Lists.newArrayList();
263             kind.typeList.add(buildPostalType(StructuredPostal.TYPE_HOME));
264             kind.typeList.add(buildPostalType(StructuredPostal.TYPE_WORK));
265             kind.typeList.add(buildPostalType(StructuredPostal.TYPE_OTHER));
266             kind.typeList.add(buildPostalType(StructuredPostal.TYPE_CUSTOM).setSecondary(true)
267                     .setCustomColumn(StructuredPostal.LABEL));
268 
269             kind.fieldList = Lists.newArrayList();
270 
271             if (useJapaneseOrder) {
272                 kind.fieldList.add(new EditField(StructuredPostal.COUNTRY,
273                         R.string.postal_country, FLAGS_POSTAL).setOptional(true));
274                 kind.fieldList.add(new EditField(StructuredPostal.POSTCODE,
275                         R.string.postal_postcode, FLAGS_POSTAL));
276                 kind.fieldList.add(new EditField(StructuredPostal.REGION,
277                         R.string.postal_region, FLAGS_POSTAL));
278                 kind.fieldList.add(new EditField(StructuredPostal.CITY,
279                         R.string.postal_city, FLAGS_POSTAL));
280                 kind.fieldList.add(new EditField(StructuredPostal.NEIGHBORHOOD,
281                         R.string.postal_neighborhood, FLAGS_POSTAL).setOptional(true));
282                 kind.fieldList.add(new EditField(StructuredPostal.STREET,
283                         R.string.postal_street, FLAGS_POSTAL));
284                 kind.fieldList.add(new EditField(StructuredPostal.POBOX,
285                         R.string.postal_pobox, FLAGS_POSTAL).setOptional(true));
286             } else {
287                 kind.fieldList.add(new EditField(StructuredPostal.STREET,
288                         R.string.postal_street, FLAGS_POSTAL));
289                 kind.fieldList.add(new EditField(StructuredPostal.POBOX,
290                         R.string.postal_pobox, FLAGS_POSTAL).setOptional(true));
291                 kind.fieldList.add(new EditField(StructuredPostal.NEIGHBORHOOD,
292                         R.string.postal_neighborhood, FLAGS_POSTAL).setOptional(true));
293                 kind.fieldList.add(new EditField(StructuredPostal.CITY,
294                         R.string.postal_city, FLAGS_POSTAL));
295                 kind.fieldList.add(new EditField(StructuredPostal.REGION,
296                         R.string.postal_region, FLAGS_POSTAL));
297                 kind.fieldList.add(new EditField(StructuredPostal.POSTCODE,
298                         R.string.postal_postcode, FLAGS_POSTAL));
299                 kind.fieldList.add(new EditField(StructuredPostal.COUNTRY,
300                         R.string.postal_country, FLAGS_POSTAL).setOptional(true));
301             }
302         }
303 
304         return kind;
305     }
306 
inflateIm(Context context, int inflateLevel)307     protected DataKind inflateIm(Context context, int inflateLevel) {
308         DataKind kind = getKindForMimetype(Im.CONTENT_ITEM_TYPE);
309         if (kind == null) {
310             kind = addKind(new DataKind(Im.CONTENT_ITEM_TYPE, R.string.imLabelsGroup,
311                     android.R.drawable.sym_action_chat, 20, true));
312             kind.secondary = true;
313             kind.actionHeader = new ImActionInflater();
314             kind.actionBody = new SimpleInflater(Im.DATA);
315         }
316 
317         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
318             // NOTE: even though a traditional "type" exists, for editing
319             // purposes we're using the protocol to pick labels
320 
321             kind.defaultValues = new ContentValues();
322             kind.defaultValues.put(Im.TYPE, Im.TYPE_OTHER);
323 
324             kind.typeColumn = Im.PROTOCOL;
325             kind.typeList = Lists.newArrayList();
326             kind.typeList.add(buildImType(Im.PROTOCOL_AIM));
327             kind.typeList.add(buildImType(Im.PROTOCOL_MSN));
328             kind.typeList.add(buildImType(Im.PROTOCOL_YAHOO));
329             kind.typeList.add(buildImType(Im.PROTOCOL_SKYPE));
330             kind.typeList.add(buildImType(Im.PROTOCOL_QQ));
331             kind.typeList.add(buildImType(Im.PROTOCOL_GOOGLE_TALK));
332             kind.typeList.add(buildImType(Im.PROTOCOL_ICQ));
333             kind.typeList.add(buildImType(Im.PROTOCOL_JABBER));
334             kind.typeList.add(buildImType(Im.PROTOCOL_CUSTOM).setSecondary(true).setCustomColumn(
335                     Im.CUSTOM_PROTOCOL));
336 
337             kind.fieldList = Lists.newArrayList();
338             kind.fieldList.add(new EditField(Im.DATA, R.string.imLabelsGroup, FLAGS_EMAIL));
339         }
340 
341         return kind;
342     }
343 
inflateOrganization(Context context, int inflateLevel)344     protected DataKind inflateOrganization(Context context, int inflateLevel) {
345         DataKind kind = getKindForMimetype(Organization.CONTENT_ITEM_TYPE);
346         if (kind == null) {
347             kind = addKind(new DataKind(Organization.CONTENT_ITEM_TYPE,
348                     R.string.organizationLabelsGroup, R.drawable.sym_action_organization, 30, true));
349             kind.actionHeader = new SimpleInflater(Organization.COMPANY);
350             kind.actionBody = new SimpleInflater(Organization.TITLE);
351         }
352 
353         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
354             kind.typeColumn = Organization.TYPE;
355             kind.typeList = Lists.newArrayList();
356             kind.typeList.add(buildOrgType(Organization.TYPE_WORK));
357             kind.typeList.add(buildOrgType(Organization.TYPE_OTHER));
358             kind.typeList.add(buildOrgType(Organization.TYPE_CUSTOM).setSecondary(true)
359                     .setCustomColumn(Organization.LABEL));
360 
361             kind.fieldList = Lists.newArrayList();
362             kind.fieldList.add(new EditField(Organization.COMPANY, R.string.ghostData_company,
363                     FLAGS_GENERIC_NAME));
364             kind.fieldList.add(new EditField(Organization.TITLE, R.string.ghostData_title,
365                     FLAGS_GENERIC_NAME));
366         }
367 
368         return kind;
369     }
370 
inflatePhoto(Context context, int inflateLevel)371     protected DataKind inflatePhoto(Context context, int inflateLevel) {
372         DataKind kind = getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
373         if (kind == null) {
374             kind = addKind(new DataKind(Photo.CONTENT_ITEM_TYPE, -1, -1, -1, true));
375         }
376 
377         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
378             kind.fieldList = Lists.newArrayList();
379             kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1));
380         }
381 
382         return kind;
383     }
384 
inflateNote(Context context, int inflateLevel)385     protected DataKind inflateNote(Context context, int inflateLevel) {
386         DataKind kind = getKindForMimetype(Note.CONTENT_ITEM_TYPE);
387         if (kind == null) {
388             kind = addKind(new DataKind(Note.CONTENT_ITEM_TYPE,
389                     R.string.label_notes, R.drawable.sym_note, 110, true));
390             kind.isList = false;
391             kind.secondary = true;
392             kind.actionHeader = new SimpleInflater(R.string.label_notes);
393             kind.actionBody = new SimpleInflater(Note.NOTE);
394         }
395 
396         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
397             kind.fieldList = Lists.newArrayList();
398             kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE));
399         }
400 
401         return kind;
402     }
403 
inflateWebsite(Context context, int inflateLevel)404     protected DataKind inflateWebsite(Context context, int inflateLevel) {
405         DataKind kind = getKindForMimetype(Website.CONTENT_ITEM_TYPE);
406         if (kind == null) {
407             kind = addKind(new DataKind(Website.CONTENT_ITEM_TYPE,
408                     R.string.websiteLabelsGroup, -1, 120, true));
409             kind.secondary = true;
410             kind.actionHeader = new SimpleInflater(R.string.websiteLabelsGroup);
411             kind.actionBody = new SimpleInflater(Website.URL);
412         }
413 
414         if (inflateLevel >= ContactsSource.LEVEL_CONSTRAINTS) {
415             kind.defaultValues = new ContentValues();
416             kind.defaultValues.put(Website.TYPE, Website.TYPE_OTHER);
417 
418             kind.fieldList = Lists.newArrayList();
419             kind.fieldList.add(new EditField(Website.URL, R.string.websiteLabelsGroup, FLAGS_WEBSITE));
420         }
421 
422         return kind;
423     }
424 
inflateEvent(Context context, int inflateLevel)425     protected DataKind inflateEvent(Context context, int inflateLevel) {
426         DataKind kind = getKindForMimetype(Event.CONTENT_ITEM_TYPE);
427         if (kind == null) {
428             kind = addKind(new DataKind(Event.CONTENT_ITEM_TYPE,
429                     R.string.eventLabelsGroup, -1, 150, false));
430             kind.secondary = true;
431             kind.actionHeader = new EventActionInflater();
432             kind.actionBody = new SimpleInflater(Event.START_DATE);
433         }
434 
435         return kind;
436     }
437 
438     /**
439      * Simple inflater that assumes a string resource has a "%s" that will be
440      * filled from the given column.
441      */
442     public static class SimpleInflater implements StringInflater {
443         private final int mStringRes;
444         private final String mColumnName;
445 
SimpleInflater(int stringRes)446         public SimpleInflater(int stringRes) {
447             this(stringRes, null);
448         }
449 
SimpleInflater(String columnName)450         public SimpleInflater(String columnName) {
451             this(-1, columnName);
452         }
453 
SimpleInflater(int stringRes, String columnName)454         public SimpleInflater(int stringRes, String columnName) {
455             mStringRes = stringRes;
456             mColumnName = columnName;
457         }
458 
inflateUsing(Context context, Cursor cursor)459         public CharSequence inflateUsing(Context context, Cursor cursor) {
460             final int index = mColumnName != null ? cursor.getColumnIndex(mColumnName) : -1;
461             final boolean validString = mStringRes > 0;
462             final boolean validColumn = index != -1;
463 
464             final CharSequence stringValue = validString ? context.getText(mStringRes) : null;
465             final CharSequence columnValue = validColumn ? cursor.getString(index) : null;
466 
467             if (validString && validColumn) {
468                 return String.format(stringValue.toString(), columnValue);
469             } else if (validString) {
470                 return stringValue;
471             } else if (validColumn) {
472                 return columnValue;
473             } else {
474                 return null;
475             }
476         }
477 
inflateUsing(Context context, ContentValues values)478         public CharSequence inflateUsing(Context context, ContentValues values) {
479             final boolean validColumn = values.containsKey(mColumnName);
480             final boolean validString = mStringRes > 0;
481 
482             final CharSequence stringValue = validString ? context.getText(mStringRes) : null;
483             final CharSequence columnValue = validColumn ? values.getAsString(mColumnName) : null;
484 
485             if (validString && validColumn) {
486                 return String.format(stringValue.toString(), columnValue);
487             } else if (validString) {
488                 return stringValue;
489             } else if (validColumn) {
490                 return columnValue;
491             } else {
492                 return null;
493             }
494         }
495     }
496 
497     public static abstract class CommonInflater implements StringInflater {
getTypeLabelResource(Integer type)498         protected abstract int getTypeLabelResource(Integer type);
499 
isCustom(Integer type)500         protected boolean isCustom(Integer type) {
501             return type == BaseTypes.TYPE_CUSTOM;
502         }
503 
getTypeColumn()504         protected String getTypeColumn() {
505             return Phone.TYPE;
506         }
507 
getLabelColumn()508         protected String getLabelColumn() {
509             return Phone.LABEL;
510         }
511 
getTypeLabel(Resources res, Integer type, CharSequence label)512         protected CharSequence getTypeLabel(Resources res, Integer type, CharSequence label) {
513             final int labelRes = getTypeLabelResource(type);
514             if (type == null) {
515                 return res.getText(labelRes);
516             } else if (isCustom(type)) {
517                 return res.getString(labelRes, label == null ? "" : label);
518             } else {
519                 return res.getText(labelRes);
520             }
521         }
522 
inflateUsing(Context context, Cursor cursor)523         public CharSequence inflateUsing(Context context, Cursor cursor) {
524             final Integer type = cursor.getInt(cursor.getColumnIndex(getTypeColumn()));
525             final String label = cursor.getString(cursor.getColumnIndex(getLabelColumn()));
526             return getTypeLabel(context.getResources(), type, label);
527         }
528 
inflateUsing(Context context, ContentValues values)529         public CharSequence inflateUsing(Context context, ContentValues values) {
530             final Integer type = values.getAsInteger(getTypeColumn());
531             final String label = values.getAsString(getLabelColumn());
532             return getTypeLabel(context.getResources(), type, label);
533         }
534     }
535 
536     public static class PhoneActionInflater extends CommonInflater {
537         @Override
isCustom(Integer type)538         protected boolean isCustom(Integer type) {
539             return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT;
540         }
541 
542         @Override
getTypeLabelResource(Integer type)543         protected int getTypeLabelResource(Integer type) {
544             if (type == null) return R.string.call_other;
545             switch (type) {
546                 case Phone.TYPE_HOME: return R.string.call_home;
547                 case Phone.TYPE_MOBILE: return R.string.call_mobile;
548                 case Phone.TYPE_WORK: return R.string.call_work;
549                 case Phone.TYPE_FAX_WORK: return R.string.call_fax_work;
550                 case Phone.TYPE_FAX_HOME: return R.string.call_fax_home;
551                 case Phone.TYPE_PAGER: return R.string.call_pager;
552                 case Phone.TYPE_OTHER: return R.string.call_other;
553                 case Phone.TYPE_CALLBACK: return R.string.call_callback;
554                 case Phone.TYPE_CAR: return R.string.call_car;
555                 case Phone.TYPE_COMPANY_MAIN: return R.string.call_company_main;
556                 case Phone.TYPE_ISDN: return R.string.call_isdn;
557                 case Phone.TYPE_MAIN: return R.string.call_main;
558                 case Phone.TYPE_OTHER_FAX: return R.string.call_other_fax;
559                 case Phone.TYPE_RADIO: return R.string.call_radio;
560                 case Phone.TYPE_TELEX: return R.string.call_telex;
561                 case Phone.TYPE_TTY_TDD: return R.string.call_tty_tdd;
562                 case Phone.TYPE_WORK_MOBILE: return R.string.call_work_mobile;
563                 case Phone.TYPE_WORK_PAGER: return R.string.call_work_pager;
564                 case Phone.TYPE_ASSISTANT: return R.string.call_assistant;
565                 case Phone.TYPE_MMS: return R.string.call_mms;
566                 default: return R.string.call_custom;
567             }
568         }
569     }
570 
571     public static class PhoneActionAltInflater extends CommonInflater {
572         @Override
isCustom(Integer type)573         protected boolean isCustom(Integer type) {
574             return (type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT);
575         }
576 
577         @Override
getTypeLabelResource(Integer type)578         protected int getTypeLabelResource(Integer type) {
579             if (type == null) return R.string.sms_other;
580             switch (type) {
581                 case Phone.TYPE_HOME: return R.string.sms_home;
582                 case Phone.TYPE_MOBILE: return R.string.sms_mobile;
583                 case Phone.TYPE_WORK: return R.string.sms_work;
584                 case Phone.TYPE_FAX_WORK: return R.string.sms_fax_work;
585                 case Phone.TYPE_FAX_HOME: return R.string.sms_fax_home;
586                 case Phone.TYPE_PAGER: return R.string.sms_pager;
587                 case Phone.TYPE_OTHER: return R.string.sms_other;
588                 case Phone.TYPE_CALLBACK: return R.string.sms_callback;
589                 case Phone.TYPE_CAR: return R.string.sms_car;
590                 case Phone.TYPE_COMPANY_MAIN: return R.string.sms_company_main;
591                 case Phone.TYPE_ISDN: return R.string.sms_isdn;
592                 case Phone.TYPE_MAIN: return R.string.sms_main;
593                 case Phone.TYPE_OTHER_FAX: return R.string.sms_other_fax;
594                 case Phone.TYPE_RADIO: return R.string.sms_radio;
595                 case Phone.TYPE_TELEX: return R.string.sms_telex;
596                 case Phone.TYPE_TTY_TDD: return R.string.sms_tty_tdd;
597                 case Phone.TYPE_WORK_MOBILE: return R.string.sms_work_mobile;
598                 case Phone.TYPE_WORK_PAGER: return R.string.sms_work_pager;
599                 case Phone.TYPE_ASSISTANT: return R.string.sms_assistant;
600                 case Phone.TYPE_MMS: return R.string.sms_mms;
601                 default: return R.string.sms_custom;
602             }
603         }
604     }
605 
606     public static class EmailActionInflater extends CommonInflater {
607         @Override
getTypeLabelResource(Integer type)608         protected int getTypeLabelResource(Integer type) {
609             if (type == null) return R.string.email;
610             switch (type) {
611                 case Email.TYPE_HOME: return R.string.email_home;
612                 case Email.TYPE_WORK: return R.string.email_work;
613                 case Email.TYPE_OTHER: return R.string.email_other;
614                 case Email.TYPE_MOBILE: return R.string.email_mobile;
615                 default: return R.string.email_custom;
616             }
617         }
618     }
619 
620     public static class EventActionInflater extends CommonInflater {
621         @Override
getTypeLabelResource(Integer type)622         protected int getTypeLabelResource(Integer type) {
623             return Event.getTypeResource(type);
624         }
625     }
626 
627     public static class PostalActionInflater extends CommonInflater {
628         @Override
getTypeLabelResource(Integer type)629         protected int getTypeLabelResource(Integer type) {
630             if (type == null) return R.string.map_other;
631             switch (type) {
632                 case StructuredPostal.TYPE_HOME: return R.string.map_home;
633                 case StructuredPostal.TYPE_WORK: return R.string.map_work;
634                 case StructuredPostal.TYPE_OTHER: return R.string.map_other;
635                 default: return R.string.map_custom;
636             }
637         }
638     }
639 
640     public static class ImActionInflater extends CommonInflater {
641         @Override
getTypeColumn()642         protected String getTypeColumn() {
643             return Im.PROTOCOL;
644         }
645 
646         @Override
getLabelColumn()647         protected String getLabelColumn() {
648             return Im.CUSTOM_PROTOCOL;
649         }
650 
651         @Override
getTypeLabelResource(Integer type)652         protected int getTypeLabelResource(Integer type) {
653             if (type == null) return R.string.chat;
654             switch (type) {
655                 case Im.PROTOCOL_AIM: return R.string.chat_aim;
656                 case Im.PROTOCOL_MSN: return R.string.chat_msn;
657                 case Im.PROTOCOL_YAHOO: return R.string.chat_yahoo;
658                 case Im.PROTOCOL_SKYPE: return R.string.chat_skype;
659                 case Im.PROTOCOL_QQ: return R.string.chat_qq;
660                 case Im.PROTOCOL_GOOGLE_TALK: return R.string.chat_gtalk;
661                 case Im.PROTOCOL_ICQ: return R.string.chat_icq;
662                 case Im.PROTOCOL_JABBER: return R.string.chat_jabber;
663                 case Im.PROTOCOL_NETMEETING: return R.string.chat;
664                 default: return R.string.chat;
665             }
666         }
667     }
668 
669     @Override
getHeaderColor(Context context)670     public int getHeaderColor(Context context) {
671         return 0xff7f93bc;
672     }
673 
674     @Override
getSideBarColor(Context context)675     public int getSideBarColor(Context context) {
676         return 0xffbdc7b8;
677     }
678 }
679