Home | History | Annotate | Download | only in editor
      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.contacts.editor;
     18 
     19 import android.content.ContentUris;
     20 import android.content.Context;
     21 import android.content.res.Resources;
     22 import android.graphics.drawable.Drawable;
     23 import android.provider.ContactsContract.CommonDataKinds.Email;
     24 import android.provider.ContactsContract.CommonDataKinds.Phone;
     25 import android.provider.ContactsContract.CommonDataKinds.Photo;
     26 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
     27 import android.provider.ContactsContract.RawContacts;
     28 import android.text.TextUtils;
     29 import android.util.AttributeSet;
     30 import android.util.Pair;
     31 import android.view.LayoutInflater;
     32 import android.view.View;
     33 import android.view.View.OnClickListener;
     34 import android.view.ViewGroup;
     35 import android.widget.Button;
     36 import android.widget.ImageView;
     37 import android.widget.TextView;
     38 
     39 import com.android.contacts.R;
     40 import com.android.contacts.common.GeoUtil;
     41 import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
     42 import com.android.contacts.common.model.RawContactModifier;
     43 import com.android.contacts.common.model.RawContactDelta;
     44 import com.android.contacts.common.model.ValuesDelta;
     45 import com.android.contacts.common.model.account.AccountType;
     46 import com.android.contacts.common.model.account.AccountWithDataSet;
     47 import com.android.contacts.common.model.dataitem.DataKind;
     48 
     49 import java.util.ArrayList;
     50 
     51 /**
     52  * Custom view that displays external contacts in the edit screen.
     53  */
     54 public class RawContactReadOnlyEditorView extends BaseRawContactEditorView
     55         implements OnClickListener {
     56     private LayoutInflater mInflater;
     57 
     58     private TextView mName;
     59     private Button mEditExternallyButton;
     60     private ViewGroup mGeneral;
     61 
     62     private TextView mAccountHeaderTypeTextView;
     63     private TextView mAccountHeaderNameTextView;
     64     private ImageView mAccountIconImageView;
     65 
     66     private String mAccountName;
     67     private String mAccountType;
     68     private String mDataSet;
     69     private long mRawContactId = -1;
     70 
     71     public RawContactReadOnlyEditorView(Context context) {
     72         super(context);
     73     }
     74 
     75     public RawContactReadOnlyEditorView(Context context, AttributeSet attrs) {
     76         super(context, attrs);
     77     }
     78 
     79 
     80     /** {@inheritDoc} */
     81     @Override
     82     protected void onFinishInflate() {
     83         super.onFinishInflate();
     84 
     85         mInflater = (LayoutInflater)getContext().getSystemService(
     86                 Context.LAYOUT_INFLATER_SERVICE);
     87 
     88         mName = (TextView) findViewById(R.id.read_only_name);
     89         mEditExternallyButton = (Button) findViewById(R.id.button_edit_externally);
     90         mEditExternallyButton.setOnClickListener(this);
     91         mGeneral = (ViewGroup)findViewById(R.id.sect_general);
     92 
     93         mAccountHeaderTypeTextView = (TextView) findViewById(R.id.account_type);
     94         mAccountHeaderNameTextView = (TextView) findViewById(R.id.account_name);
     95         mAccountIconImageView = (ImageView) findViewById(android.R.id.icon);
     96     }
     97 
     98     /**
     99      * Set the internal state for this view, given a current
    100      * {@link RawContactDelta} state and the {@link AccountType} that
    101      * apply to that state.
    102      */
    103     @Override
    104     public void setState(RawContactDelta state, AccountType type, ViewIdGenerator vig,
    105             boolean isProfile) {
    106         // Remove any existing sections
    107         mGeneral.removeAllViews();
    108 
    109         // Bail if invalid state or source
    110         if (state == null || type == null) return;
    111 
    112         // Make sure we have StructuredName
    113         RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
    114 
    115         // Fill in the header info
    116         mAccountName = state.getAccountName();
    117         mAccountType = state.getAccountType();
    118         mDataSet = state.getDataSet();
    119 
    120         final Pair<String,String> accountInfo = isProfile
    121                 ? EditorUiUtils.getLocalAccountInfo(getContext(), state.getAccountName(), type)
    122                 : EditorUiUtils.getAccountInfo(getContext(), state.getAccountName(), type);
    123         if (accountInfo.first == null) {
    124             // Hide this view so the other text view will be centered vertically
    125             mAccountHeaderNameTextView.setVisibility(View.GONE);
    126         } else {
    127             mAccountHeaderNameTextView.setVisibility(View.VISIBLE);
    128             mAccountHeaderNameTextView.setText(accountInfo.first);
    129         }
    130         mAccountHeaderTypeTextView.setText(accountInfo.second);
    131         updateAccountHeaderContentDescription();
    132 
    133         mAccountIconImageView.setImageDrawable(state.getRawContactAccountType(getContext())
    134                 .getDisplayIcon(getContext()));
    135 
    136         // TODO: Expose data set in the UI somehow?
    137 
    138         mRawContactId = state.getRawContactId();
    139 
    140         ValuesDelta primary;
    141 
    142         // Photo
    143         DataKind kind = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
    144         if (kind != null) {
    145             RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
    146             boolean hasPhotoEditor = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null;
    147             setHasPhotoEditor(hasPhotoEditor);
    148             primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
    149             getPhotoEditor().setValues(kind, primary, state, !type.areContactsWritable(), vig);
    150         }
    151 
    152         // Name
    153         primary = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
    154         mName.setText(primary != null ? primary.getAsString(StructuredName.DISPLAY_NAME) :
    155                 getContext().getString(R.string.missing_name));
    156 
    157         if (type.getEditContactActivityClassName() != null) {
    158             mEditExternallyButton.setVisibility(View.VISIBLE);
    159         } else {
    160             mEditExternallyButton.setVisibility(View.GONE);
    161         }
    162 
    163         final Resources res = getContext().getResources();
    164         // Phones
    165         final ArrayList<ValuesDelta> phones = state.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
    166         final Drawable phoneDrawable = getResources().getDrawable(R.drawable.ic_phone_24dp);
    167         final String phoneContentDescription = res.getString(R.string.header_phone_entry);
    168         if (phones != null) {
    169             boolean isFirstPhoneBound = true;
    170             for (ValuesDelta phone : phones) {
    171                 final String phoneNumber = phone.getPhoneNumber();
    172                 if (TextUtils.isEmpty(phoneNumber)) {
    173                     continue;
    174                 }
    175                 final String formattedNumber = PhoneNumberUtilsCompat.formatNumber(
    176                         phoneNumber, phone.getPhoneNormalizedNumber(),
    177                         GeoUtil.getCurrentCountryIso(getContext()));
    178                 CharSequence phoneType = null;
    179                 if (phone.hasPhoneType()) {
    180                     phoneType = Phone.getTypeLabel(
    181                             res, phone.getPhoneType(), phone.getPhoneLabel());
    182                 }
    183                 bindData(phoneDrawable, phoneContentDescription, formattedNumber, phoneType,
    184                         isFirstPhoneBound, true);
    185                 isFirstPhoneBound = false;
    186             }
    187         }
    188 
    189         // Emails
    190         final ArrayList<ValuesDelta> emails = state.getMimeEntries(Email.CONTENT_ITEM_TYPE);
    191         final Drawable emailDrawable = getResources().getDrawable(R.drawable.ic_email_24dp);
    192         final String emailContentDescription = res.getString(R.string.header_email_entry);
    193         if (emails != null) {
    194             boolean isFirstEmailBound = true;
    195             for (ValuesDelta email : emails) {
    196                 final String emailAddress = email.getEmailData();
    197                 if (TextUtils.isEmpty(emailAddress)) {
    198                     continue;
    199                 }
    200                 CharSequence emailType = null;
    201                 if (email.hasEmailType()) {
    202                     emailType = Email.getTypeLabel(
    203                             res, email.getEmailType(), email.getEmailLabel());
    204                 }
    205                 bindData(emailDrawable, emailContentDescription, emailAddress, emailType,
    206                         isFirstEmailBound);
    207                 isFirstEmailBound = false;
    208             }
    209         }
    210 
    211         // Hide mGeneral if it's empty
    212         if (mGeneral.getChildCount() > 0) {
    213             mGeneral.setVisibility(View.VISIBLE);
    214         } else {
    215             mGeneral.setVisibility(View.GONE);
    216         }
    217     }
    218 
    219     private void bindData(Drawable icon, String iconContentDescription, CharSequence data,
    220             CharSequence type, boolean isFirstEntry) {
    221         bindData(icon, iconContentDescription, data, type, isFirstEntry, false);
    222     }
    223 
    224     private void bindData(Drawable icon, String iconContentDescription, CharSequence data,
    225             CharSequence type, boolean isFirstEntry, boolean forceLTR) {
    226         final View field = mInflater.inflate(R.layout.item_read_only_field, mGeneral, false);
    227         if (isFirstEntry) {
    228             final ImageView imageView = (ImageView) field.findViewById(R.id.kind_icon);
    229             imageView.setImageDrawable(icon);
    230             imageView.setContentDescription(iconContentDescription);
    231         } else {
    232             final ImageView imageView = (ImageView) field.findViewById(R.id.kind_icon);
    233             imageView.setVisibility(View.INVISIBLE);
    234             imageView.setContentDescription(null);
    235         }
    236         final TextView dataView = (TextView) field.findViewById(R.id.data);
    237         dataView.setText(data);
    238         if (forceLTR) {
    239             dataView.setTextDirection(View.TEXT_DIRECTION_LTR);
    240         }
    241         final TextView typeView = (TextView) field.findViewById(R.id.type);
    242         if (!TextUtils.isEmpty(type)) {
    243             typeView.setText(type);
    244         } else {
    245             typeView.setVisibility(View.GONE);
    246         }
    247 
    248         mGeneral.addView(field);
    249     }
    250 
    251     @Override
    252     public long getRawContactId() {
    253         return mRawContactId;
    254     }
    255 
    256     @Override
    257     public void onClick(View v) {
    258         if (v.getId() == R.id.button_edit_externally) {
    259             if (mListener != null) {
    260                 mListener.onExternalEditorRequest(
    261                         new AccountWithDataSet(mAccountName, mAccountType, mDataSet),
    262                         ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactId));
    263             }
    264         }
    265     }
    266 }
    267