ContactEditorFragment.java revision 5a7a23bdb698b8e741a425c9617c5e33e6314cdd
1cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann/* 2ef3f8f045ed4150caa64749742227acd0e6b85d8Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project 3cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * 4cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 5cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * you may not use this file except in compliance with the License. 6cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * You may obtain a copy of the License at 7cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * 8cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 9cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * 10cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * Unless required by applicable law or agreed to in writing, software 11cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 12cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * See the License for the specific language governing permissions and 14cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann * limitations under the License 15cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann */ 16cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor; 18cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 19cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.app.Activity; 20cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Context; 21cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Intent; 22f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport android.graphics.Bitmap; 23cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.net.Uri; 24cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.os.Bundle; 25151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jangimport android.provider.ContactsContract; 26151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jangimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 2791004b37683c15650eccde68ff04defcf94a1c84Maurice Chuimport android.provider.ContactsContract.CommonDataKinds.Photo; 28688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Leeimport android.text.TextUtils; 29cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.util.Log; 30cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.LayoutInflater; 315a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jangimport android.view.MenuItem; 32cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.View; 33cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.ViewGroup; 34d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.AdapterView; 3580d527c94389cab477e2c75ded03eec877ea6835Daniel Lehmannimport android.widget.LinearLayout; 36d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.ListPopupWindow; 37cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 38e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService; 39e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 40e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ContactEditorActivity; 4144cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.AccountTypeManager; 4292101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactDelta; 4392101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactDeltaList; 4444cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.ValuesDelta; 4544cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.account.AccountType; 4644cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.account.AccountWithDataSet; 4744cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter; 4844cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter.AccountListFilter; 495a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jangimport com.android.contacts.common.util.MaterialColorMapUtils; 50e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.PhotoSelectionHandler; 51e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.Editor.EditorListener; 52e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.ContactPhotoUtils; 5386625158bdc52855c37e96bf098ba7a213c810d7Chiao Chengimport com.android.contacts.util.UiClosables; 5492101e77238e450dedb56814cec80edc0adf79c0Walter Jang 55637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Leeimport java.io.FileNotFoundException; 56f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport java.util.Collections; 57daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwellimport java.util.HashMap; 58f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.List; 59f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 603f990ba4e35a99078d831c041290e574a320caa5Walter Jang/** 613f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Contact editor with all fields displayed. 623f990ba4e35a99078d831c041290e574a320caa5Walter Jang */ 633f990ba4e35a99078d831c041290e574a320caa5Walter Jangpublic class ContactEditorFragment extends ContactEditorBaseFragment implements 642b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann RawContactReadOnlyEditorView.Listener { 65cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 66daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell private static final String KEY_EXPANDED_EDITORS = "expandedEditors"; 67f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 68cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester"; 69cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang private static final String KEY_CURRENT_PHOTO_URI = "currentphotouri"; 70cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang private static final String KEY_UPDATED_PHOTOS = "updatedPhotos"; 71cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang 72fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang // Used to store which raw contact editors have been expanded. Keyed on raw contact ids. 73fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang private HashMap<Long, Boolean> mExpandedEditors = new HashMap<Long, Boolean>(); 74fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang 75fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang /** 76fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * The raw contact for which we started "take photo" or "choose photo from gallery" most 77fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * recently. Used to restore {@link #mCurrentPhotoHandler} after orientation change. 78fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang */ 79fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang private long mRawContactIdRequestingPhoto; 8044cfc56d1701629070384364416c1311b780535dChiao Cheng 81fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang /** 82fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * The {@link PhotoHandler} for the photo editor for the {@link #mRawContactIdRequestingPhoto} 83fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * raw contact. 84fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * 85fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * A {@link PhotoHandler} is created for each photo editor in {@link #bindPhotoHandler}, but 86fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * the only "active" one should get the activity result. This member represents the active 87fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang * one. 88fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang */ 89fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang private PhotoHandler mCurrentPhotoHandler; 90fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang private Uri mCurrentPhotoUri; 91fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang private Bundle mUpdatedPhotos = new Bundle(); 92daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell 93cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public ContactEditorFragment() { 94cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 95cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 96cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann @Override 97cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { 98cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann final View view = inflater.inflate(R.layout.contact_editor_fragment, container, false); 99cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 100f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent = (LinearLayout) view.findViewById(R.id.editors); 101e8767a1136d2a2f9cb3e3ca5f44b2142baab9709Daniel Lehmann 1023648d2ea76a6649230d1fdd3dba92797ae7cfb26Daniel Lehmann setHasOptionsMenu(true); 103cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 104cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann return view; 105cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 106cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 107222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann @Override 108f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void onCreate(Bundle savedState) { 109f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann super.onCreate(savedState); 110f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 111ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang if (savedState != null) { 112daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell mExpandedEditors = (HashMap<Long, Boolean>) 113daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell savedState.getSerializable(KEY_EXPANDED_EDITORS); 114cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang mRawContactIdRequestingPhoto = savedState.getLong( 115cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang KEY_RAW_CONTACT_ID_REQUESTING_PHOTO); 116cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang mCurrentPhotoUri = savedState.getParcelable(KEY_CURRENT_PHOTO_URI); 117cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS); 11844cfc56d1701629070384364416c1311b780535dChiao Cheng } 119fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 120fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 121fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov @Override 1225a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang public void onStop() { 1235a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang super.onStop(); 1245a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang 1255a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang // If anything was left unsaved, save it now and return to the compact editor. 1265a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (!getActivity().isChangingConfigurations() && mStatus == Status.EDITING) { 1275a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang save(SaveMode.COMPACT); 1285a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 1295a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 1305a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang 1315a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang @Override 1322b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro public void onExternalEditorRequest(AccountWithDataSet account, Uri uri) { 133fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov mListener.onCustomEditContactActivityRequested(account, uri, null, false); 134fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 135fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 136daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell @Override 1375a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang public boolean onOptionsItemSelected(MenuItem item) { 1385a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang // Override the home/done options to return to the compact editor 1395a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (item.getItemId() == android.R.id.home || item.getItemId() == R.id.menu_done) { 1405a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang return save(SaveMode.COMPACT); 1415a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 1425a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang return super.onOptionsItemSelected(item); 1435a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 1445a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang 1455a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang @Override 146daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell public void onEditorExpansionChanged() { 147daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell updatedExpandedEditorsMap(); 148daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } 149daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell 150d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa /** 151d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * Removes a current editor ({@link #mState}) and rebinds new editor for a new account. 152d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * Some of old data are reused with new restriction enforced by the new account. 153d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * 1542b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro * @param oldState Old data being edited. 155d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * @param oldAccount Old account associated with oldState. 156d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * @param newAccount New account to be used. 157d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa */ 158d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa private void rebindEditorsForNewContact( 159851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDelta oldState, AccountWithDataSet oldAccount, 160851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu AccountWithDataSet newAccount) { 161d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 16267e83223e954ed54898daa5e32400dbff6d3831aJay Shrauner AccountType oldAccountType = accountTypes.getAccountTypeForAccount(oldAccount); 16367e83223e954ed54898daa5e32400dbff6d3831aJay Shrauner AccountType newAccountType = accountTypes.getAccountTypeForAccount(newAccount); 164d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 165d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (newAccountType.getCreateContactActivityClassName() != null) { 166d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa Log.w(TAG, "external activity called in rebind situation"); 167d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (mListener != null) { 168d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa mListener.onCustomCreateContactActivityRequested(newAccount, mIntentExtras); 169d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 170d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } else { 17144cfc56d1701629070384364416c1311b780535dChiao Cheng mExistingContactDataReady = false; 17244cfc56d1701629070384364416c1311b780535dChiao Cheng mNewContactDataReady = false; 17344cfc56d1701629070384364416c1311b780535dChiao Cheng mState = new RawContactDeltaList(); 174b55107303cc46906c265582a8931172f13d684b6Walter Jang setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType); 17544cfc56d1701629070384364416c1311b780535dChiao Cheng if (mIsEdit) { 176b55107303cc46906c265582a8931172f13d684b6Walter Jang setStateForExistingContact(mDefaultDisplayName, mIsUserProfile, mRawContacts); 17744cfc56d1701629070384364416c1311b780535dChiao Cheng } 178d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 179d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 180d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 181ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang @Override 18292f8ccc1f15df787b7434224857c056721281046Walter Jang protected void setGroupMetaData() { 18392f8ccc1f15df787b7434224857c056721281046Walter Jang if (mGroupMetaData == null) { 18492f8ccc1f15df787b7434224857c056721281046Walter Jang return; 18592f8ccc1f15df787b7434224857c056721281046Walter Jang } 18692f8ccc1f15df787b7434224857c056721281046Walter Jang int editorCount = mContent.getChildCount(); 18792f8ccc1f15df787b7434224857c056721281046Walter Jang for (int i = 0; i < editorCount; i++) { 18892f8ccc1f15df787b7434224857c056721281046Walter Jang BaseRawContactEditorView editor = (BaseRawContactEditorView) mContent.getChildAt(i); 18992f8ccc1f15df787b7434224857c056721281046Walter Jang editor.setGroupMetaData(mGroupMetaData); 19092f8ccc1f15df787b7434224857c056721281046Walter Jang } 19192f8ccc1f15df787b7434224857c056721281046Walter Jang } 19292f8ccc1f15df787b7434224857c056721281046Walter Jang 19392f8ccc1f15df787b7434224857c056721281046Walter Jang @Override 194ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang protected void bindEditors() { 1955671c7e7718c3285dc0391807401083986fcfd51Maurice Chu // bindEditors() can only bind views if there is data in mState, so immediately return 1965671c7e7718c3285dc0391807401083986fcfd51Maurice Chu // if mState is null 19744cfc56d1701629070384364416c1311b780535dChiao Cheng if (mState.isEmpty()) { 19844cfc56d1701629070384364416c1311b780535dChiao Cheng return; 19944cfc56d1701629070384364416c1311b780535dChiao Cheng } 20044cfc56d1701629070384364416c1311b780535dChiao Cheng 20144cfc56d1701629070384364416c1311b780535dChiao Cheng // Check if delta list is ready. Delta list is populated from existing data and when 20244cfc56d1701629070384364416c1311b780535dChiao Cheng // editing an read-only contact, it's also populated with newly created data for the 20344cfc56d1701629070384364416c1311b780535dChiao Cheng // blank form. When the data is not ready, skip. This method will be called multiple times. 20444cfc56d1701629070384364416c1311b780535dChiao Cheng if ((mIsEdit && !mExistingContactDataReady) || (mHasNewContact && !mNewContactDataReady)) { 2055671c7e7718c3285dc0391807401083986fcfd51Maurice Chu return; 2065671c7e7718c3285dc0391807401083986fcfd51Maurice Chu } 2075671c7e7718c3285dc0391807401083986fcfd51Maurice Chu 208f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Sort the editors 209f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann Collections.sort(mState, mComparator); 210cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 211f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Remove any existing editors and rebuild any visible 212f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent.removeAllViews(); 213cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 214f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( 215f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann Context.LAYOUT_INFLATER_SERVICE); 216a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 217a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan int numRawContacts = mState.size(); 21844cfc56d1701629070384364416c1311b780535dChiao Cheng 219a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan for (int i = 0; i < numRawContacts; i++) { 220f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // TODO ensure proper ordering of entities in the list 221851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta rawContactDelta = mState.get(i); 222851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (!rawContactDelta.isVisible()) continue; 223f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 224851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final AccountType type = rawContactDelta.getAccountType(accountTypes); 225851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final long rawContactId = rawContactDelta.getRawContactId(); 226f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 22772af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann final BaseRawContactEditorView editor; 2282b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann if (!type.areContactsWritable()) { 229fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov editor = (BaseRawContactEditorView) inflater.inflate( 2302b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann R.layout.raw_contact_readonly_editor_view, mContent, false); 231fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } else { 232fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view, 233fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan mContent, false); 234cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 235daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell editor.setListener(this); 236daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(mContext) 237daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell .getAccounts(true); 238daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell if (mHasNewContact && !mNewLocalProfile && accounts.size() > 1) { 239daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell addAccountSwitcher(mState.get(0), editor); 240d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 241a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan 242b55107303cc46906c265582a8931172f13d684b6Walter Jang editor.setEnabled(isEnabled()); 243cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 244daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell if (mExpandedEditors.containsKey(rawContactId)) { 245daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell editor.setCollapsed(mExpandedEditors.get(rawContactId)); 246daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } else { 247daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell // By default, only the first editor will be expanded. 248daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell editor.setCollapsed(i != 0); 249daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } 250daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell 251f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent.addView(editor); 2527d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov 253851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile()); 254daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell editor.setCollapsible(numRawContacts > 1); 255f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 2566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Set up the photo handler. 2576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro bindPhotoHandler(editor, type, mState); 2586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 259c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell // If a new photo was chosen but not yet saved, we need to update the UI to 260c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell // reflect this. 261c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell final Uri photoUri = updatedPhotoUriForRawContact(rawContactId); 262c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell if (photoUri != null) editor.setFullSizedPhoto(photoUri); 26328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 26472af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann if (editor instanceof RawContactEditorView) { 2652828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki final Activity activity = getActivity(); 26672af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann final RawContactEditorView rawContactEditor = (RawContactEditorView) editor; 267151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final ValuesDelta nameValuesDelta = rawContactEditor.getNameEditor().getValues(); 268151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final EditorListener structuredNameListener = new EditorListener() { 269f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 270f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 271f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void onRequest(int request) { 272151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang // Make sure the activity is running 273151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (activity.isFinishing()) { 2742828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki return; 2752828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki } 276151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (request == EditorListener.EDITOR_FOCUS_CHANGED) { 277151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang adjustNameFieldsHintDarkness(rawContactEditor); 278151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang return; 279151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 280151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (!isEditingUserProfile()) { 281151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (request == EditorListener.FIELD_CHANGED) { 282151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (!nameValuesDelta.isSuperPrimary()) { 283151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang unsetSuperPrimaryForAllNameEditors(); 284151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang nameValuesDelta.setSuperPrimary(true); 285151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 286151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang acquireAggregationSuggestions(activity, 287151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang rawContactEditor.getNameEditor().getRawContactId(), 288151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang rawContactEditor.getNameEditor().getValues()); 289151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } else if (request == EditorListener.FIELD_TURNED_EMPTY) { 290151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (nameValuesDelta.isSuperPrimary()) { 291151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang nameValuesDelta.setSuperPrimary(false); 292151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 293151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 294151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 295151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 296151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang 297151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang @Override 298151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang public void onDeleteRequested(Editor removedEditor) { 299151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 300151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang }; 301151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final EditorListener otherNamesListener = new EditorListener() { 302151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang 303151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang @Override 304151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang public void onRequest(int request) { 305151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang // Make sure the activity is running 306151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (activity.isFinishing()) { 307151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang return; 308151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 309151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (request == EditorListener.EDITOR_FOCUS_CHANGED) { 310d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell adjustNameFieldsHintDarkness(rawContactEditor); 31111bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov } 312f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 313f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 314f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 3152293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan public void onDeleteRequested(Editor removedEditor) { 316f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 3175ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov }; 3185ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 31944cfc56d1701629070384364416c1311b780535dChiao Cheng final StructuredNameEditorView nameEditor = rawContactEditor.getNameEditor(); 3205ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov if (mRequestFocus) { 3215ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov nameEditor.requestFocus(); 3225ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov mRequestFocus = false; 3235ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 324151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang nameEditor.setEditorListener(structuredNameListener); 325688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee if (!TextUtils.isEmpty(mDefaultDisplayName)) { 326688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee nameEditor.setDisplayName(mDefaultDisplayName); 327688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee } 328f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 3295ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov final TextFieldsEditorView phoneticNameEditor = 3305ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov rawContactEditor.getPhoneticNameEditor(); 331151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang phoneticNameEditor.setEditorListener(otherNamesListener); 3327d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup); 3337d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov 334d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell final TextFieldsEditorView nickNameEditor = 335d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell rawContactEditor.getNickNameEditor(); 336151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang nickNameEditor.setEditorListener(otherNamesListener); 337d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell 3383e9a62449b8ca3a38b1d51019c6ea13972263bc2Walter Jang if (isAggregationSuggestionRawContactId(rawContactId)) { 339d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang acquireAggregationSuggestions(activity, 340d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang rawContactEditor.getNameEditor().getRawContactId(), 341d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang rawContactEditor.getNameEditor().getValues()); 342f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 343d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell 344d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell adjustNameFieldsHintDarkness(rawContactEditor); 345f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 346cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 347f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 348eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov mRequestFocus = false; 349eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov 350b55107303cc46906c265582a8931172f13d684b6Walter Jang setGroupMetaData(); 351e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 352f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Show editor now that we've loaded state 353f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent.setVisibility(View.VISIBLE); 354a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 355a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann // Refresh Action Bar as the visibility of the join command 356825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // Activity can be null if we have been detached from the Activity 35792f8ccc1f15df787b7434224857c056721281046Walter Jang invalidateOptionsMenu(); 358daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell 359daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell updatedExpandedEditorsMap(); 360daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } 361daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell 362151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang private void unsetSuperPrimaryForAllNameEditors() { 363151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang for (int i = 0; i < mContent.getChildCount(); i++) { 364151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final View view = mContent.getChildAt(i); 365151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (view instanceof RawContactEditorView) { 366151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final RawContactEditorView rawContactEditorView = (RawContactEditorView) view; 367151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final StructuredNameEditorView nameEditorView = 368151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang rawContactEditorView.getNameEditor(); 369151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (nameEditorView != null) { 370151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang final ValuesDelta valuesDelta = nameEditorView.getValues(); 371151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang if (valuesDelta != null) { 372151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang valuesDelta.setSuperPrimary(false); 373151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 374151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 375151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 376151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 377151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang } 378151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang 3795a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang @Override 3805a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang public String getDisplayName() { 3815a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang // Return the super primary name if it is non-empty 3825a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang for (int i = 0; i < mContent.getChildCount(); i++) { 3835a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final View view = mContent.getChildAt(i); 3845a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (view instanceof RawContactEditorView) { 3855a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final RawContactEditorView rawContactEditorView = (RawContactEditorView) view; 3865a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final StructuredNameEditorView nameEditorView = 3875a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang rawContactEditorView.getNameEditor(); 3885a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (nameEditorView != null) { 3895a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final ValuesDelta valuesDelta = nameEditorView.getValues(); 3905a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (valuesDelta != null && valuesDelta.isSuperPrimary()) { 3915a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final String displayName = valuesDelta.getDisplayName(); 3925a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (!TextUtils.isEmpty(displayName)) { 3935a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang return displayName; 3945a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 3955a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 3965a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 3975a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 3985a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 3995a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang // Return the first non-empty name 4005a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang for (int i = 0; i < mContent.getChildCount(); i++) { 4015a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final View view = mContent.getChildAt(i); 4025a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (view instanceof RawContactEditorView) { 4035a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final RawContactEditorView rawContactEditorView = (RawContactEditorView) view; 4045a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final StructuredNameEditorView nameEditorView = 4055a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang rawContactEditorView.getNameEditor(); 4065a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (nameEditorView != null) { 4075a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final ValuesDelta valuesDelta = nameEditorView.getValues(); 4085a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (valuesDelta != null) { 4095a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang final String displayName = valuesDelta.getDisplayName(); 4105a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang if (!TextUtils.isEmpty(displayName)) { 4115a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang return displayName; 4125a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4135a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4145a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4155a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4165a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4175a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang return null; 4185a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4195a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang 4205a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang @Override 4215a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang public MaterialColorMapUtils.MaterialPalette getMaterialPalette() { 4225a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang // There is no color for default photos on the fully expanded editor 4235a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang return null; 4245a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang } 4255a7a23bdb698b8e741a425c9617c5e33e6314cddWalter Jang 426daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell /** 427d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell * Adjust how dark the hint text should be on all the names' text fields. 428d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell * 429d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell * @param rawContactEditor editor to update 430d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell */ 431d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell private void adjustNameFieldsHintDarkness(RawContactEditorView rawContactEditor) { 432d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell // Check whether fields contain focus by calling findFocus() instead of hasFocus(). 433d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell // The hasFocus() value is not necessarily up to date. 434d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell final boolean nameFieldsAreNotFocused 435d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell = rawContactEditor.getNameEditor().findFocus() == null 436d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell && rawContactEditor.getPhoneticNameEditor().findFocus() == null 437d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell && rawContactEditor.getNickNameEditor().findFocus() == null; 438d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell rawContactEditor.getNameEditor().setHintColorDark(!nameFieldsAreNotFocused); 439d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell rawContactEditor.getPhoneticNameEditor().setHintColorDark(!nameFieldsAreNotFocused); 440d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell rawContactEditor.getNickNameEditor().setHintColorDark(!nameFieldsAreNotFocused); 441d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell } 442d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell 443d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell /** 444daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell * Update the values in {@link #mExpandedEditors}. 445daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell */ 446daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell private void updatedExpandedEditorsMap() { 447daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell for (int i = 0; i < mContent.getChildCount(); i++) { 448daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell final View childView = mContent.getChildAt(i); 449daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell if (childView instanceof BaseRawContactEditorView) { 450daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell BaseRawContactEditorView childEditor = (BaseRawContactEditorView) childView; 451daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell mExpandedEditors.put(childEditor.getRawContactId(), childEditor.isCollapsed()); 452daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } 453daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } 4546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 455eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov 45628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus /** 457c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell * If we've stashed a temporary file containing a contact's new photo, return its URI. 45828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus * @param rawContactId identifies the raw-contact whose Bitmap we'll try to return. 459c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell * @return Uru of photo for specified raw-contact, or null 460c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell */ 461c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell private Uri updatedPhotoUriForRawContact(long rawContactId) { 462c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell return (Uri) mUpdatedPhotos.get(String.valueOf(rawContactId)); 46328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus } 46428eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 4656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type, 466851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDeltaList state) { 4676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final int mode; 4687e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell final boolean showIsPrimaryOption; 4696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (type.areContactsWritable()) { 4706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (editor.hasSetPhoto()) { 4717e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell mode = PhotoActionPopup.Modes.WRITE_ABLE_PHOTO; 4727e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell showIsPrimaryOption = hasMoreThanOnePhoto(); 4736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 474ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mode = PhotoActionPopup.Modes.NO_PHOTO; 4757e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell showIsPrimaryOption = false; 4766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 4777e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell } else if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) { 4787e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell mode = PhotoActionPopup.Modes.READ_ONLY_PHOTO; 4797e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell showIsPrimaryOption = true; 4806fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 4817e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell // Read-only and either no photo or the only photo ==> no options 4827e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell editor.getPhotoEditor().setEditorListener(null); 4837e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell editor.getPhotoEditor().setShowPrimary(false); 4847e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell return; 4856fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 48691004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state); 4876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro editor.getPhotoEditor().setEditorListener( 48891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu (PhotoHandler.PhotoEditorListener) photoHandler.getListener()); 4897e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell editor.getPhotoEditor().setShowPrimary(showIsPrimaryOption); 4904bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki 4914bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki // Note a newly created raw contact gets some random negative ID, so any value is valid 4924bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki // here. (i.e. don't check against -1 or anything.) 4934bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki if (mRawContactIdRequestingPhoto == editor.getRawContactId()) { 4944bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki mCurrentPhotoHandler = photoHandler; 4954bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki } 496cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 497cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 498d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa private void addAccountSwitcher( 499851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta currentState, BaseRawContactEditorView editor) { 5002b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final AccountWithDataSet currentAccount = new AccountWithDataSet( 501851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu currentState.getAccountName(), 502851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu currentState.getAccountType(), 503851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu currentState.getDataSet()); 504d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa final View accountView = editor.findViewById(R.id.account); 505daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell final View anchorView = editor.findViewById(R.id.account_selector_container); 506daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell if (accountView == null) { 507daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell return; 508daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell } 509daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell anchorView.setVisibility(View.VISIBLE); 510d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa accountView.setOnClickListener(new View.OnClickListener() { 511d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa @Override 512d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa public void onClick(View v) { 513d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa final ListPopupWindow popup = new ListPopupWindow(mContext, null); 514a6c8f2daa80f1816dd25237457d7f6287c6b1b7cDaisuke Miyakawa final AccountsListAdapter adapter = 5156f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki new AccountsListAdapter(mContext, 5166f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, currentAccount); 517d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setWidth(anchorView.getWidth()); 518d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setAnchorView(anchorView); 519d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setAdapter(adapter); 520d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setModal(true); 521d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 522d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setOnItemClickListener(new AdapterView.OnItemClickListener() { 523d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa @Override 524d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa public void onItemClick(AdapterView<?> parent, View view, int position, 525d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa long id) { 52686625158bdc52855c37e96bf098ba7a213c810d7Chiao Cheng UiClosables.closeQuietly(popup); 5272b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro AccountWithDataSet newAccount = adapter.getItem(position); 528d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (!newAccount.equals(currentAccount)) { 529d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa rebindEditorsForNewContact(currentState, currentAccount, newAccount); 530d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 531d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 532d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa }); 533d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.show(); 534d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 535d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa }); 536d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 537d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 538b85b83ee4adc8b72fe68499f669ca530d58e6815Daniel Lehmann @Override 539b55107303cc46906c265582a8931172f13d684b6Walter Jang protected boolean doSaveAction(int saveMode) { 5400353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Save contact 541ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState, 542ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(), 543ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus ((Activity)mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED, 544ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus mUpdatedPhotos); 545ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus mContext.startService(intent); 54687270e1b58e669354bb1571ced686421c56deb7aJosh Gargus 54787270e1b58e669354bb1571ced686421c56deb7aJosh Gargus // Don't try to save the same photos twice. 54887270e1b58e669354bb1571ced686421c56deb7aJosh Gargus mUpdatedPhotos = new Bundle(); 54987270e1b58e669354bb1571ced686421c56deb7aJosh Gargus 550f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return true; 551f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 552f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 553ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang @Override 554f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void onSaveInstanceState(Bundle outState) { 555daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell outState.putSerializable(KEY_EXPANDED_EDITORS, mExpandedEditors); 556cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto); 557cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang outState.putParcelable(KEY_CURRENT_PHOTO_URI, mCurrentPhotoUri); 558cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos); 559f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann super.onSaveInstanceState(outState); 560f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 561f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 562d364314c460152db7089b304beec81b3675893baDmitri Plotnikov @Override 563f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void onActivityResult(int requestCode, int resultCode, Intent data) { 564f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov if (mStatus == Status.SUB_ACTIVITY) { 565f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov mStatus = Status.EDITING; 566f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov } 567f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov 5686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // See if the photo selection handler handles this result. 56991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu if (mCurrentPhotoHandler != null && mCurrentPhotoHandler.handlePhotoActivityResult( 5706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro requestCode, resultCode, data)) { 5716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return; 5726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 573f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 5743e9a62449b8ca3a38b1d51019c6ea13972263bc2Walter Jang super.onActivityResult(requestCode, resultCode, data); 575cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 5769cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov 57749ed2033f83005f92c30068ae33c3138d75e1825Walter Jang @Override 57849ed2033f83005f92c30068ae33c3138d75e1825Walter Jang protected void joinAggregate(final long contactId) { 57949ed2033f83005f92c30068ae33c3138d75e1825Walter Jang final Intent intent = ContactSaveService.createJoinContactsIntent( 580d3946cae17273ed1c2fceb507990882e3f828ba9Brian Attwell mContext, mContactIdForJoin, contactId, ContactEditorActivity.class, 581d3946cae17273ed1c2fceb507990882e3f828ba9Brian Attwell ContactEditorActivity.ACTION_JOIN_COMPLETED); 58249ed2033f83005f92c30068ae33c3138d75e1825Walter Jang mContext.startService(intent); 58349ed2033f83005f92c30068ae33c3138d75e1825Walter Jang } 58449ed2033f83005f92c30068ae33c3138d75e1825Walter Jang 585c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann /** 586c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann * Sets the photo stored in mPhoto and writes it to the RawContact with the given id 587c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann */ 588637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee private void setPhoto(long rawContact, Bitmap photo, Uri photoUri) { 589bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov BaseRawContactEditorView requestingEditor = getRawContactEditorView(rawContact); 590e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus 5913efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang if (photo == null || photo.getHeight() <= 0 || photo.getWidth() <= 0) { 592e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus // This is unexpected. 593e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus Log.w(TAG, "Invalid bitmap passed to setPhoto()"); 594e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus } 595e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus 5969302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov if (requestingEditor != null) { 597c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell requestingEditor.setPhotoEntry(photo); 5987e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell // Immediately set all other photos as non-primary. Otherwise the UI can display 5997e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell // multiple photos as "Primary photo". 6007e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell for (int i = 0; i < mContent.getChildCount(); i++) { 6017e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell final View childView = mContent.getChildAt(i); 6027e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell if (childView instanceof BaseRawContactEditorView 6037e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell && childView != requestingEditor) { 6047e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell final BaseRawContactEditorView rawContactEditor 6057e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell = (BaseRawContactEditorView) childView; 6067e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell rawContactEditor.getPhotoEditor().setSuperPrimary(false); 6077e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell } 6087e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell } 6099302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } else { 6109302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov Log.w(TAG, "The contact that requested the photo is no longer present."); 6119302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 612e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus 613637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee mUpdatedPhotos.putParcelable(String.valueOf(rawContact), photoUri); 6149302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 6159302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov 6169302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov /** 6179302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov * Finds raw contact editor view for the given rawContactId. 6189302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov */ 619d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang @Override 620d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang protected View getAggregationAnchorView(long rawContactId) { 621d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang BaseRawContactEditorView editorView = getRawContactEditorView(rawContactId); 622d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang return editorView == null ? null : editorView.findViewById(R.id.anchor_view); 623d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang } 624d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang 625bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public BaseRawContactEditorView getRawContactEditorView(long rawContactId) { 626c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann for (int i = 0; i < mContent.getChildCount(); i++) { 627c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann final View childView = mContent.getChildAt(i); 62872af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann if (childView instanceof BaseRawContactEditorView) { 62972af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView; 6309302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov if (editor.getRawContactId() == rawContactId) { 6319302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov return editor; 632c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 633c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 634c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 6359302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov return null; 636c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 637c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann 638fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann /** 639fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann * Returns true if there is currently more than one photo on screen. 640fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann */ 641fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann private boolean hasMoreThanOnePhoto() { 642fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann int countWithPicture = 0; 64391004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final int numEntities = mState.size(); 64491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu for (int i = 0; i < numEntities; i++) { 645851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta entity = mState.get(i); 646851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (entity.isVisible()) { 64791004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE); 648851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (primary != null && primary.getPhoto() != null) { 649fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann countWithPicture++; 65091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } else { 651851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final long rawContactId = entity.getRawContactId(); 652637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee final Uri uri = mUpdatedPhotos.getParcelable(String.valueOf(rawContactId)); 653637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee if (uri != null) { 654637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee try { 655637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee mContext.getContentResolver().openInputStream(uri); 65691004b37683c15650eccde68ff04defcf94a1c84Maurice Chu countWithPicture++; 657637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee } catch (FileNotFoundException e) { 65891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } 65991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } 66091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } 66191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu 66291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu if (countWithPicture > 1) { 66391004b37683c15650eccde68ff04defcf94a1c84Maurice Chu return true; 664fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann } 665fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann } 666fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann } 667fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann return false; 6689cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov } 669222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann 6706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 6716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Custom photo handler for the editor. The inner listener that this creates also has a 6726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * reference to the editor and acts as an {@link EditorListener}, and uses that editor to hold 6736fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * state information in several of the listener methods. 6746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 6756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final class PhotoHandler extends PhotoSelectionHandler { 67628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 67728eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus final long mRawContactId; 678e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus private final BaseRawContactEditorView mEditor; 6794bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki private final PhotoActionListener mPhotoEditorListener; 68028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 6816fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode, 682851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDeltaList state) { 6837e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell super(context, editor.getPhotoEditor().getChangeAnchorView(), photoMode, false, state); 684e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus mEditor = editor; 68528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus mRawContactId = editor.getRawContactId(); 6869a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann mPhotoEditorListener = new PhotoEditorListener(); 687e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus } 688e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus 689e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus @Override 690e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus public PhotoActionListener getListener() { 6919a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann return mPhotoEditorListener; 692e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus } 693e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus 694e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus @Override 695637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) { 6964bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki mRawContactIdRequestingPhoto = mEditor.getRawContactId(); 69791004b37683c15650eccde68ff04defcf94a1c84Maurice Chu mCurrentPhotoHandler = this; 698e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus mStatus = Status.SUB_ACTIVITY; 699637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee mCurrentPhotoUri = photoUri; 700e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus ContactEditorFragment.this.startActivityForResult(intent, requestCode); 7019442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 7029442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 7036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener 7046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro implements EditorListener { 705fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann 7066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 7076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onRequest(int request) { 7086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (!hasValidState()) return; 709a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 7106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (request == EditorListener.REQUEST_PICK_PHOTO) { 7116fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro onClick(mEditor.getPhotoEditor()); 7129442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 7137e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell if (request == EditorListener.REQUEST_PICK_PRIMARY_PHOTO) { 7147e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell useAsPrimaryChosen(); 7157e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell } 7169442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 717a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 7186fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 7196fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onDeleteRequested(Editor removedEditor) { 7206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // The picture cannot be deleted, it can only be removed, which is handled by 7216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // onRemovePictureChosen() 7226fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 723a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 7246fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 7256fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * User has chosen to set the selected photo as the (super) primary photo 7266fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 7277e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell public void useAsPrimaryChosen() { 7286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Set the IsSuperPrimary for each editor 7296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro int count = mContent.getChildCount(); 7306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro for (int i = 0; i < count; i++) { 7316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final View childView = mContent.getChildAt(i); 7326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (childView instanceof BaseRawContactEditorView) { 7336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final BaseRawContactEditorView editor = 7346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro (BaseRawContactEditorView) childView; 7356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final PhotoEditorView photoEditor = editor.getPhotoEditor(); 7366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro photoEditor.setSuperPrimary(editor == mEditor); 7376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 7386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 73991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu bindEditors(); 7406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 7419442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 7426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 7436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * User has chosen to remove a picture 7446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 7456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 7466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onRemovePictureChosen() { 747c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell mEditor.setPhotoEntry(null); 74828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 74928eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus // Prevent bitmap from being restored if rotate the device. 75028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus // (only if we first chose a new photo before removing it) 75128eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus mUpdatedPhotos.remove(String.valueOf(mRawContactId)); 75291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu bindEditors(); 7536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 7546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 7556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 756637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee public void onPhotoSelected(Uri uri) throws FileNotFoundException { 757637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(mContext, uri); 758637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee setPhoto(mRawContactId, bitmap, uri); 75991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu mCurrentPhotoHandler = null; 76091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu bindEditors(); 7616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 7626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 7636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 764637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee public Uri getCurrentPhotoUri() { 765637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee return mCurrentPhotoUri; 7666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 7676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 7686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 7696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onPhotoSelectionDismissed() { 7706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Nothing to do. 7719442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 7724a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann } 7734a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann } 7742ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey} 775