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.net.Uri;
     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 import android.widget.Toast;
     39 
     40 import com.android.contacts.R;
     41 import com.android.contacts.common.GeoUtil;
     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 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 RawContactDelta} state and the {@link AccountType} that
    112      * apply to that state.
    113      */
    114     @Override
    115     public void setState(RawContactDelta 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         RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
    125 
    126         // Fill in the header info
    127         mAccountName = state.getAccountName();
    128         mAccountType = state.getAccountType();
    129         mDataSet = state.getDataSet();
    130 
    131         if (isProfile) {
    132             if (TextUtils.isEmpty(mAccountName)) {
    133                 mAccountNameTextView.setVisibility(View.GONE);
    134                 mAccountTypeTextView.setText(R.string.local_profile_title);
    135             } else {
    136                 CharSequence accountType = type.getDisplayLabel(mContext);
    137                 mAccountTypeTextView.setText(mContext.getString(R.string.external_profile_title,
    138                         accountType));
    139                 mAccountNameTextView.setText(mAccountName);
    140             }
    141         } else {
    142             CharSequence accountType = type.getDisplayLabel(mContext);
    143             if (TextUtils.isEmpty(accountType)) {
    144                 accountType = mContext.getString(R.string.account_phone);
    145             }
    146             if (!TextUtils.isEmpty(mAccountName)) {
    147                 mAccountNameTextView.setVisibility(View.VISIBLE);
    148                 mAccountNameTextView.setText(
    149                         mContext.getString(R.string.from_account_format, mAccountName));
    150             } else {
    151                 // Hide this view so the other text view will be centered vertically
    152                 mAccountNameTextView.setVisibility(View.GONE);
    153             }
    154             mAccountTypeTextView.setText(mContext.getString(R.string.account_type_format,
    155                     accountType));
    156         }
    157         mAccountTypeTextView.setTextColor(mContext.getResources().getColor(
    158                 R.color.secondary_text_color));
    159 
    160         // TODO: Expose data set in the UI somehow?
    161 
    162         mAccountIcon.setImageDrawable(type.getDisplayIcon(mContext));
    163 
    164         mRawContactId = state.getRawContactId();
    165 
    166         ValuesDelta primary;
    167 
    168         // Photo
    169         DataKind kind = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
    170         if (kind != null) {
    171             RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
    172             boolean hasPhotoEditor = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null;
    173             setHasPhotoEditor(hasPhotoEditor);
    174             primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
    175             getPhotoEditor().setValues(kind, primary, state, !type.areContactsWritable(), vig);
    176         }
    177 
    178         // Name
    179         primary = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
    180         mName.setText(primary != null ? primary.getAsString(StructuredName.DISPLAY_NAME) :
    181                 mContext.getString(R.string.missing_name));
    182 
    183         if (type.getEditContactActivityClassName() != null) {
    184             mAccountContainer.setBackgroundDrawable(null);
    185             mAccountContainer.setEnabled(false);
    186             mEditExternallyButton.setVisibility(View.VISIBLE);
    187         } else {
    188             mAccountContainer.setOnClickListener(new OnClickListener() {
    189                 @Override
    190                 public void onClick(View v) {
    191                     Toast.makeText(mContext, mContext.getString(R.string.contact_read_only),
    192                             Toast.LENGTH_SHORT).show();
    193                 }
    194             });
    195             mEditExternallyButton.setVisibility(View.GONE);
    196         }
    197 
    198         final Resources res = mContext.getResources();
    199         // Phones
    200         ArrayList<ValuesDelta> phones = state.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
    201         if (phones != null) {
    202             for (int i = 0; i < phones.size(); i++) {
    203                 ValuesDelta phone = phones.get(i);
    204                 final String phoneNumber = PhoneNumberUtils.formatNumber(
    205                         phone.getPhoneNumber(),
    206                         phone.getPhoneNormalizedNumber(),
    207                         GeoUtil.getCurrentCountryIso(getContext()));
    208                 final CharSequence phoneType;
    209                 if (phone.phoneHasType()) {
    210                     phoneType = Phone.getTypeLabel(
    211                             res, phone.getPhoneType(), phone.getPhoneLabel());
    212                 } else {
    213                     phoneType = null;
    214                 }
    215                 bindData(mContext.getText(R.string.phoneLabelsGroup), phoneNumber, phoneType,
    216                         i == 0, true);
    217             }
    218         }
    219 
    220         // Emails
    221         ArrayList<ValuesDelta> emails = state.getMimeEntries(Email.CONTENT_ITEM_TYPE);
    222         if (emails != null) {
    223             for (int i = 0; i < emails.size(); i++) {
    224                 ValuesDelta email = emails.get(i);
    225                 final String emailAddress = email.getEmailData();
    226                 final CharSequence emailType;
    227                 if (email.emailHasType()) {
    228                     emailType = Email.getTypeLabel(
    229                             res, email.getEmailType(), email.getEmailLabel());
    230                 } else {
    231                     emailType = null;
    232                 }
    233                 bindData(mContext.getText(R.string.emailLabelsGroup), emailAddress, emailType,
    234                         i == 0);
    235             }
    236         }
    237 
    238         // Hide mGeneral if it's empty
    239         if (mGeneral.getChildCount() > 0) {
    240             mGeneral.setVisibility(View.VISIBLE);
    241         } else {
    242             mGeneral.setVisibility(View.GONE);
    243         }
    244     }
    245 
    246     private void bindData(CharSequence titleText, CharSequence data, CharSequence type,
    247             boolean isFirstEntry) {
    248         bindData(titleText, data, type, isFirstEntry, false);
    249     }
    250 
    251     private void bindData(CharSequence titleText, CharSequence data, CharSequence type,
    252             boolean isFirstEntry, boolean forceLTR) {
    253         final View field = mInflater.inflate(R.layout.item_read_only_field, mGeneral, false);
    254         final View divider = field.findViewById(R.id.divider);
    255         if (isFirstEntry) {
    256             final TextView titleView = (TextView) field.findViewById(R.id.kind_title);
    257             titleView.setText(titleText);
    258             divider.setVisibility(View.GONE);
    259         } else {
    260             View titleContainer = field.findViewById(R.id.kind_title_layout);
    261             titleContainer.setVisibility(View.GONE);
    262             divider.setVisibility(View.VISIBLE);
    263         }
    264         final TextView dataView = (TextView) field.findViewById(R.id.data);
    265         dataView.setText(data);
    266         if (forceLTR) {
    267             dataView.setTextDirection(View.TEXT_DIRECTION_LTR);
    268         }
    269         final TextView typeView = (TextView) field.findViewById(R.id.type);
    270         if (!TextUtils.isEmpty(type)) {
    271             typeView.setText(type);
    272         } else {
    273             typeView.setVisibility(View.GONE);
    274         }
    275 
    276         mGeneral.addView(field);
    277     }
    278 
    279     @Override
    280     public long getRawContactId() {
    281         return mRawContactId;
    282     }
    283 
    284     @Override
    285     public void onClick(View v) {
    286         if (v.getId() == R.id.button_edit_externally) {
    287             if (mListener != null) {
    288                 mListener.onExternalEditorRequest(
    289                         new AccountWithDataSet(mAccountName, mAccountType, mDataSet),
    290                         ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactId));
    291             }
    292         }
    293     }
    294 }
    295