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 RawContactReadOnlyEditorView(Context context)69 public RawContactReadOnlyEditorView(Context context) { 70 super(context); 71 } 72 RawContactReadOnlyEditorView(Context context, AttributeSet attrs)73 public RawContactReadOnlyEditorView(Context context, AttributeSet attrs) { 74 super(context, attrs); 75 } 76 77 78 /** {@inheritDoc} */ 79 @Override onFinishInflate()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 setState(RawContactDelta state, AccountType type, ViewIdGenerator vig, boolean isProfile)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 bindData(Drawable icon, String iconContentDescription, CharSequence data, CharSequence type, boolean isFirstEntry)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 bindData(Drawable icon, String iconContentDescription, CharSequence data, CharSequence type, boolean isFirstEntry, boolean forceLTR)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 getRawContactId()261 public long getRawContactId() { 262 return mRawContactId; 263 } 264 265 @Override onClick(View v)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