Home | History | Annotate | Download | only in model
      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 
     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
     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 
     85     protected EditType buildPhoneType(int type) {
     86         return new EditType(type, Phone.getTypeLabelResource(type));
     87     }
     88 
     89     protected EditType buildEmailType(int type) {
     90         return new EditType(type, Email.getTypeLabelResource(type));
     91     }
     92 
     93     protected EditType buildPostalType(int type) {
     94         return new EditType(type, StructuredPostal.getTypeLabelResource(type));
     95     }
     96 
     97     protected EditType buildImType(int type) {
     98         return new EditType(type, Im.getProtocolLabelResource(type));
     99     }
    100 
    101     protected EditType buildOrgType(int type) {
    102         return new EditType(type, Organization.getTypeLabelResource(type));
    103     }
    104 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    446         public SimpleInflater(int stringRes) {
    447             this(stringRes, null);
    448         }
    449 
    450         public SimpleInflater(String columnName) {
    451             this(-1, columnName);
    452         }
    453 
    454         public SimpleInflater(int stringRes, String columnName) {
    455             mStringRes = stringRes;
    456             mColumnName = columnName;
    457         }
    458 
    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 
    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 {
    498         protected abstract int getTypeLabelResource(Integer type);
    499 
    500         protected boolean isCustom(Integer type) {
    501             return type == BaseTypes.TYPE_CUSTOM;
    502         }
    503 
    504         protected String getTypeColumn() {
    505             return Phone.TYPE;
    506         }
    507 
    508         protected String getLabelColumn() {
    509             return Phone.LABEL;
    510         }
    511 
    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 
    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 
    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
    538         protected boolean isCustom(Integer type) {
    539             return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT;
    540         }
    541 
    542         @Override
    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
    573         protected boolean isCustom(Integer type) {
    574             return (type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT);
    575         }
    576 
    577         @Override
    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
    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
    622         protected int getTypeLabelResource(Integer type) {
    623             return Event.getTypeResource(type);
    624         }
    625     }
    626 
    627     public static class PostalActionInflater extends CommonInflater {
    628         @Override
    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
    642         protected String getTypeColumn() {
    643             return Im.PROTOCOL;
    644         }
    645 
    646         @Override
    647         protected String getLabelColumn() {
    648             return Im.CUSTOM_PROTOCOL;
    649         }
    650 
    651         @Override
    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
    670     public int getHeaderColor(Context context) {
    671         return 0xff7f93bc;
    672     }
    673 
    674     @Override
    675     public int getSideBarColor(Context context) {
    676         return 0xffbdc7b8;
    677     }
    678 }
    679