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