• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
onExternalEditorRequest(AccountWithDataSet account, Uri uri)75         void onExternalEditorRequest(AccountWithDataSet account, Uri uri);
76     }
77 
RawContactReadOnlyEditorView(Context context)78     public RawContactReadOnlyEditorView(Context context) {
79         super(context);
80     }
81 
RawContactReadOnlyEditorView(Context context, AttributeSet attrs)82     public RawContactReadOnlyEditorView(Context context, AttributeSet attrs) {
83         super(context, attrs);
84     }
85 
setListener(Listener listener)86     public void setListener(Listener listener) {
87         mListener = listener;
88     }
89 
90     /** {@inheritDoc} */
91     @Override
onFinishInflate()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
setState(RawContactDelta state, AccountType type, ViewIdGenerator vig, boolean isProfile)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             boolean isFirstPhoneBound = true;
203             for (ValuesDelta phone : phones) {
204                 final String phoneNumber = phone.getPhoneNumber();
205                 if (TextUtils.isEmpty(phoneNumber)) {
206                     continue;
207                 }
208                 final String formattedNumber = PhoneNumberUtils.formatNumber(
209                         phoneNumber, phone.getPhoneNormalizedNumber(),
210                         GeoUtil.getCurrentCountryIso(getContext()));
211                 CharSequence phoneType = null;
212                 if (phone.phoneHasType()) {
213                     phoneType = Phone.getTypeLabel(
214                             res, phone.getPhoneType(), phone.getPhoneLabel());
215                 }
216                 bindData(mContext.getText(R.string.phoneLabelsGroup), formattedNumber,
217                         phoneType, isFirstPhoneBound, true);
218                 isFirstPhoneBound = false;
219             }
220         }
221 
222         // Emails
223         ArrayList<ValuesDelta> emails = state.getMimeEntries(Email.CONTENT_ITEM_TYPE);
224         if (emails != null) {
225             boolean isFirstEmailBound = true;
226             for (ValuesDelta email : emails) {
227                 final String emailAddress = email.getEmailData();
228                 if (TextUtils.isEmpty(emailAddress)) {
229                     continue;
230                 }
231                 CharSequence emailType = null;
232                 if (email.emailHasType()) {
233                     emailType = Email.getTypeLabel(
234                             res, email.getEmailType(), email.getEmailLabel());
235                 }
236                 bindData(mContext.getText(R.string.emailLabelsGroup), emailAddress, emailType,
237                         isFirstEmailBound);
238                 isFirstEmailBound = false;
239             }
240         }
241 
242         // Hide mGeneral if it's empty
243         if (mGeneral.getChildCount() > 0) {
244             mGeneral.setVisibility(View.VISIBLE);
245         } else {
246             mGeneral.setVisibility(View.GONE);
247         }
248     }
249 
bindData(CharSequence titleText, CharSequence data, CharSequence type, boolean isFirstEntry)250     private void bindData(CharSequence titleText, CharSequence data, CharSequence type,
251             boolean isFirstEntry) {
252         bindData(titleText, data, type, isFirstEntry, false);
253     }
254 
bindData(CharSequence titleText, CharSequence data, CharSequence type, boolean isFirstEntry, boolean forceLTR)255     private void bindData(CharSequence titleText, CharSequence data, CharSequence type,
256             boolean isFirstEntry, boolean forceLTR) {
257         final View field = mInflater.inflate(R.layout.item_read_only_field, mGeneral, false);
258         final View divider = field.findViewById(R.id.divider);
259         if (isFirstEntry) {
260             final TextView titleView = (TextView) field.findViewById(R.id.kind_title);
261             titleView.setText(titleText);
262             divider.setVisibility(View.GONE);
263         } else {
264             View titleContainer = field.findViewById(R.id.kind_title_layout);
265             titleContainer.setVisibility(View.GONE);
266             divider.setVisibility(View.VISIBLE);
267         }
268         final TextView dataView = (TextView) field.findViewById(R.id.data);
269         dataView.setText(data);
270         if (forceLTR) {
271             dataView.setTextDirection(View.TEXT_DIRECTION_LTR);
272         }
273         final TextView typeView = (TextView) field.findViewById(R.id.type);
274         if (!TextUtils.isEmpty(type)) {
275             typeView.setText(type);
276         } else {
277             typeView.setVisibility(View.GONE);
278         }
279 
280         mGeneral.addView(field);
281     }
282 
283     @Override
getRawContactId()284     public long getRawContactId() {
285         return mRawContactId;
286     }
287 
288     @Override
onClick(View v)289     public void onClick(View v) {
290         if (v.getId() == R.id.button_edit_externally) {
291             if (mListener != null) {
292                 mListener.onExternalEditorRequest(
293                         new AccountWithDataSet(mAccountName, mAccountType, mDataSet),
294                         ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactId));
295             }
296         }
297     }
298 }
299