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