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 com.android.contacts.ContactsUtils;
     20 import com.android.contacts.R;
     21 import com.android.contacts.model.AccountType;
     22 import com.android.contacts.model.AccountWithDataSet;
     23 import com.android.contacts.model.DataKind;
     24 import com.android.contacts.model.EntityDelta;
     25 import com.android.contacts.model.EntityDelta.ValuesDelta;
     26 import com.android.contacts.model.EntityModifier;
     27 
     28 import android.content.ContentUris;
     29 import android.content.Context;
     30 import android.content.res.Resources;
     31 import android.net.Uri;
     32 import android.provider.ContactsContract.CommonDataKinds.Email;
     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.RawContacts;
     37 import android.telephony.PhoneNumberUtils;
     38 import android.text.TextUtils;
     39 import android.util.AttributeSet;
     40 import android.view.LayoutInflater;
     41 import android.view.View;
     42 import android.view.View.OnClickListener;
     43 import android.view.ViewGroup;
     44 import android.widget.Button;
     45 import android.widget.ImageView;
     46 import android.widget.TextView;
     47 import android.widget.Toast;
     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 View mAccountContainer;
     63     private ImageView mAccountIcon;
     64     private TextView mAccountTypeTextView;
     65     private TextView mAccountNameTextView;
     66 
     67     private String mAccountName;
     68     private String mAccountType;
     69     private String mDataSet;
     70     private long mRawContactId = -1;
     71 
     72     private Listener mListener;
     73 
     74     public interface Listener {
     75         void onExternalEditorRequest(AccountWithDataSet account, Uri uri);
     76     }
     77 
     78     public RawContactReadOnlyEditorView(Context context) {
     79         super(context);
     80     }
     81 
     82     public RawContactReadOnlyEditorView(Context context, AttributeSet attrs) {
     83         super(context, attrs);
     84     }
     85 
     86     public void setListener(Listener listener) {
     87         mListener = listener;
     88     }
     89 
     90     /** {@inheritDoc} */
     91     @Override
     92     protected void onFinishInflate() {
     93         super.onFinishInflate();
     94 
     95         mInflater = (LayoutInflater)getContext().getSystemService(
     96                 Context.LAYOUT_INFLATER_SERVICE);
     97 
     98         mName = (TextView) findViewById(R.id.read_only_name);
     99         mEditExternallyButton = (Button) findViewById(R.id.button_edit_externally);
    100         mEditExternallyButton.setOnClickListener(this);
    101         mGeneral = (ViewGroup)findViewById(R.id.sect_general);
    102 
    103         mAccountContainer = findViewById(R.id.account_container);
    104         mAccountIcon = (ImageView) findViewById(R.id.account_icon);
    105         mAccountTypeTextView = (TextView) findViewById(R.id.account_type);
    106         mAccountNameTextView = (TextView) findViewById(R.id.account_name);
    107     }
    108 
    109     /**
    110      * Set the internal state for this view, given a current
    111      * {@link EntityDelta} state and the {@link AccountType} that
    112      * apply to that state.
    113      */
    114     @Override
    115     public void setState(EntityDelta state, AccountType type, ViewIdGenerator vig,
    116             boolean isProfile) {
    117         // Remove any existing sections
    118         mGeneral.removeAllViews();
    119 
    120         // Bail if invalid state or source
    121         if (state == null || type == null) return;
    122 
    123         // Make sure we have StructuredName
    124         EntityModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
    125 
    126         // Fill in the header info
    127         ValuesDelta values = state.getValues();
    128         mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
    129         mAccountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
    130         mDataSet = values.getAsString(RawContacts.DATA_SET);
    131 
    132         if (isProfile) {
    133             if (TextUtils.isEmpty(mAccountName)) {
    134                 mAccountNameTextView.setVisibility(View.GONE);
    135                 mAccountTypeTextView.setText(R.string.local_profile_title);
    136             } else {
    137                 CharSequence accountType = type.getDisplayLabel(mContext);
    138                 mAccountTypeTextView.setText(mContext.getString(R.string.external_profile_title,
    139                         accountType));
    140                 mAccountNameTextView.setText(mAccountName);
    141             }
    142         } else {
    143             CharSequence accountType = type.getDisplayLabel(mContext);
    144             if (TextUtils.isEmpty(accountType)) {
    145                 accountType = mContext.getString(R.string.account_phone);
    146             }
    147             if (!TextUtils.isEmpty(mAccountName)) {
    148                 mAccountNameTextView.setVisibility(View.VISIBLE);
    149                 mAccountNameTextView.setText(
    150                         mContext.getString(R.string.from_account_format, mAccountName));
    151             } else {
    152                 // Hide this view so the other text view will be centered vertically
    153                 mAccountNameTextView.setVisibility(View.GONE);
    154             }
    155             mAccountTypeTextView.setText(mContext.getString(R.string.account_type_format,
    156                     accountType));
    157         }
    158         mAccountTypeTextView.setTextColor(mContext.getResources().getColor(
    159                 R.color.secondary_text_color));
    160 
    161         // TODO: Expose data set in the UI somehow?
    162 
    163         mAccountIcon.setImageDrawable(type.getDisplayIcon(mContext));
    164 
    165         mRawContactId = values.getAsLong(RawContacts._ID);
    166 
    167         ValuesDelta primary;
    168 
    169         // Photo
    170         DataKind kind = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
    171         if (kind != null) {
    172             EntityModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
    173             boolean hasPhotoEditor = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null;
    174             setHasPhotoEditor(hasPhotoEditor);
    175             primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
    176             getPhotoEditor().setValues(kind, primary, state, !type.areContactsWritable(), vig);
    177         }
    178 
    179         // Name
    180         primary = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
    181         mName.setText(primary != null ? primary.getAsString(StructuredName.DISPLAY_NAME) :
    182                 mContext.getString(R.string.missing_name));
    183 
    184         if (type.getEditContactActivityClassName() != null) {
    185             mAccountContainer.setBackgroundDrawable(null);
    186             mAccountContainer.setEnabled(false);
    187             mEditExternallyButton.setVisibility(View.VISIBLE);
    188         } else {
    189             mAccountContainer.setOnClickListener(new OnClickListener() {
    190                 @Override
    191                 public void onClick(View v) {
    192                     Toast.makeText(mContext, mContext.getString(R.string.contact_read_only),
    193                             Toast.LENGTH_SHORT).show();
    194                 }
    195             });
    196             mEditExternallyButton.setVisibility(View.GONE);
    197         }
    198 
    199         final Resources res = mContext.getResources();
    200         // Phones
    201         ArrayList<ValuesDelta> phones = state.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
    202         if (phones != null) {
    203             for (int i = 0; i < phones.size(); i++) {
    204                 ValuesDelta phone = phones.get(i);
    205                 final String phoneNumber = PhoneNumberUtils.formatNumber(
    206                         phone.getAsString(Phone.NUMBER),
    207                         phone.getAsString(Phone.NORMALIZED_NUMBER),
    208                         ContactsUtils.getCurrentCountryIso(getContext()));
    209                 final CharSequence phoneType;
    210                 if (phone.containsKey(Phone.TYPE)) {
    211                     phoneType = Phone.getTypeLabel(
    212                             res, phone.getAsInteger(Phone.TYPE), phone.getAsString(Phone.LABEL));
    213                 } else {
    214                     phoneType = null;
    215                 }
    216                 bindData(mContext.getText(R.string.phoneLabelsGroup),
    217                         phoneNumber, phoneType, i == 0);
    218             }
    219         }
    220 
    221         // Emails
    222         ArrayList<ValuesDelta> emails = state.getMimeEntries(Email.CONTENT_ITEM_TYPE);
    223         if (emails != null) {
    224             for (int i = 0; i < emails.size(); i++) {
    225                 ValuesDelta email = emails.get(i);
    226                 final String emailAddress = email.getAsString(Email.DATA);
    227                 final CharSequence emailType;
    228                 if (email.containsKey(Email.TYPE)) {
    229                     emailType = Email.getTypeLabel(
    230                             res, email.getAsInteger(Email.TYPE), email.getAsString(Email.LABEL));
    231                 } else {
    232                     emailType = null;
    233                 }
    234                 bindData(mContext.getText(R.string.emailLabelsGroup), emailAddress, emailType,
    235                         i == 0);
    236             }
    237         }
    238 
    239         // Hide mGeneral if it's empty
    240         if (mGeneral.getChildCount() > 0) {
    241             mGeneral.setVisibility(View.VISIBLE);
    242         } else {
    243             mGeneral.setVisibility(View.GONE);
    244         }
    245     }
    246 
    247     private void bindData(
    248             CharSequence titleText, CharSequence data, CharSequence type, boolean isFirstEntry) {
    249         final View field = mInflater.inflate(R.layout.item_read_only_field, mGeneral, false);
    250         final View divider = field.findViewById(R.id.divider);
    251         if (isFirstEntry) {
    252             final TextView titleView = (TextView) field.findViewById(R.id.kind_title);
    253             titleView.setText(titleText);
    254             divider.setVisibility(View.GONE);
    255         } else {
    256             View titleContainer = field.findViewById(R.id.kind_title_layout);
    257             titleContainer.setVisibility(View.GONE);
    258             divider.setVisibility(View.VISIBLE);
    259         }
    260         final TextView dataView = (TextView) field.findViewById(R.id.data);
    261         dataView.setText(data);
    262         final TextView typeView = (TextView) field.findViewById(R.id.type);
    263         if (!TextUtils.isEmpty(type)) {
    264             typeView.setText(type);
    265         } else {
    266             typeView.setVisibility(View.GONE);
    267         }
    268 
    269         mGeneral.addView(field);
    270     }
    271 
    272     @Override
    273     public long getRawContactId() {
    274         return mRawContactId;
    275     }
    276 
    277     @Override
    278     public void onClick(View v) {
    279         if (v.getId() == R.id.button_edit_externally) {
    280             if (mListener != null) {
    281                 mListener.onExternalEditorRequest(
    282                         new AccountWithDataSet(mAccountName, mAccountType, mDataSet),
    283                         ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactId));
    284             }
    285         }
    286     }
    287 }
    288