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