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