blob: b91671cae51c43a8efc32752f2260b210f37216c [file] [log] [blame]
Walter Jangcab3dce2015-02-09 17:48:03 -08001/*
2 * Copyright (C) 2015 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
17package com.android.contacts.editor;
18
19import com.android.contacts.R;
20import com.android.contacts.common.model.AccountTypeManager;
21import com.android.contacts.common.model.RawContactDelta;
22import com.android.contacts.common.model.RawContactDeltaList;
Walter Jange720fde2015-02-17 10:54:14 -080023import com.android.contacts.common.model.RawContactModifier;
Walter Jangcab3dce2015-02-09 17:48:03 -080024import com.android.contacts.common.model.ValuesDelta;
25import com.android.contacts.common.model.account.AccountType;
26import com.android.contacts.common.model.account.AccountType.EditField;
Walter Jang2d3f31c2015-06-18 23:15:31 -070027import com.android.contacts.common.model.account.AccountWithDataSet;
Walter Jangcab3dce2015-02-09 17:48:03 -080028import com.android.contacts.common.model.dataitem.DataKind;
Walter Jangf46abd82015-02-20 16:52:04 -080029import com.android.contacts.common.util.MaterialColorMapUtils;
Walter Jang3efae4a2015-02-18 11:12:00 -080030import com.android.contacts.editor.CompactContactEditorFragment.PhotoHandler;
Walter Jangcab3dce2015-02-09 17:48:03 -080031
32import android.content.Context;
Walter Jang3efae4a2015-02-18 11:12:00 -080033import android.graphics.Bitmap;
Walter Jang41b3ea12015-03-09 17:30:06 -070034import android.net.Uri;
Walter Jangcab3dce2015-02-09 17:48:03 -080035import android.provider.ContactsContract.CommonDataKinds.Email;
36import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
Walter Jang3efae4a2015-02-18 11:12:00 -080037import android.provider.ContactsContract.CommonDataKinds.Nickname;
Walter Jangcab3dce2015-02-09 17:48:03 -080038import android.provider.ContactsContract.CommonDataKinds.Phone;
39import android.provider.ContactsContract.CommonDataKinds.Photo;
Walter Jangcab3dce2015-02-09 17:48:03 -080040import android.provider.ContactsContract.CommonDataKinds.StructuredName;
41import android.text.TextUtils;
42import android.util.AttributeSet;
43import android.util.Log;
Walter Jang2d3f31c2015-06-18 23:15:31 -070044import android.util.Pair;
Walter Jangcab3dce2015-02-09 17:48:03 -080045import android.view.LayoutInflater;
Walter Jangb1c87622015-02-13 17:51:38 -080046import android.view.View;
Walter Jangcab3dce2015-02-09 17:48:03 -080047import android.view.ViewGroup;
48import android.widget.LinearLayout;
Walter Jang2d3f31c2015-06-18 23:15:31 -070049import android.widget.TextView;
Walter Jangcab3dce2015-02-09 17:48:03 -080050
51import java.util.ArrayList;
Walter Jang19d985f2015-07-01 13:36:27 -070052import java.util.HashMap;
Walter Jangcab3dce2015-02-09 17:48:03 -080053import java.util.List;
Walter Jang19d985f2015-07-01 13:36:27 -070054import java.util.Map;
Walter Jangcab3dce2015-02-09 17:48:03 -080055
56/**
57 * View to display information from multiple {@link RawContactDelta}s grouped together
58 * (e.g. all the phone numbers from a {@link com.android.contacts.common.model.Contact} together.
59 */
Walter Jangb6ca2722015-02-20 11:10:25 -080060public class CompactRawContactsEditorView extends LinearLayout implements View.OnClickListener {
Walter Jangcab3dce2015-02-09 17:48:03 -080061
62 private static final String TAG = "CompactEditorView";
63
Walter Jangb6ca2722015-02-20 11:10:25 -080064 /**
65 * Callbacks for hosts of {@link CompactRawContactsEditorView}s.
66 */
67 public interface Listener {
68
69 /**
70 * Invoked when the compact editor should be expanded to show all fields.
71 */
72 public void onExpandEditor();
Walter Jang151f3e62015-02-26 15:29:40 -080073
74 /**
75 * Invoked when the structured name editor field has changed.
76 *
77 * @param rawContactId The raw contact ID from the underlying {@link RawContactDelta}.
78 * @param valuesDelta The values from the underlying {@link RawContactDelta}.
79 */
80 public void onNameFieldChanged(long rawContactId, ValuesDelta valuesDelta);
81 }
82
83 /**
84 * Marks a name as super primary when it is changed.
85 *
86 * This is for the case when two or more raw contacts with names are joined where neither is
87 * marked as super primary. If the user hits back (which causes a save) after changing the
88 * name that was arbitrarily displayed, we want that to be the name that is used.
89 *
90 * Should only be set when a super primary name does not already exist since we only show
91 * one name field.
92 */
93 static final class NameEditorListener implements Editor.EditorListener {
94
95 private final ValuesDelta mValuesDelta;
96 private final long mRawContactId;
97 private final Listener mListener;
98
99 public NameEditorListener(ValuesDelta valuesDelta, long rawContactId,
100 Listener listener) {
101 mValuesDelta = valuesDelta;
102 mRawContactId = rawContactId;
103 mListener = listener;
104 }
105
106 @Override
107 public void onRequest(int request) {
108 if (request == Editor.EditorListener.FIELD_CHANGED) {
109 mValuesDelta.setSuperPrimary(true);
110 if (mListener != null) {
111 mListener.onNameFieldChanged(mRawContactId, mValuesDelta);
112 }
113 } else if (request == Editor.EditorListener.FIELD_TURNED_EMPTY) {
114 mValuesDelta.setSuperPrimary(false);
115 }
116 }
117
118 @Override
119 public void onDeleteRequested(Editor editor) {
120 }
Walter Jangb6ca2722015-02-20 11:10:25 -0800121 }
122
123 private Listener mListener;
124
Walter Jangcab3dce2015-02-09 17:48:03 -0800125 private AccountTypeManager mAccountTypeManager;
126 private LayoutInflater mLayoutInflater;
Walter Jangd35e5ef2015-02-24 09:18:16 -0800127
Walter Jangcab3dce2015-02-09 17:48:03 -0800128 private ViewIdGenerator mViewIdGenerator;
Walter Jangf46abd82015-02-20 16:52:04 -0800129 private MaterialColorMapUtils.MaterialPalette mMaterialPalette;
Walter Jangcab3dce2015-02-09 17:48:03 -0800130
Walter Jang2d3f31c2015-06-18 23:15:31 -0700131 private View mAccountContainer;
132 private TextView mAccountTypeView;
133 private TextView mAccountNameView;
Walter Janga5e4bb22015-02-24 13:08:16 -0800134 private CompactPhotoEditorView mPhoto;
Walter Jangcab3dce2015-02-09 17:48:03 -0800135 private ViewGroup mNames;
Walter Jangb1c87622015-02-13 17:51:38 -0800136 private ViewGroup mPhoneticNames;
137 private ViewGroup mNicknames;
Walter Jangcab3dce2015-02-09 17:48:03 -0800138 private ViewGroup mPhoneNumbers;
139 private ViewGroup mEmails;
140 private ViewGroup mOther;
Walter Jang19d985f2015-07-01 13:36:27 -0700141 private Map<String,LinearLayout> mOtherMap = new HashMap<>();
Walter Jangb6ca2722015-02-20 11:10:25 -0800142 private View mMoreFields;
Walter Jangcab3dce2015-02-09 17:48:03 -0800143
Walter Jang151f3e62015-02-26 15:29:40 -0800144 // The ValuesDelta for the non super primary name that was displayed to the user.
145 private ValuesDelta mNameValuesDelta;
146
Walter Jang3efae4a2015-02-18 11:12:00 -0800147 private long mPhotoRawContactId;
148
Walter Jang06f73a12015-06-17 11:15:48 -0700149 private StructuredNameEditorView mDefaultNameEditorView;
150
Walter Jangcab3dce2015-02-09 17:48:03 -0800151 public CompactRawContactsEditorView(Context context) {
152 super(context);
153 }
154
155 public CompactRawContactsEditorView(Context context, AttributeSet attrs) {
156 super(context, attrs);
157 }
158
Walter Jangb6ca2722015-02-20 11:10:25 -0800159 /**
160 * Sets the receiver for {@link CompactRawContactsEditorView} callbacks.
161 */
162 public void setListener(Listener listener) {
163 mListener = listener;
164 }
165
Walter Jangcab3dce2015-02-09 17:48:03 -0800166 @Override
167 protected void onFinishInflate() {
168 super.onFinishInflate();
169
170 mAccountTypeManager = AccountTypeManager.getInstance(getContext());
171 mLayoutInflater = (LayoutInflater)
172 getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
173
Walter Jang2d3f31c2015-06-18 23:15:31 -0700174 mAccountContainer = findViewById(R.id.account_container);
175 mAccountTypeView = (TextView) findViewById(R.id.account_type);
176 mAccountNameView = (TextView) findViewById(R.id.account_name);
Walter Janga5e4bb22015-02-24 13:08:16 -0800177 mPhoto = (CompactPhotoEditorView) findViewById(R.id.photo_editor);
Walter Jangcab3dce2015-02-09 17:48:03 -0800178 mNames = (LinearLayout) findViewById(R.id.names);
Walter Jangb1c87622015-02-13 17:51:38 -0800179 mPhoneticNames = (LinearLayout) findViewById(R.id.phonetic_names);
180 mNicknames = (LinearLayout) findViewById(R.id.nicknames);
Walter Jangcab3dce2015-02-09 17:48:03 -0800181 mPhoneNumbers = (LinearLayout) findViewById(R.id.phone_numbers);
182 mEmails = (LinearLayout) findViewById(R.id.emails);
183 mOther = (LinearLayout) findViewById(R.id.other);
Walter Jangb6ca2722015-02-20 11:10:25 -0800184 mMoreFields = findViewById(R.id.more_fields);
185 mMoreFields.setOnClickListener(this);
186 }
187
Walter Jangb6ca2722015-02-20 11:10:25 -0800188 @Override
189 public void onClick(View view) {
190 if (view.getId() == R.id.more_fields && mListener != null ) {
191 mListener.onExpandEditor();
192 }
Walter Jangcab3dce2015-02-09 17:48:03 -0800193 }
194
195 @Override
196 public void setEnabled(boolean enabled) {
197 super.setEnabled(enabled);
198 setEnabled(enabled, mNames);
Walter Jangb1c87622015-02-13 17:51:38 -0800199 setEnabled(enabled, mPhoneticNames);
200 setEnabled(enabled, mNicknames);
Walter Jangcab3dce2015-02-09 17:48:03 -0800201 setEnabled(enabled, mPhoneNumbers);
202 setEnabled(enabled, mEmails);
Walter Jang19d985f2015-07-01 13:36:27 -0700203 for (Map.Entry<String,LinearLayout> other : mOtherMap.entrySet()) {
204 setEnabled(enabled, other.getValue());
205 }
Walter Jangcab3dce2015-02-09 17:48:03 -0800206 }
207
208 private void setEnabled(boolean enabled, ViewGroup viewGroup) {
209 if (viewGroup != null) {
210 final int childCount = viewGroup.getChildCount();
211 for (int i = 0; i < childCount; i++) {
212 viewGroup.getChildAt(i).setEnabled(enabled);
213 }
214 }
215 }
216
Walter Jang3efae4a2015-02-18 11:12:00 -0800217 /**
Walter Janga5e4bb22015-02-24 13:08:16 -0800218 * Pass through to {@link CompactPhotoEditorView#setPhotoHandler}.
Walter Jang3efae4a2015-02-18 11:12:00 -0800219 */
220 public void setPhotoHandler(PhotoHandler photoHandler) {
Walter Janga5e4bb22015-02-24 13:08:16 -0800221 mPhoto.setPhotoHandler(photoHandler);
Walter Jang3efae4a2015-02-18 11:12:00 -0800222 }
223
224 /**
Walter Janga5e4bb22015-02-24 13:08:16 -0800225 * Pass through to {@link CompactPhotoEditorView#setPhoto}.
Walter Jang3efae4a2015-02-18 11:12:00 -0800226 */
227 public void setPhoto(Bitmap bitmap) {
Walter Janga5e4bb22015-02-24 13:08:16 -0800228 mPhoto.setPhoto(bitmap);
Walter Jang3efae4a2015-02-18 11:12:00 -0800229 }
230
231 /**
Walter Jang41b3ea12015-03-09 17:30:06 -0700232 * Pass through to {@link CompactPhotoEditorView#setFullSizedPhoto(Uri)}.
233 */
234 public void setFullSizePhoto(Uri photoUri) {
235 mPhoto.setFullSizedPhoto(photoUri);
236 }
237
238 /**
Walter Janga5e4bb22015-02-24 13:08:16 -0800239 * Pass through to {@link CompactPhotoEditorView#isWritablePhotoSet}.
Walter Jang3efae4a2015-02-18 11:12:00 -0800240 */
241 public boolean isWritablePhotoSet() {
Walter Janga5e4bb22015-02-24 13:08:16 -0800242 return mPhoto.isWritablePhotoSet();
Walter Jang3efae4a2015-02-18 11:12:00 -0800243 }
244
245 /**
Walter Jang3efae4a2015-02-18 11:12:00 -0800246 * Get the raw contact ID for the CompactHeaderView photo.
247 */
Walter Jang3efae4a2015-02-18 11:12:00 -0800248 public long getPhotoRawContactId() {
249 return mPhotoRawContactId;
250 }
251
Walter Jang06f73a12015-06-17 11:15:48 -0700252 public StructuredNameEditorView getDefaultNameEditorView() {
253 return mDefaultNameEditorView;
254 }
255
Walter Jangd35e5ef2015-02-24 09:18:16 -0800256 public StructuredNameEditorView getStructuredNameEditorView() {
257 // We only ever show one StructuredName
258 return mNames.getChildCount() == 0
259 ? null : (StructuredNameEditorView) mNames.getChildAt(0);
260 }
261
Walter Jangbf63a6d2015-05-05 09:14:35 -0700262 public PhoneticNameEditorView getFirstPhoneticNameEditorView() {
263 // There should only ever be one phonetic name
264 return mPhoneticNames.getChildCount() == 0
265 ? null : (PhoneticNameEditorView) mPhoneticNames.getChildAt(0);
266 }
267
Walter Jangd35e5ef2015-02-24 09:18:16 -0800268 public View getAggregationAnchorView() {
269 // Since there is only one structured name we can just return it as the anchor for
270 // the aggregation suggestions popup
271 if (mNames.getChildCount() == 0) {
272 return null;
273 }
274 return mNames.getChildAt(0).findViewById(R.id.anchor_view);
275 }
276
Walter Jang06f73a12015-06-17 11:15:48 -0700277 /**
278 * @param readOnlyDisplayName The display name to set on the new raw contact created in order
279 * to edit a read-only contact.
280 */
Walter Jangf46abd82015-02-20 16:52:04 -0800281 public void setState(RawContactDeltaList rawContactDeltas,
Walter Jang06f73a12015-06-17 11:15:48 -0700282 MaterialColorMapUtils.MaterialPalette materialPalette, ViewIdGenerator viewIdGenerator,
Walter Jang2d3f31c2015-06-18 23:15:31 -0700283 long photoId, long nameId, String readOnlyDisplayName, boolean hasNewContact,
284 boolean isUserProfile) {
Walter Jangcab3dce2015-02-09 17:48:03 -0800285 mNames.removeAllViews();
Walter Jangb1c87622015-02-13 17:51:38 -0800286 mPhoneticNames.removeAllViews();
287 mNicknames.removeAllViews();
Walter Jangcab3dce2015-02-09 17:48:03 -0800288 mPhoneNumbers.removeAllViews();
289 mEmails.removeAllViews();
290 mOther.removeAllViews();
Walter Jang19d985f2015-07-01 13:36:27 -0700291 mOtherMap.clear();
Walter Jangcab3dce2015-02-09 17:48:03 -0800292
293 if (rawContactDeltas == null || rawContactDeltas.isEmpty()) {
294 return;
295 }
296
297 mViewIdGenerator = viewIdGenerator;
Walter Jangcab3dce2015-02-09 17:48:03 -0800298 setId(mViewIdGenerator.getId(rawContactDeltas.get(0), /* dataKind =*/ null,
299 /* valuesDelta =*/ null, ViewIdGenerator.NO_VIEW_INDEX));
Walter Jangf46abd82015-02-20 16:52:04 -0800300 mMaterialPalette = materialPalette;
Walter Jangcab3dce2015-02-09 17:48:03 -0800301
Walter Jangbf63a6d2015-05-05 09:14:35 -0700302 vlog("Setting compact editor state from " + rawContactDeltas);
Walter Jang2d3f31c2015-06-18 23:15:31 -0700303 addAccountInfo(rawContactDeltas, hasNewContact, readOnlyDisplayName, isUserProfile);
Walter Jangfa127a12015-06-18 09:48:18 -0700304 addPhotoView(rawContactDeltas, viewIdGenerator, photoId, readOnlyDisplayName);
Walter Jang06f73a12015-06-17 11:15:48 -0700305 addStructuredNameView(rawContactDeltas, nameId, readOnlyDisplayName);
Walter Jang3efae4a2015-02-18 11:12:00 -0800306 addEditorViews(rawContactDeltas);
Walter Jang19d985f2015-07-01 13:36:27 -0700307 updateKindEditorEmptyFields(mPhoneNumbers);
308 updateKindEditorIcons(mPhoneNumbers);
309 updateKindEditorEmptyFields(mEmails);
310 updateKindEditorIcons(mEmails);
311 for (Map.Entry<String,LinearLayout> other : mOtherMap.entrySet()) {
312 updateKindEditorIcons(other.getValue());
313 }
Walter Jangcab3dce2015-02-09 17:48:03 -0800314 }
315
Walter Jang2d3f31c2015-06-18 23:15:31 -0700316 private void addAccountInfo(RawContactDeltaList rawContactDeltas, boolean hasNewContact,
317 String readOnlyDisplayName, boolean isUserProfile) {
318 // Only show account info for inserts and first time edits of read-only accounts
319 if (!hasNewContact && TextUtils.isEmpty(readOnlyDisplayName)) {
320 vlog("Account info hidden");
321 mAccountContainer.setVisibility(View.GONE);
322 return;
323 }
324
325 // Get the default account
326 final AccountWithDataSet defaultAccountWithDataSet =
327 ContactEditorUtils.getInstance(getContext()).getDefaultAccount();
328 if (defaultAccountWithDataSet == null) {
329 vlog("Account info hidden because default account not set");
330 mAccountContainer.setVisibility(View.GONE);
331 return;
332 }
333
334 // We can assume the first writable raw contact is the newly created one because
335 // inserts have a delta list of size 1 and read-only contacts are should be of size 2
336 RawContactDelta defaultAccountRawContactDelta = null;
337 AccountType accountType = null;
338 for (RawContactDelta rawContactDelta : rawContactDeltas) {
339 if (!rawContactDelta.isVisible()) continue;
340 accountType = rawContactDelta.getAccountType(mAccountTypeManager);
341 if (accountType != null && accountType.areContactsWritable()) {
342 defaultAccountRawContactDelta = rawContactDelta;
343 break;
344 }
345 }
346 if (defaultAccountRawContactDelta == null) {
347 vlog("Account info hidden because no raw contact delta matched");
348 mAccountContainer.setVisibility(View.GONE);
349 return;
350 }
351 if (accountType == null) {
352 vlog("Account info hidden because no account type returned from raw contact delta");
353 mAccountContainer.setVisibility(View.GONE);
354 return;
355 }
356
357 // Get the account information for the default account RawContactDelta
358 final Pair<String,String> accountInfo = EditorUiUtils.getAccountInfo(getContext(),
Walter Jangc4cecc72015-06-25 10:45:50 -0700359 isUserProfile, defaultAccountRawContactDelta.getAccountName(), accountType);
Walter Jang2d3f31c2015-06-18 23:15:31 -0700360
361 // Set the account information already
362 if (accountInfo == null) {
363 vlog("Account info hidden because no account info could be composed");
364 mAccountContainer.setVisibility(View.GONE);
365 return;
366 }
367 vlog("Account info loaded");
368 if (accountInfo.first == null) {
369 mAccountNameView.setVisibility(View.GONE);
370 } else {
371 mAccountNameView.setVisibility(View.VISIBLE);
372 mAccountNameView.setText(accountInfo.first);
373 }
374 mAccountTypeView.setText(accountInfo.second);
375
376 mAccountContainer.setContentDescription(EditorUiUtils.getAccountInfoContentDescription(
377 accountInfo.first, accountInfo.second));
378 }
379
Walter Jang151f3e62015-02-26 15:29:40 -0800380 private void addPhotoView(RawContactDeltaList rawContactDeltas,
Walter Jangfa127a12015-06-18 09:48:18 -0700381 ViewIdGenerator viewIdGenerator, long photoId, String readOnlyDisplayName) {
382 // If we're editing a read-only contact, the display name from the read-only
383 // contact is non empty and we can use it determine whether to back the photo editor with
384 // the empty new raw contact delta. See go/editing-read-only-contacts
385 final boolean readOnlyContact = !TextUtils.isEmpty(readOnlyDisplayName);
386 if (readOnlyContact) {
387 for (RawContactDelta rawContactDelta : rawContactDeltas) {
388 if (!rawContactDelta.isVisible()) continue;
389 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
390
391 // Make sure we have a photo
392 RawContactModifier.ensureKindExists(
393 rawContactDelta, accountType, Photo.CONTENT_ITEM_TYPE);
394
395 final DataKind dataKind = accountType.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
396 if (accountType.areContactsWritable()) {
397 for (ValuesDelta valuesDelta : rawContactDelta.getMimeEntries(
398 Photo.CONTENT_ITEM_TYPE)) {
399 if (valuesDelta != null) {
400 // Break the loop but don't return because we need to keep going to
401 // in order to show the photo from the read-only contact.
402 mPhotoRawContactId = rawContactDelta.getRawContactId();
403 mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
404 /* readOnly =*/ false, mMaterialPalette, viewIdGenerator);
405 break;
406 }
407 }
408 }
409 }
410 }
411
Walter Jangac679af2015-06-01 12:17:06 -0700412 // Look for a match for the photo ID that was passed in
Walter Jangcab3dce2015-02-09 17:48:03 -0800413 for (RawContactDelta rawContactDelta : rawContactDeltas) {
Walter Jang3b210272015-03-04 11:34:11 -0800414 if (!rawContactDelta.isVisible()) continue;
Walter Jangcab3dce2015-02-09 17:48:03 -0800415 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
Walter Jange720fde2015-02-17 10:54:14 -0800416
Walter Jang3efae4a2015-02-18 11:12:00 -0800417 // Make sure we have a photo
418 RawContactModifier.ensureKindExists(
419 rawContactDelta, accountType, Photo.CONTENT_ITEM_TYPE);
420
421 final DataKind dataKind = accountType.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
Walter Jangab50e6f2015-06-15 08:57:22 -0700422 if (dataKind != null && dataKind.editable) {
Walter Jangac679af2015-06-01 12:17:06 -0700423 for (ValuesDelta valuesDelta
424 : rawContactDelta.getMimeEntries(Photo.CONTENT_ITEM_TYPE)) {
425 if (valuesDelta != null && valuesDelta.getId() != null
426 && valuesDelta.getId().equals(photoId)) {
Walter Jangfa127a12015-06-18 09:48:18 -0700427 if (readOnlyContact) {
428 mPhoto.setPhoto(valuesDelta);
429 } else {
430 mPhotoRawContactId = rawContactDelta.getRawContactId();
431 mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
432 !accountType.areContactsWritable(),
433 mMaterialPalette, viewIdGenerator);
434 }
Walter Jangac679af2015-06-01 12:17:06 -0700435 return;
436 }
437 }
438 }
439 }
440
441 // Look for a non-empty super primary photo
442 for (RawContactDelta rawContactDelta : rawContactDeltas) {
443 if (!rawContactDelta.isVisible()) continue;
444 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
445 final DataKind dataKind = accountType.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
Walter Jangab50e6f2015-06-15 08:57:22 -0700446 if (dataKind != null && dataKind.editable) {
Walter Jang3b210272015-03-04 11:34:11 -0800447 final ValuesDelta valuesDelta = getNonEmptySuperPrimaryValuesDeltas(
448 rawContactDelta, Photo.CONTENT_ITEM_TYPE, dataKind);
449 if (valuesDelta != null) {
Walter Jangfa127a12015-06-18 09:48:18 -0700450 if (readOnlyContact) {
451 mPhoto.setPhoto(valuesDelta);
452 } else {
453 mPhotoRawContactId = rawContactDelta.getRawContactId();
454 mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
455 !accountType.areContactsWritable(), mMaterialPalette,
456 viewIdGenerator);
457 }
Walter Jang3efae4a2015-02-18 11:12:00 -0800458 return;
459 }
460 }
461 }
Walter Jang3b210272015-03-04 11:34:11 -0800462 // We didn't find a non-empty super primary photo, use the first non-empty one
463 for (RawContactDelta rawContactDelta : rawContactDeltas) {
464 if (!rawContactDelta.isVisible()) continue;
465 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
466 final DataKind dataKind = accountType.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
Walter Jangab50e6f2015-06-15 08:57:22 -0700467 if (dataKind != null && dataKind.editable) {
Walter Jang3b210272015-03-04 11:34:11 -0800468 final List<ValuesDelta> valuesDeltas = getNonEmptyValuesDeltas(
469 rawContactDelta, Photo.CONTENT_ITEM_TYPE, dataKind);
470 if (valuesDeltas != null && !valuesDeltas.isEmpty()) {
Walter Jangfa127a12015-06-18 09:48:18 -0700471 if (readOnlyContact) {
472 mPhoto.setPhoto(valuesDeltas.get(0));
473 } else {
474 mPhotoRawContactId = rawContactDelta.getRawContactId();
475 mPhoto.setValues(dataKind, valuesDeltas.get(0), rawContactDelta,
476 !accountType.areContactsWritable(), mMaterialPalette,
477 viewIdGenerator);
478 }
Walter Jang3b210272015-03-04 11:34:11 -0800479 return;
480 }
481 }
482 }
483 // No suitable non-empty photo
484 for (RawContactDelta rawContactDelta : rawContactDeltas) {
485 if (!rawContactDelta.isVisible()) continue;
486 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
487 final DataKind dataKind = accountType.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
Walter Jangab50e6f2015-06-15 08:57:22 -0700488 if (dataKind != null && dataKind.editable) {
Walter Jang3b210272015-03-04 11:34:11 -0800489 final ValuesDelta valuesDelta = rawContactDelta.getSuperPrimaryEntry(
490 dataKind.mimeType, /* forceSelection =*/ true);
491 if (valuesDelta != null) {
Walter Jangfa127a12015-06-18 09:48:18 -0700492 if (readOnlyContact) {
493 mPhoto.setPhoto(valuesDelta);
494 } else {
495 mPhotoRawContactId = rawContactDelta.getRawContactId();
496 mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
497 !accountType.areContactsWritable(), mMaterialPalette,
498 viewIdGenerator);
499 }
Walter Jang3b210272015-03-04 11:34:11 -0800500 return;
501 }
502 }
503 }
504 // Should not happen since we ensure the kind exists but if we unexpectedly get here
505 // we must remove the photo section so that it does not take up the entire view
506 mPhoto.setVisibility(View.GONE);
Walter Jang3efae4a2015-02-18 11:12:00 -0800507 }
508
Walter Jang06f73a12015-06-17 11:15:48 -0700509 private void addStructuredNameView(RawContactDeltaList rawContactDeltas, long nameId,
510 String readOnlyDisplayName) {
511 // If we're editing a read-only contact we want to display the name from the read-only
512 // contact in a structured name editor backed by the new raw contact that was created.
513 // The new raw contact is writable and merging it with the read-only contact allows us
514 // to edit the read-only contact. See go/editing-read-only-contacts
515 if (!TextUtils.isEmpty(readOnlyDisplayName)) {
516 for (RawContactDelta rawContactDelta : rawContactDeltas) {
517 if (!rawContactDelta.isVisible()) continue;
518 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
519
520 // Make sure we have a structured name
521 RawContactModifier.ensureKindExists(
522 rawContactDelta, accountType, StructuredName.CONTENT_ITEM_TYPE);
523
524 if (accountType.areContactsWritable()) {
525 for (ValuesDelta valuesDelta : rawContactDelta.getMimeEntries(
526 StructuredName.CONTENT_ITEM_TYPE)) {
527 if (valuesDelta != null) {
528 mNameValuesDelta = valuesDelta;
529 final NameEditorListener nameEditorListener = new NameEditorListener(
530 mNameValuesDelta, rawContactDelta.getRawContactId(), mListener);
531 final StructuredNameEditorView nameEditorView =
532 inflateStructuredNameEditorView(mNames, accountType,
533 mNameValuesDelta, rawContactDelta, nameEditorListener,
534 !accountType.areContactsWritable());
535 nameEditorView.setDisplayName(readOnlyDisplayName);
536 mNames.addView(nameEditorView);
537 mDefaultNameEditorView = nameEditorView;
538 return;
539 }
540 }
541 }
542 }
543 }
544
Walter Jang65d35202015-06-16 13:08:34 -0700545 // Look for a match for the name ID that was passed in
Walter Jang10446452015-02-20 13:51:16 -0800546 for (RawContactDelta rawContactDelta : rawContactDeltas) {
Walter Jang151f3e62015-02-26 15:29:40 -0800547 if (!rawContactDelta.isVisible()) continue;
Walter Jang10446452015-02-20 13:51:16 -0800548 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
549
550 // Make sure we have a structured name
551 RawContactModifier.ensureKindExists(
552 rawContactDelta, accountType, StructuredName.CONTENT_ITEM_TYPE);
553
Walter Jang151f3e62015-02-26 15:29:40 -0800554 // Note use of pseudo mime type to get the DataKind and StructuredName to get value
Walter Jang10446452015-02-20 13:51:16 -0800555 final DataKind dataKind = accountType.getKindForMimetype(
Walter Jang151f3e62015-02-26 15:29:40 -0800556 DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME);
557 if (dataKind == null || !dataKind.editable) continue;
558
Walter Jang398cd4b2015-06-16 11:17:53 -0700559 for (ValuesDelta valuesDelta : rawContactDelta.getMimeEntries(
560 StructuredName.CONTENT_ITEM_TYPE)) {
561 if (valuesDelta != null && valuesDelta.getId() != null
562 && valuesDelta.getId().equals(nameId)) {
563 mNameValuesDelta = valuesDelta;
564 final NameEditorListener nameEditorListener = new NameEditorListener(
565 mNameValuesDelta, rawContactDelta.getRawContactId(), mListener);
566 mNames.addView(inflateStructuredNameEditorView(mNames, accountType,
Walter Jang65d35202015-06-16 13:08:34 -0700567 mNameValuesDelta, rawContactDelta, nameEditorListener,
568 !accountType.areContactsWritable()));
Walter Jang398cd4b2015-06-16 11:17:53 -0700569 return;
570 }
571 }
572 }
573 // Look for a super primary name
574 for (RawContactDelta rawContactDelta : rawContactDeltas) {
575 if (!rawContactDelta.isVisible()) continue;
576 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
577
578 final DataKind dataKind = accountType.getKindForMimetype(
579 DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME);
580 if (dataKind == null || !dataKind.editable) continue;
581
Walter Jang151f3e62015-02-26 15:29:40 -0800582 final ValuesDelta superPrimaryValuesDelta = getNonEmptySuperPrimaryValuesDeltas(
583 rawContactDelta, StructuredName.CONTENT_ITEM_TYPE, dataKind);
584 if (superPrimaryValuesDelta != null) {
585 // Our first preference is for a non-empty super primary name
Walter Janga26490b2015-05-27 13:08:24 -0700586 final NameEditorListener nameEditorListener = new NameEditorListener(
587 superPrimaryValuesDelta, rawContactDelta.getRawContactId(), mListener);
Walter Jang151f3e62015-02-26 15:29:40 -0800588 mNames.addView(inflateStructuredNameEditorView(mNames, accountType,
Walter Jang65d35202015-06-16 13:08:34 -0700589 superPrimaryValuesDelta, rawContactDelta, nameEditorListener,
590 !accountType.areContactsWritable()));
Walter Jang151f3e62015-02-26 15:29:40 -0800591 return;
592 }
593 }
594 // We didn't find a super primary name
595 for (RawContactDelta rawContactDelta : rawContactDeltas) {
596 if (!rawContactDelta.isVisible()) continue;
597 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
598
599 final DataKind dataKind = accountType.getKindForMimetype(
600 DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME);
601 if (dataKind == null || !dataKind.editable) continue;
602
603 final List<ValuesDelta> nonEmptyValuesDeltas = getNonEmptyValuesDeltas(
604 rawContactDelta, StructuredName.CONTENT_ITEM_TYPE, dataKind);
605 if (nonEmptyValuesDeltas != null && !nonEmptyValuesDeltas.isEmpty()) {
Walter Jang65d35202015-06-16 13:08:34 -0700606 // Take the first non-empty name
Walter Jang151f3e62015-02-26 15:29:40 -0800607 mNameValuesDelta = nonEmptyValuesDeltas.get(0);
608 final NameEditorListener nameEditorListener = new NameEditorListener(
609 mNameValuesDelta, rawContactDelta.getRawContactId(), mListener);
610 mNames.addView(inflateStructuredNameEditorView(mNames, accountType,
Walter Jang65d35202015-06-16 13:08:34 -0700611 mNameValuesDelta, rawContactDelta, nameEditorListener,
612 !accountType.areContactsWritable()));
Walter Jang151f3e62015-02-26 15:29:40 -0800613 return;
614 }
615 }
616 for (RawContactDelta rawContactDelta : rawContactDeltas) {
617 if (!rawContactDelta.isVisible()) continue;
618 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
619
620 final DataKind dataKind = accountType.getKindForMimetype(
621 DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME);
622 if (dataKind == null || !dataKind.editable) continue;
623
624 // Fall back to the first entry
625 final ArrayList<ValuesDelta> valuesDeltas = rawContactDelta.getMimeEntries(
Walter Jang10446452015-02-20 13:51:16 -0800626 StructuredName.CONTENT_ITEM_TYPE);
Walter Jang151f3e62015-02-26 15:29:40 -0800627 if (valuesDeltas != null && !valuesDeltas.isEmpty()) {
628 mNameValuesDelta = valuesDeltas.get(0);
629 final NameEditorListener nameEditorListener = new NameEditorListener(
630 mNameValuesDelta, rawContactDelta.getRawContactId(), mListener);
631 mNames.addView(inflateStructuredNameEditorView(mNames, accountType,
Walter Jang65d35202015-06-16 13:08:34 -0700632 mNameValuesDelta, rawContactDelta, nameEditorListener,
633 !accountType.areContactsWritable()));
Walter Jang151f3e62015-02-26 15:29:40 -0800634 return;
Walter Jang10446452015-02-20 13:51:16 -0800635 }
636 }
637 }
638
Walter Jang3efae4a2015-02-18 11:12:00 -0800639 private void addEditorViews(RawContactDeltaList rawContactDeltas) {
640 for (RawContactDelta rawContactDelta : rawContactDeltas) {
Walter Jangab50e6f2015-06-15 08:57:22 -0700641 if (!rawContactDelta.isVisible()) continue;
Walter Jang3efae4a2015-02-18 11:12:00 -0800642 final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
643
Walter Jangcab3dce2015-02-09 17:48:03 -0800644 for (DataKind dataKind : accountType.getSortedDataKinds()) {
Walter Jangab50e6f2015-06-15 08:57:22 -0700645 if (!dataKind.editable) continue;
646
Walter Jangcab3dce2015-02-09 17:48:03 -0800647 final String mimeType = dataKind.mimeType;
Walter Jangbf63a6d2015-05-05 09:14:35 -0700648 vlog(mimeType + " " + dataKind.fieldList.size() + " field(s)");
Walter Jangcab3dce2015-02-09 17:48:03 -0800649 if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)
Walter Jang10446452015-02-20 13:51:16 -0800650 || StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)
Walter Jangcab3dce2015-02-09 17:48:03 -0800651 || GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
Walter Jang151f3e62015-02-26 15:29:40 -0800652 // Photos and structured names are handled separately and
653 // group membership is not supported
Walter Jangcab3dce2015-02-09 17:48:03 -0800654 continue;
Walter Jangcab3dce2015-02-09 17:48:03 -0800655 } else if (DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)) {
Walter Jang151f3e62015-02-26 15:29:40 -0800656 // Only add phonetic names if there is a non-empty one. Note the use of
657 // StructuredName mimeType below, even though we matched a pseudo mime type.
Walter Jang3a37a1a2015-03-04 07:41:32 -0800658 final ValuesDelta valuesDelta = rawContactDelta.getSuperPrimaryEntry(
659 StructuredName.CONTENT_ITEM_TYPE, /* forceSelection =*/ true);
660 if (hasNonEmptyValue(dataKind, valuesDelta)) {
661 mPhoneticNames.addView(inflatePhoneticNameEditorView(
662 mPhoneticNames, accountType, valuesDelta, rawContactDelta));
Walter Jangcab3dce2015-02-09 17:48:03 -0800663 }
664 } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
Walter Jang151f3e62015-02-26 15:29:40 -0800665 // Only add nicknames if there is a non-empty one
Walter Jangcab3dce2015-02-09 17:48:03 -0800666 if (hasNonEmptyValuesDelta(rawContactDelta, mimeType, dataKind)) {
Walter Jang28c98b72015-06-01 15:56:37 -0700667 mNicknames.addView(inflateKindSectionView(mNicknames, dataKind,
Walter Jang88b0a8c2015-06-08 13:15:56 -0700668 rawContactDelta));
Walter Jangcab3dce2015-02-09 17:48:03 -0800669 }
670 } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
Walter Jang4a9351d2015-06-30 14:09:10 -0700671 final KindSectionView kindSectionView =
672 inflateKindSectionView(mPhoneNumbers, dataKind, rawContactDelta);
673 kindSectionView.setListener(new KindSectionView.Listener() {
674 @Override
675 public void onDeleteRequested() {
Walter Jang19d985f2015-07-01 13:36:27 -0700676 kindSectionView.setVisibility(View.GONE);
677 updateKindEditorEmptyFields(mPhoneNumbers);
678 updateKindEditorIcons(mPhoneNumbers);
Walter Jang4a9351d2015-06-30 14:09:10 -0700679 }
680 });
681 mPhoneNumbers.addView(kindSectionView);
Walter Jangcab3dce2015-02-09 17:48:03 -0800682 } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
Walter Jang4a9351d2015-06-30 14:09:10 -0700683 final KindSectionView kindSectionView =
684 inflateKindSectionView(mEmails, dataKind, rawContactDelta);
685 kindSectionView.setListener(new KindSectionView.Listener() {
686 @Override
687 public void onDeleteRequested() {
Walter Jang19d985f2015-07-01 13:36:27 -0700688 kindSectionView.setVisibility(View.GONE);
689 updateKindEditorEmptyFields(mEmails);
690 updateKindEditorIcons(mEmails);
Walter Jang4a9351d2015-06-30 14:09:10 -0700691 }
692 });
693 mEmails.addView(kindSectionView);
Walter Jangcab3dce2015-02-09 17:48:03 -0800694 } else if (hasNonEmptyValuesDelta(rawContactDelta, mimeType, dataKind)) {
Walter Jang19d985f2015-07-01 13:36:27 -0700695 final LinearLayout otherViewGroup;
696 if (mOtherMap.containsKey(mimeType)) {
697 otherViewGroup = mOtherMap.get(mimeType);
698 } else {
699 otherViewGroup = new LinearLayout(getContext());
700 otherViewGroup.setOrientation(LinearLayout.VERTICAL);
701 mOther.addView(otherViewGroup);
702 mOtherMap.put(mimeType, otherViewGroup);
703 }
704 final KindSectionView kindSectionView =
705 inflateKindSectionView(mOther, dataKind, rawContactDelta);
706 kindSectionView.setListener(new KindSectionView.Listener() {
707 @Override
708 public void onDeleteRequested() {
709 if (kindSectionView.getVisibleEditorCount() == 1) {
710 kindSectionView.setVisibility(View.GONE);
711 }
712 updateKindEditorIcons(otherViewGroup);
713 }
714 });
715 otherViewGroup.addView(kindSectionView);
Walter Jangcab3dce2015-02-09 17:48:03 -0800716 }
717 }
718 }
719 }
720
Walter Jang19d985f2015-07-01 13:36:27 -0700721 private static void updateKindEditorEmptyFields(ViewGroup viewGroup) {
722 KindSectionView lastVisibleKindSectionView = null;
723 for (int i = 0; i < viewGroup.getChildCount(); i++) {
724 if (viewGroup.getChildAt(i).getVisibility() == View.VISIBLE) {
725 lastVisibleKindSectionView = (KindSectionView) viewGroup.getChildAt(i);
Walter Jangb1c87622015-02-13 17:51:38 -0800726 }
Walter Jang4a9351d2015-06-30 14:09:10 -0700727 }
Walter Jang19d985f2015-07-01 13:36:27 -0700728 // Only the last editor should show an empty editor
729 if (lastVisibleKindSectionView != null) {
730 lastVisibleKindSectionView.setShowOneEmptyEditor(true);
731 lastVisibleKindSectionView.updateEmptyEditors(/* shouldAnimate =*/ false);
732 }
733 }
Walter Jang4a9351d2015-06-30 14:09:10 -0700734
Walter Jang19d985f2015-07-01 13:36:27 -0700735 private static void updateKindEditorIcons(ViewGroup viewGroup) {
Walter Jang4a9351d2015-06-30 14:09:10 -0700736 // Show the icon on the first visible kind editor
737 boolean iconVisible = false;
738 for (int i = 0; i < viewGroup.getChildCount(); i++) {
739 final KindSectionView kindSectionView = (KindSectionView) viewGroup.getChildAt(i);
740 if (kindSectionView.getVisibility() != View.VISIBLE) {
741 continue;
742 }
743 if (!iconVisible) {
744 kindSectionView.setIconVisibility(true);
745 iconVisible = true;
746 } else {
747 kindSectionView.setIconVisibility(false);
Walter Jangb1c87622015-02-13 17:51:38 -0800748 }
749 }
750 }
751
Walter Jangcab3dce2015-02-09 17:48:03 -0800752 private static boolean hasNonEmptyValuesDelta(RawContactDelta rawContactDelta,
753 String mimeType, DataKind dataKind) {
754 return !getNonEmptyValuesDeltas(rawContactDelta, mimeType, dataKind).isEmpty();
755 }
756
Walter Jang151f3e62015-02-26 15:29:40 -0800757 private static ValuesDelta getNonEmptySuperPrimaryValuesDeltas(RawContactDelta rawContactDelta,
758 String mimeType, DataKind dataKind) {
759 for (ValuesDelta valuesDelta : getNonEmptyValuesDeltas(
760 rawContactDelta, mimeType, dataKind)) {
761 if (valuesDelta.isSuperPrimary()) {
762 return valuesDelta;
763 }
764 }
765 return null;
766 }
767
768 static List<ValuesDelta> getNonEmptyValuesDeltas(RawContactDelta rawContactDelta,
Walter Jangcab3dce2015-02-09 17:48:03 -0800769 String mimeType, DataKind dataKind) {
770 final List<ValuesDelta> result = new ArrayList<>();
771 if (rawContactDelta == null) {
Walter Jangbf63a6d2015-05-05 09:14:35 -0700772 vlog("Null RawContactDelta");
Walter Jangcab3dce2015-02-09 17:48:03 -0800773 return result;
774 }
775 if (!rawContactDelta.hasMimeEntries(mimeType)) {
Walter Jangbf63a6d2015-05-05 09:14:35 -0700776 vlog("No ValueDeltas");
Walter Jangcab3dce2015-02-09 17:48:03 -0800777 return result;
778 }
779 for (ValuesDelta valuesDelta : rawContactDelta.getMimeEntries(mimeType)) {
Walter Jang3a37a1a2015-03-04 07:41:32 -0800780 if (hasNonEmptyValue(dataKind, valuesDelta)) {
781 result.add(valuesDelta);
Walter Jangcab3dce2015-02-09 17:48:03 -0800782 }
783 }
784 return result;
785 }
786
Walter Jang3a37a1a2015-03-04 07:41:32 -0800787 private static boolean hasNonEmptyValue(DataKind dataKind, ValuesDelta valuesDelta) {
788 if (valuesDelta == null) {
Walter Jangbf63a6d2015-05-05 09:14:35 -0700789 vlog("Null valuesDelta");
Walter Jang3a37a1a2015-03-04 07:41:32 -0800790 return false;
791 }
792 for (EditField editField : dataKind.fieldList) {
793 final String column = editField.column;
794 final String value = valuesDelta == null ? null : valuesDelta.getAsString(column);
Walter Jangbf63a6d2015-05-05 09:14:35 -0700795 vlog("Field " + column + " empty=" + TextUtils.isEmpty(value) + " value=" + value);
Walter Jang3a37a1a2015-03-04 07:41:32 -0800796 if (!TextUtils.isEmpty(value)) {
797 return true;
798 }
799 }
800 return false;
801 }
802
Walter Jangcab3dce2015-02-09 17:48:03 -0800803 private StructuredNameEditorView inflateStructuredNameEditorView(ViewGroup viewGroup,
Walter Jang151f3e62015-02-26 15:29:40 -0800804 AccountType accountType, ValuesDelta valuesDelta, RawContactDelta rawContactDelta,
Walter Jang65d35202015-06-16 13:08:34 -0700805 NameEditorListener nameEditorListener, boolean readOnly) {
Walter Jangcab3dce2015-02-09 17:48:03 -0800806 final StructuredNameEditorView result = (StructuredNameEditorView) mLayoutInflater.inflate(
807 R.layout.structured_name_editor_view, viewGroup, /* attachToRoot =*/ false);
Walter Jang151f3e62015-02-26 15:29:40 -0800808 if (nameEditorListener != null) {
809 result.setEditorListener(nameEditorListener);
810 }
Walter Jang3a37a1a2015-03-04 07:41:32 -0800811 result.setDeletable(false);
Walter Jangcab3dce2015-02-09 17:48:03 -0800812 result.setValues(
813 accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME),
814 valuesDelta,
815 rawContactDelta,
Walter Jang65d35202015-06-16 13:08:34 -0700816 readOnly,
Walter Jangcab3dce2015-02-09 17:48:03 -0800817 mViewIdGenerator);
818 return result;
819 }
820
821 private PhoneticNameEditorView inflatePhoneticNameEditorView(ViewGroup viewGroup,
822 AccountType accountType, ValuesDelta valuesDelta, RawContactDelta rawContactDelta) {
823 final PhoneticNameEditorView result = (PhoneticNameEditorView) mLayoutInflater.inflate(
824 R.layout.phonetic_name_editor_view, viewGroup, /* attachToRoot =*/ false);
Walter Jang3a37a1a2015-03-04 07:41:32 -0800825 result.setDeletable(false);
Walter Jangcab3dce2015-02-09 17:48:03 -0800826 result.setValues(
827 accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME),
828 valuesDelta,
829 rawContactDelta,
830 /* readOnly =*/ false,
831 mViewIdGenerator);
832 return result;
833 }
834
Walter Jangcab3dce2015-02-09 17:48:03 -0800835 private KindSectionView inflateKindSectionView(ViewGroup viewGroup, DataKind dataKind,
Walter Jang88b0a8c2015-06-08 13:15:56 -0700836 RawContactDelta rawContactDelta) {
Walter Jangcab3dce2015-02-09 17:48:03 -0800837 final KindSectionView result = (KindSectionView) mLayoutInflater.inflate(
838 R.layout.item_kind_section, viewGroup, /* attachToRoot =*/ false);
839 result.setState(
840 dataKind,
841 rawContactDelta,
842 /* readOnly =*/ false,
Walter Jangcab3dce2015-02-09 17:48:03 -0800843 mViewIdGenerator);
844 return result;
845 }
846
Walter Jangbf63a6d2015-05-05 09:14:35 -0700847 private static void vlog(String message) {
848 if (Log.isLoggable(TAG, Log.VERBOSE)) {
849 Log.v(TAG, message);
Walter Jangcab3dce2015-02-09 17:48:03 -0800850 }
851 }
852}