blob: 0f12de72e08276da706d74b24495fae3300adf37 [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.contacts.detail;
import com.android.contacts.ContactLoader;
import com.android.contacts.ContactLoader.Result;
import com.android.contacts.R;
import com.android.contacts.format.FormatUtils;
import com.android.contacts.preference.ContactsPreferences;
import com.android.contacts.util.ContactBadgeUtil;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
import android.content.Entity.NamedContentValues;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.DisplayNameSources;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
/**
* This class contains utility methods to bind high-level contact details
* (meaning name, phonetic name, job, and attribution) from a
* {@link ContactLoader.Result} data object to appropriate {@link View}s.
*/
public class ContactDetailDisplayUtils {
private static final int PHOTO_FADE_IN_ANIMATION_DURATION_MILLIS = 100;
private ContactDetailDisplayUtils() {
// Disallow explicit creation of this class.
}
/**
* Returns the display name of the contact. Depending on the preference for
* display name ordering, the contact's first name may be bolded if
* possible. Returns empty string if there is no display name.
*/
public static CharSequence getDisplayName(Context context, Result contactData) {
CharSequence displayName = contactData.getDisplayName();
CharSequence altDisplayName = contactData.getAltDisplayName();
ContactsPreferences prefs = new ContactsPreferences(context);
CharSequence styledName = "";
if (!TextUtils.isEmpty(displayName) && !TextUtils.isEmpty(altDisplayName)) {
if (prefs.getDisplayOrder() == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
int overlapPoint = FormatUtils.overlapPoint(
displayName.toString(), altDisplayName.toString());
if (overlapPoint > 0) {
styledName = FormatUtils.applyStyleToSpan(Typeface.BOLD,
displayName, 0, overlapPoint, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
styledName = displayName;
}
} else {
// Displaying alternate display name.
int overlapPoint = FormatUtils.overlapPoint(
altDisplayName.toString(), displayName.toString());
if (overlapPoint > 0) {
styledName = FormatUtils.applyStyleToSpan(Typeface.BOLD,
altDisplayName, overlapPoint, altDisplayName.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
styledName = altDisplayName;
}
}
}
return styledName;
}
/**
* Returns the phonetic name of the contact or null if there isn't one.
*/
public static String getPhoneticName(Context context, Result contactData) {
String phoneticName = contactData.getPhoneticName();
if (!TextUtils.isEmpty(phoneticName)) {
return phoneticName;
}
return null;
}
/**
* Returns the attribution string for the contact. This could either specify
* that this is a joined contact or specify the contact directory that the
* contact came from. Returns null if there is none applicable.
*/
public static String getAttribution(Context context, Result contactData) {
// Check if this is a joined contact
if (contactData.getEntities().size() > 1) {
return context.getString(R.string.indicator_joined_contact);
} else if (contactData.isDirectoryEntry()) {
// This contact is from a directory
String directoryDisplayName = contactData.getDirectoryDisplayName();
String directoryType = contactData.getDirectoryType();
String displayName = !TextUtils.isEmpty(directoryDisplayName)
? directoryDisplayName
: directoryType;
return context.getString(R.string.contact_directory_description, displayName);
}
return null;
}
/**
* Returns the organization of the contact. If several organizations are given,
* the first one is used. Returns null if not applicable.
*/
public static String getCompany(Context context, Result contactData) {
final boolean displayNameIsOrganization = contactData.getDisplayNameSource()
== DisplayNameSources.ORGANIZATION;
for (Entity entity : contactData.getEntities()) {
for (NamedContentValues subValue : entity.getSubValues()) {
final ContentValues entryValues = subValue.values;
final String mimeType = entryValues.getAsString(Data.MIMETYPE);
if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
final String company = entryValues.getAsString(Organization.COMPANY);
final String title = entryValues.getAsString(Organization.TITLE);
final String combined;
// We need to show company and title in a combined string. However, if the
// DisplayName is already the organization, it mirrors company or (if company
// is empty title). Make sure we don't show what's already shown as DisplayName
if (TextUtils.isEmpty(company)) {
combined = displayNameIsOrganization ? null : title;
} else {
if (TextUtils.isEmpty(title)) {
combined = displayNameIsOrganization ? null : company;
} else {
if (displayNameIsOrganization) {
combined = title;
} else {
combined = context.getString(
R.string.organization_company_and_title,
company, title);
}
}
}
if (!TextUtils.isEmpty(combined)) {
return combined;
}
}
}
}
return null;
}
/**
* Sets the contact photo to display in the given {@link ImageView}. If bitmap is null, the
* default placeholder image is shown.
*/
public static void setPhoto(Context context, Result contactData, ImageView photoView) {
if (contactData.isLoadingPhoto()) {
photoView.setImageBitmap(null);
return;
}
byte[] photo = contactData.getPhotoBinaryData();
Bitmap bitmap = photo != null ? BitmapFactory.decodeByteArray(photo, 0, photo.length)
: ContactBadgeUtil.loadPlaceholderPhoto(context);
boolean fadeIn = contactData.isDirectoryEntry();
if (photoView.getDrawable() == null && fadeIn) {
AlphaAnimation animation = new AlphaAnimation(0, 1);
animation.setDuration(PHOTO_FADE_IN_ANIMATION_DURATION_MILLIS);
animation.setInterpolator(new AccelerateInterpolator());
photoView.startAnimation(animation);
}
photoView.setImageBitmap(bitmap);
}
/**
* Sets the starred state of this contact.
*/
public static void setStarred(Result contactData, CheckBox starredView) {
// Check if the starred state should be visible
if (!contactData.isDirectoryEntry()) {
starredView.setVisibility(View.VISIBLE);
starredView.setChecked(contactData.getStarred());
} else {
starredView.setVisibility(View.GONE);
}
}
/**
* Set the social snippet text and date. If there isn't one, then set the view to gone.
*/
public static void setSocialSnippetAndDate(Context context, Result contactData,
TextView statusView, TextView dateView) {
setDataOrHideIfNone(contactData.getSocialSnippet(), statusView);
setDataOrHideIfNone(ContactBadgeUtil.getSocialDate(contactData, context), dateView);
}
/**
* Sets the phonetic name of this contact to the given {@link TextView}. If
* there is none, then set the view to gone.
*/
public static void setPhoneticName(Context context, Result contactData, TextView textView) {
setDataOrHideIfNone(getPhoneticName(context, contactData), textView);
}
/**
* Sets the attribution contact to the given {@link TextView}. If
* there is none, then set the view to gone.
*/
public static void setAttribution(Context context, Result contactData, TextView textView) {
setDataOrHideIfNone(getAttribution(context, contactData), textView);
}
/**
* Helper function to display the given text in the {@link TextView} or
* hides the {@link TextView} if the text is empty or null.
*/
private static void setDataOrHideIfNone(CharSequence textToDisplay, TextView textView) {
if (!TextUtils.isEmpty(textToDisplay)) {
textView.setText(textToDisplay);
textView.setVisibility(View.VISIBLE);
} else {
textView.setText(null);
textView.setVisibility(View.GONE);
}
}
}