ContactEditorFragment.java revision 151f3e6883e5785019f7b5083dc8baf3e305dc18
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;
31cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.View;
32cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.ViewGroup;
33d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.AdapterView;
3480d527c94389cab477e2c75ded03eec877ea6835Daniel Lehmannimport android.widget.LinearLayout;
35d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.ListPopupWindow;
36cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
37e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService;
38e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
39e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ContactEditorActivity;
4044cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.AccountTypeManager;
4192101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactDelta;
4292101e77238e450dedb56814cec80edc0adf79c0Walter Jangimport com.android.contacts.common.model.RawContactDeltaList;
4344cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.ValuesDelta;
4444cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.account.AccountType;
4544cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.model.account.AccountWithDataSet;
4644cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter;
4744cfc56d1701629070384364416c1311b780535dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
48e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.PhotoSelectionHandler;
49e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.Editor.EditorListener;
50e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.ContactPhotoUtils;
5186625158bdc52855c37e96bf098ba7a213c810d7Chiao Chengimport com.android.contacts.util.UiClosables;
5292101e77238e450dedb56814cec80edc0adf79c0Walter Jang
53637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Leeimport java.io.FileNotFoundException;
54f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport java.util.Collections;
55daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwellimport java.util.HashMap;
56f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.List;
57f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
583f990ba4e35a99078d831c041290e574a320caa5Walter Jang/**
593f990ba4e35a99078d831c041290e574a320caa5Walter Jang * Contact editor with all fields displayed.
603f990ba4e35a99078d831c041290e574a320caa5Walter Jang */
613f990ba4e35a99078d831c041290e574a320caa5Walter Jangpublic class ContactEditorFragment extends ContactEditorBaseFragment implements
622b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann        RawContactReadOnlyEditorView.Listener {
63cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
64daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private static final String KEY_EXPANDED_EDITORS = "expandedEditors";
65f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
66cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang    private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester";
67cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang    private static final String KEY_CURRENT_PHOTO_URI = "currentphotouri";
68cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang    private static final String KEY_UPDATED_PHOTOS = "updatedPhotos";
69cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang
70fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    // Used to store which raw contact editors have been expanded. Keyed on raw contact ids.
71fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private HashMap<Long, Boolean> mExpandedEditors = new HashMap<Long, Boolean>();
72fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang
73fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    /**
74fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * The raw contact for which we started "take photo" or "choose photo from gallery" most
75fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * recently.  Used to restore {@link #mCurrentPhotoHandler} after orientation change.
76fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     */
77fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private long mRawContactIdRequestingPhoto;
7844cfc56d1701629070384364416c1311b780535dChiao Cheng
79fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    /**
80fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * The {@link PhotoHandler} for the photo editor for the {@link #mRawContactIdRequestingPhoto}
81fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * raw contact.
82fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     *
83fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * A {@link PhotoHandler} is created for each photo editor in {@link #bindPhotoHandler}, but
84fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * the only "active" one should get the activity result.  This member represents the active
85fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     * one.
86fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang     */
87fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private PhotoHandler mCurrentPhotoHandler;
88fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private Uri mCurrentPhotoUri;
89fb5dc6f857104c38ff49993d7498e8aa5fbc462eWalter Jang    private Bundle mUpdatedPhotos = new Bundle();
90daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
91cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    public ContactEditorFragment() {
92cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
93cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
94cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    @Override
95cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
96cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        final View view = inflater.inflate(R.layout.contact_editor_fragment, container, false);
97cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
98f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        mContent = (LinearLayout) view.findViewById(R.id.editors);
99e8767a1136d2a2f9cb3e3ca5f44b2142baab9709Daniel Lehmann
1003648d2ea76a6649230d1fdd3dba92797ae7cfb26Daniel Lehmann        setHasOptionsMenu(true);
101cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
102cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        return view;
103cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
104cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
105222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann    @Override
106f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    public void onCreate(Bundle savedState) {
107f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        super.onCreate(savedState);
108f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
109ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang        if (savedState != null) {
110daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            mExpandedEditors = (HashMap<Long, Boolean>)
111daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                    savedState.getSerializable(KEY_EXPANDED_EDITORS);
112cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang            mRawContactIdRequestingPhoto = savedState.getLong(
113cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang                    KEY_RAW_CONTACT_ID_REQUESTING_PHOTO);
114cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang            mCurrentPhotoUri = savedState.getParcelable(KEY_CURRENT_PHOTO_URI);
115cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang            mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS);
11644cfc56d1701629070384364416c1311b780535dChiao Cheng        }
117fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov    }
118fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov
119fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov    @Override
1202b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro    public void onExternalEditorRequest(AccountWithDataSet account, Uri uri) {
121fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov        mListener.onCustomEditContactActivityRequested(account, uri, null, false);
122fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov    }
123fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov
124daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    @Override
125daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    public void onEditorExpansionChanged() {
126daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        updatedExpandedEditorsMap();
127daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    }
128daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
129d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    /**
130d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Removes a current editor ({@link #mState}) and rebinds new editor for a new account.
131d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Some of old data are reused with new restriction enforced by the new account.
132d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     *
1332b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro     * @param oldState Old data being edited.
134d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @param oldAccount Old account associated with oldState.
135d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @param newAccount New account to be used.
136d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     */
137d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    private void rebindEditorsForNewContact(
138851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            RawContactDelta oldState, AccountWithDataSet oldAccount,
139851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            AccountWithDataSet newAccount) {
140d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
14167e83223e954ed54898daa5e32400dbff6d3831aJay Shrauner        AccountType oldAccountType = accountTypes.getAccountTypeForAccount(oldAccount);
14267e83223e954ed54898daa5e32400dbff6d3831aJay Shrauner        AccountType newAccountType = accountTypes.getAccountTypeForAccount(newAccount);
143d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
144d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        if (newAccountType.getCreateContactActivityClassName() != null) {
145d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            Log.w(TAG, "external activity called in rebind situation");
146d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            if (mListener != null) {
147d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                mListener.onCustomCreateContactActivityRequested(newAccount, mIntentExtras);
148d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
149d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        } else {
15044cfc56d1701629070384364416c1311b780535dChiao Cheng            mExistingContactDataReady = false;
15144cfc56d1701629070384364416c1311b780535dChiao Cheng            mNewContactDataReady = false;
15244cfc56d1701629070384364416c1311b780535dChiao Cheng            mState = new RawContactDeltaList();
153b55107303cc46906c265582a8931172f13d684b6Walter Jang            setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType);
15444cfc56d1701629070384364416c1311b780535dChiao Cheng            if (mIsEdit) {
155b55107303cc46906c265582a8931172f13d684b6Walter Jang                setStateForExistingContact(mDefaultDisplayName, mIsUserProfile, mRawContacts);
15644cfc56d1701629070384364416c1311b780535dChiao Cheng            }
157d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        }
158d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
159d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
160ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    @Override
16192f8ccc1f15df787b7434224857c056721281046Walter Jang    protected void setGroupMetaData() {
16292f8ccc1f15df787b7434224857c056721281046Walter Jang        if (mGroupMetaData == null) {
16392f8ccc1f15df787b7434224857c056721281046Walter Jang            return;
16492f8ccc1f15df787b7434224857c056721281046Walter Jang        }
16592f8ccc1f15df787b7434224857c056721281046Walter Jang        int editorCount = mContent.getChildCount();
16692f8ccc1f15df787b7434224857c056721281046Walter Jang        for (int i = 0; i < editorCount; i++) {
16792f8ccc1f15df787b7434224857c056721281046Walter Jang            BaseRawContactEditorView editor = (BaseRawContactEditorView) mContent.getChildAt(i);
16892f8ccc1f15df787b7434224857c056721281046Walter Jang            editor.setGroupMetaData(mGroupMetaData);
16992f8ccc1f15df787b7434224857c056721281046Walter Jang        }
17092f8ccc1f15df787b7434224857c056721281046Walter Jang    }
17192f8ccc1f15df787b7434224857c056721281046Walter Jang
17292f8ccc1f15df787b7434224857c056721281046Walter Jang    @Override
173ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    protected void bindEditors() {
1745671c7e7718c3285dc0391807401083986fcfd51Maurice Chu        // bindEditors() can only bind views if there is data in mState, so immediately return
1755671c7e7718c3285dc0391807401083986fcfd51Maurice Chu        // if mState is null
17644cfc56d1701629070384364416c1311b780535dChiao Cheng        if (mState.isEmpty()) {
17744cfc56d1701629070384364416c1311b780535dChiao Cheng            return;
17844cfc56d1701629070384364416c1311b780535dChiao Cheng        }
17944cfc56d1701629070384364416c1311b780535dChiao Cheng
18044cfc56d1701629070384364416c1311b780535dChiao Cheng        // Check if delta list is ready.  Delta list is populated from existing data and when
18144cfc56d1701629070384364416c1311b780535dChiao Cheng        // editing an read-only contact, it's also populated with newly created data for the
18244cfc56d1701629070384364416c1311b780535dChiao Cheng        // blank form.  When the data is not ready, skip. This method will be called multiple times.
18344cfc56d1701629070384364416c1311b780535dChiao Cheng        if ((mIsEdit && !mExistingContactDataReady) || (mHasNewContact && !mNewContactDataReady)) {
1845671c7e7718c3285dc0391807401083986fcfd51Maurice Chu            return;
1855671c7e7718c3285dc0391807401083986fcfd51Maurice Chu        }
1865671c7e7718c3285dc0391807401083986fcfd51Maurice Chu
187f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        // Sort the editors
188f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        Collections.sort(mState, mComparator);
189cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
190f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        // Remove any existing editors and rebuild any visible
191f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        mContent.removeAllViews();
192cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
193f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
194f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann                Context.LAYOUT_INFLATER_SERVICE);
195a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
196a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan        int numRawContacts = mState.size();
19744cfc56d1701629070384364416c1311b780535dChiao Cheng
198a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan        for (int i = 0; i < numRawContacts; i++) {
199f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann            // TODO ensure proper ordering of entities in the list
200851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta rawContactDelta = mState.get(i);
201851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (!rawContactDelta.isVisible()) continue;
202f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
203851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final AccountType type = rawContactDelta.getAccountType(accountTypes);
204851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final long rawContactId = rawContactDelta.getRawContactId();
205f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
20672af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann            final BaseRawContactEditorView editor;
2072b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann            if (!type.areContactsWritable()) {
208fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov                editor = (BaseRawContactEditorView) inflater.inflate(
2092b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann                        R.layout.raw_contact_readonly_editor_view, mContent, false);
210fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov            } else {
211fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan                editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view,
212fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan                        mContent, false);
213cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            }
214daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            editor.setListener(this);
215daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(mContext)
216daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                    .getAccounts(true);
217daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            if (mHasNewContact && !mNewLocalProfile && accounts.size() > 1) {
218daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                addAccountSwitcher(mState.get(0), editor);
219d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
220a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan
221b55107303cc46906c265582a8931172f13d684b6Walter Jang            editor.setEnabled(isEnabled());
222cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
223daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            if (mExpandedEditors.containsKey(rawContactId)) {
224daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                editor.setCollapsed(mExpandedEditors.get(rawContactId));
225daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            } else {
226daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                // By default, only the first editor will be expanded.
227daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                editor.setCollapsed(i != 0);
228daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            }
229daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
230f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann            mContent.addView(editor);
2317d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
232851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile());
233daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            editor.setCollapsible(numRawContacts > 1);
234f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
2356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            // Set up the photo handler.
2366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            bindPhotoHandler(editor, type, mState);
2376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
238c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            // If a new photo was chosen but not yet saved, we need to update the UI to
239c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            // reflect this.
240c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            final Uri photoUri = updatedPhotoUriForRawContact(rawContactId);
241c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            if (photoUri != null) editor.setFullSizedPhoto(photoUri);
24228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
24372af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann            if (editor instanceof RawContactEditorView) {
2442828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                final Activity activity = getActivity();
24572af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann                final RawContactEditorView rawContactEditor = (RawContactEditorView) editor;
246151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                final ValuesDelta nameValuesDelta = rawContactEditor.getNameEditor().getValues();
247151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                final EditorListener structuredNameListener = new EditorListener() {
248f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
249f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    @Override
250f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    public void onRequest(int request) {
251151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        // Make sure the activity is running
252151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        if (activity.isFinishing()) {
2532828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                            return;
2542828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki                        }
255151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        if (request == EditorListener.EDITOR_FOCUS_CHANGED) {
256151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                            adjustNameFieldsHintDarkness(rawContactEditor);
257151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                            return;
258151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        }
259151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        if (!isEditingUserProfile()) {
260151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                            if (request == EditorListener.FIELD_CHANGED) {
261151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                if (!nameValuesDelta.isSuperPrimary()) {
262151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                    unsetSuperPrimaryForAllNameEditors();
263151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                    nameValuesDelta.setSuperPrimary(true);
264151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                }
265151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                acquireAggregationSuggestions(activity,
266151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                        rawContactEditor.getNameEditor().getRawContactId(),
267151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                        rawContactEditor.getNameEditor().getValues());
268151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                            } else if (request == EditorListener.FIELD_TURNED_EMPTY) {
269151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                if (nameValuesDelta.isSuperPrimary()) {
270151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                    nameValuesDelta.setSuperPrimary(false);
271151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                                }
272151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                            }
273151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        }
274151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    }
275151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang
276151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    @Override
277151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    public void onDeleteRequested(Editor removedEditor) {
278151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    }
279151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                };
280151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                final EditorListener otherNamesListener = new EditorListener() {
281151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang
282151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    @Override
283151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    public void onRequest(int request) {
284151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        // Make sure the activity is running
285151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        if (activity.isFinishing()) {
286151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                            return;
287151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        }
288151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        if (request == EditorListener.EDITOR_FOCUS_CHANGED) {
289d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                            adjustNameFieldsHintDarkness(rawContactEditor);
29011bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov                        }
291f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    }
292f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
293f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    @Override
2942293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan                    public void onDeleteRequested(Editor removedEditor) {
295f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                    }
2965ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                };
2975ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
29844cfc56d1701629070384364416c1311b780535dChiao Cheng                final StructuredNameEditorView nameEditor = rawContactEditor.getNameEditor();
2995ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                if (mRequestFocus) {
3005ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                    nameEditor.requestFocus();
3015ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                    mRequestFocus = false;
3025ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                }
303151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                nameEditor.setEditorListener(structuredNameListener);
304688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee                if (!TextUtils.isEmpty(mDefaultDisplayName)) {
305688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee                    nameEditor.setDisplayName(mDefaultDisplayName);
306688c228b2d7cf0c812fb673451f24e7cb457d63bYorke Lee                }
307f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov
3085ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                final TextFieldsEditorView phoneticNameEditor =
3095ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                        rawContactEditor.getPhoneticNameEditor();
310151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                phoneticNameEditor.setEditorListener(otherNamesListener);
3117d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);
3127d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
313d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                final TextFieldsEditorView nickNameEditor =
314d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                        rawContactEditor.getNickNameEditor();
315151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                nickNameEditor.setEditorListener(otherNamesListener);
316d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
3173e9a62449b8ca3a38b1d51019c6ea13972263bc2Walter Jang                if (isAggregationSuggestionRawContactId(rawContactId)) {
318d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang                    acquireAggregationSuggestions(activity,
319d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang                            rawContactEditor.getNameEditor().getRawContactId(),
320d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang                            rawContactEditor.getNameEditor().getValues());
321f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov                }
322d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
323d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                adjustNameFieldsHintDarkness(rawContactEditor);
324f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov            }
325cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        }
326f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
327eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov        mRequestFocus = false;
328eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov
329b55107303cc46906c265582a8931172f13d684b6Walter Jang        setGroupMetaData();
330e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov
331f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        // Show editor now that we've loaded state
332f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        mContent.setVisibility(View.VISIBLE);
333a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
334a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann        // Refresh Action Bar as the visibility of the join command
335825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann        // Activity can be null if we have been detached from the Activity
33692f8ccc1f15df787b7434224857c056721281046Walter Jang        invalidateOptionsMenu();
337daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
338daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        updatedExpandedEditorsMap();
339daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    }
340daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
341151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang    private void unsetSuperPrimaryForAllNameEditors() {
342151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang        for (int i = 0; i < mContent.getChildCount(); i++) {
343151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang            final View view = mContent.getChildAt(i);
344151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang            if (view instanceof RawContactEditorView) {
345151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                final RawContactEditorView rawContactEditorView = (RawContactEditorView) view;
346151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                final StructuredNameEditorView nameEditorView =
347151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        rawContactEditorView.getNameEditor();
348151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                if (nameEditorView != null) {
349151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    final ValuesDelta valuesDelta = nameEditorView.getValues();
350151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    if (valuesDelta != null) {
351151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                        valuesDelta.setSuperPrimary(false);
352151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                    }
353151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang                }
354151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang            }
355151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang        }
356151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang    }
357151f3e6883e5785019f7b5083dc8baf3e305dc18Walter Jang
358daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    /**
359d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     * Adjust how dark the hint text should be on all the names' text fields.
360d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     *
361d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     * @param rawContactEditor editor to update
362d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell     */
363d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    private void adjustNameFieldsHintDarkness(RawContactEditorView rawContactEditor) {
364d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        // Check whether fields contain focus by calling findFocus() instead of hasFocus().
365d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        // The hasFocus() value is not necessarily up to date.
366d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        final boolean nameFieldsAreNotFocused
367d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                = rawContactEditor.getNameEditor().findFocus() == null
368d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                && rawContactEditor.getPhoneticNameEditor().findFocus() == null
369d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell                && rawContactEditor.getNickNameEditor().findFocus() == null;
370d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        rawContactEditor.getNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
371d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        rawContactEditor.getPhoneticNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
372d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        rawContactEditor.getNickNameEditor().setHintColorDark(!nameFieldsAreNotFocused);
373d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    }
374d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
375d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    /**
376daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell     * Update the values in {@link #mExpandedEditors}.
377daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell     */
378daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private void updatedExpandedEditorsMap() {
379daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        for (int i = 0; i < mContent.getChildCount(); i++) {
380daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            final View childView = mContent.getChildAt(i);
381daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            if (childView instanceof BaseRawContactEditorView) {
382daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                BaseRawContactEditorView childEditor = (BaseRawContactEditorView) childView;
383daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                mExpandedEditors.put(childEditor.getRawContactId(), childEditor.isCollapsed());
384daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            }
385daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        }
3866fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    }
387eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov
38828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus    /**
389c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell     * If we've stashed a temporary file containing a contact's new photo, return its URI.
39028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus     * @param rawContactId identifies the raw-contact whose Bitmap we'll try to return.
391c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell     * @return Uru of photo for specified raw-contact, or null
392c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell     */
393c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell    private Uri updatedPhotoUriForRawContact(long rawContactId) {
394c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell        return (Uri) mUpdatedPhotos.get(String.valueOf(rawContactId));
39528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus    }
39628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
3976fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
398851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            RawContactDeltaList state) {
3996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        final int mode;
4007e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell        final boolean showIsPrimaryOption;
4016fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        if (type.areContactsWritable()) {
4026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            if (editor.hasSetPhoto()) {
4037e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                mode = PhotoActionPopup.Modes.WRITE_ABLE_PHOTO;
4047e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                showIsPrimaryOption = hasMoreThanOnePhoto();
4056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            } else {
406ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus                mode = PhotoActionPopup.Modes.NO_PHOTO;
4077e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                showIsPrimaryOption = false;
4086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
4097e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell        } else if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) {
4107e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            mode = PhotoActionPopup.Modes.READ_ONLY_PHOTO;
4117e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            showIsPrimaryOption = true;
4126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        } else {
4137e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            // Read-only and either no photo or the only photo ==> no options
4147e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            editor.getPhotoEditor().setEditorListener(null);
4157e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            editor.getPhotoEditor().setShowPrimary(false);
4167e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            return;
4176fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        }
41891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state);
4196fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        editor.getPhotoEditor().setEditorListener(
42091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                (PhotoHandler.PhotoEditorListener) photoHandler.getListener());
4217e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell        editor.getPhotoEditor().setShowPrimary(showIsPrimaryOption);
4224bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki
4234bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        // Note a newly created raw contact gets some random negative ID, so any value is valid
4244bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        // here. (i.e. don't check against -1 or anything.)
4254bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        if (mRawContactIdRequestingPhoto == editor.getRawContactId()) {
4264bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki            mCurrentPhotoHandler = photoHandler;
4274bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        }
428cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
429cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
430d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    private void addAccountSwitcher(
431851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta currentState, BaseRawContactEditorView editor) {
4322b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        final AccountWithDataSet currentAccount = new AccountWithDataSet(
433851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                currentState.getAccountName(),
434851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                currentState.getAccountType(),
435851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                currentState.getDataSet());
436d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        final View accountView = editor.findViewById(R.id.account);
437daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        final View anchorView = editor.findViewById(R.id.account_selector_container);
438daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        if (accountView == null) {
439daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell            return;
440daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        }
441daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        anchorView.setVisibility(View.VISIBLE);
442d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        accountView.setOnClickListener(new View.OnClickListener() {
443d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            @Override
444d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            public void onClick(View v) {
445d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                final ListPopupWindow popup = new ListPopupWindow(mContext, null);
446a6c8f2daa80f1816dd25237457d7f6287c6b1b7cDaisuke Miyakawa                final AccountsListAdapter adapter =
4476f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki                        new AccountsListAdapter(mContext,
4486f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki                        AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, currentAccount);
449d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setWidth(anchorView.getWidth());
450d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setAnchorView(anchorView);
451d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setAdapter(adapter);
452d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setModal(true);
453d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
454d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
455d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    @Override
456d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    public void onItemClick(AdapterView<?> parent, View view, int position,
457d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                            long id) {
45886625158bdc52855c37e96bf098ba7a213c810d7Chiao Cheng                        UiClosables.closeQuietly(popup);
4592b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                        AccountWithDataSet newAccount = adapter.getItem(position);
460d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        if (!newAccount.equals(currentAccount)) {
461d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                            rebindEditorsForNewContact(currentState, currentAccount, newAccount);
462d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        }
463d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    }
464d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                });
465d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                popup.show();
466d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
467d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        });
468d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
469d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
470b85b83ee4adc8b72fe68499f669ca530d58e6815Daniel Lehmann    @Override
471b55107303cc46906c265582a8931172f13d684b6Walter Jang    protected boolean doSaveAction(int saveMode) {
4720353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan        // Save contact
473ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus        Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
474ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus                SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
475ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus                ((Activity)mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED,
476ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus                mUpdatedPhotos);
477ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus        mContext.startService(intent);
47887270e1b58e669354bb1571ced686421c56deb7aJosh Gargus
47987270e1b58e669354bb1571ced686421c56deb7aJosh Gargus        // Don't try to save the same photos twice.
48087270e1b58e669354bb1571ced686421c56deb7aJosh Gargus        mUpdatedPhotos = new Bundle();
48187270e1b58e669354bb1571ced686421c56deb7aJosh Gargus
482f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        return true;
483f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    }
484f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
485ba59deb669cf377bedf08af53c9196db3c1cc404Walter Jang    @Override
486f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    public void onSaveInstanceState(Bundle outState) {
487daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        outState.putSerializable(KEY_EXPANDED_EDITORS, mExpandedEditors);
488cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang        outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto);
489cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang        outState.putParcelable(KEY_CURRENT_PHOTO_URI, mCurrentPhotoUri);
490cf718aa47c11453925bb20f7970ca7c897f6e376Walter Jang        outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos);
491f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann        super.onSaveInstanceState(outState);
492f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    }
493f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
494d364314c460152db7089b304beec81b3675893baDmitri Plotnikov    @Override
495f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann    public void onActivityResult(int requestCode, int resultCode, Intent data) {
496f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov        if (mStatus == Status.SUB_ACTIVITY) {
497f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov            mStatus = Status.EDITING;
498f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov        }
499f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov
5006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        // See if the photo selection handler handles this result.
50191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        if (mCurrentPhotoHandler != null && mCurrentPhotoHandler.handlePhotoActivityResult(
5026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                requestCode, resultCode, data)) {
5036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            return;
5046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        }
505f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann
5063e9a62449b8ca3a38b1d51019c6ea13972263bc2Walter Jang        super.onActivityResult(requestCode, resultCode, data);
507cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    }
5089cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov
50949ed2033f83005f92c30068ae33c3138d75e1825Walter Jang    @Override
51049ed2033f83005f92c30068ae33c3138d75e1825Walter Jang    protected void joinAggregate(final long contactId) {
51149ed2033f83005f92c30068ae33c3138d75e1825Walter Jang        final Intent intent = ContactSaveService.createJoinContactsIntent(
51249ed2033f83005f92c30068ae33c3138d75e1825Walter Jang                mContext, mContactIdForJoin, contactId, mContactWritableForJoin,
51349ed2033f83005f92c30068ae33c3138d75e1825Walter Jang                ContactEditorActivity.class, ContactEditorActivity.ACTION_JOIN_COMPLETED);
51449ed2033f83005f92c30068ae33c3138d75e1825Walter Jang        mContext.startService(intent);
51549ed2033f83005f92c30068ae33c3138d75e1825Walter Jang    }
51649ed2033f83005f92c30068ae33c3138d75e1825Walter Jang
517c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann    /**
518c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann     * Sets the photo stored in mPhoto and writes it to the RawContact with the given id
519c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann     */
520637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee    private void setPhoto(long rawContact, Bitmap photo, Uri photoUri) {
521bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov        BaseRawContactEditorView requestingEditor = getRawContactEditorView(rawContact);
522e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus
5233efae4aeae8715fbfcf67c56f123da49330ea01aWalter Jang        if (photo == null || photo.getHeight() <= 0 || photo.getWidth() <= 0) {
524e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus            // This is unexpected.
525e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus            Log.w(TAG, "Invalid bitmap passed to setPhoto()");
526e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus        }
527e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus
5289302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        if (requestingEditor != null) {
529c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell            requestingEditor.setPhotoEntry(photo);
5307e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            // Immediately set all other photos as non-primary. Otherwise the UI can display
5317e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            // multiple photos as "Primary photo".
5327e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            for (int i = 0; i < mContent.getChildCount(); i++) {
5337e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                final View childView = mContent.getChildAt(i);
5347e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                if (childView instanceof BaseRawContactEditorView
5357e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                        && childView != requestingEditor) {
5367e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                    final BaseRawContactEditorView rawContactEditor
5377e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                            = (BaseRawContactEditorView) childView;
5387e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                    rawContactEditor.getPhotoEditor().setSuperPrimary(false);
5397e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                }
5407e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            }
5419302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        } else {
5429302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov            Log.w(TAG, "The contact that requested the photo is no longer present.");
5439302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        }
544e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus
545637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee        mUpdatedPhotos.putParcelable(String.valueOf(rawContact), photoUri);
5469302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov    }
5479302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov
5489302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov    /**
5499302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov     * Finds raw contact editor view for the given rawContactId.
5509302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov     */
551d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang    @Override
552d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang    protected View getAggregationAnchorView(long rawContactId) {
553d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang        BaseRawContactEditorView editorView = getRawContactEditorView(rawContactId);
554d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang        return editorView == null ? null : editorView.findViewById(R.id.anchor_view);
555d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang    }
556d35e5eff8737e757a4179d49dfe9c7db999b4e9dWalter Jang
557bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov    public BaseRawContactEditorView getRawContactEditorView(long rawContactId) {
558c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann        for (int i = 0; i < mContent.getChildCount(); i++) {
559c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann            final View childView = mContent.getChildAt(i);
56072af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann            if (childView instanceof BaseRawContactEditorView) {
56172af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann                final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
5629302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov                if (editor.getRawContactId() == rawContactId) {
5639302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov                    return editor;
564c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann                }
565c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann            }
566c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann        }
5679302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov        return null;
568c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann    }
569c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann
570fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann    /**
571fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann     * Returns true if there is currently more than one photo on screen.
572fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann     */
573fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann    private boolean hasMoreThanOnePhoto() {
574fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann        int countWithPicture = 0;
57591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        final int numEntities = mState.size();
57691004b37683c15650eccde68ff04defcf94a1c84Maurice Chu        for (int i = 0; i < numEntities; i++) {
577851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta entity = mState.get(i);
578851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (entity.isVisible()) {
57991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
580851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                if (primary != null && primary.getPhoto() != null) {
581fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann                    countWithPicture++;
58291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                } else {
583851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    final long rawContactId = entity.getRawContactId();
584637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                    final Uri uri = mUpdatedPhotos.getParcelable(String.valueOf(rawContactId));
585637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                    if (uri != null) {
586637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                        try {
587637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                            mContext.getContentResolver().openInputStream(uri);
58891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                            countWithPicture++;
589637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                        } catch (FileNotFoundException e) {
59091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                        }
59191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                    }
59291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                }
59391004b37683c15650eccde68ff04defcf94a1c84Maurice Chu
59491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                if (countWithPicture > 1) {
59591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                    return true;
596fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann                }
597fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann            }
598fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann        }
599fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann        return false;
6009cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov    }
601222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann
6026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    /**
6036fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     * Custom photo handler for the editor.  The inner listener that this creates also has a
6046fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     * reference to the editor and acts as an {@link EditorListener}, and uses that editor to hold
6056fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     * state information in several of the listener methods.
6066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro     */
6076fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    private final class PhotoHandler extends PhotoSelectionHandler {
60828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
60928eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus        final long mRawContactId;
610e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        private final BaseRawContactEditorView mEditor;
6114bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki        private final PhotoActionListener mPhotoEditorListener;
61228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
6136fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
614851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                RawContactDeltaList state) {
6157e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            super(context, editor.getPhotoEditor().getChangeAnchorView(), photoMode, false, state);
616e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus            mEditor = editor;
61728eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus            mRawContactId = editor.getRawContactId();
6189a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann            mPhotoEditorListener = new PhotoEditorListener();
619e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        }
620e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus
621e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        @Override
622e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        public PhotoActionListener getListener() {
6239a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann            return mPhotoEditorListener;
624e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        }
625e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus
626e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus        @Override
627637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee        public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) {
6284bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
62991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu            mCurrentPhotoHandler = this;
630e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus            mStatus = Status.SUB_ACTIVITY;
631637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee            mCurrentPhotoUri = photoUri;
632e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus            ContactEditorFragment.this.startActivityForResult(intent, requestCode);
6339442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann        }
6349442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann
6356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
6366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                implements EditorListener {
637fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann
6386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onRequest(int request) {
6406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                if (!hasValidState()) return;
641a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
6426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                if (request == EditorListener.REQUEST_PICK_PHOTO) {
6436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    onClick(mEditor.getPhotoEditor());
6449442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann                }
6457e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                if (request == EditorListener.REQUEST_PICK_PRIMARY_PHOTO) {
6467e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                    useAsPrimaryChosen();
6477e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell                }
6489442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann            }
649a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
6506fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onDeleteRequested(Editor removedEditor) {
6526fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // The picture cannot be deleted, it can only be removed, which is handled by
6536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // onRemovePictureChosen()
6546fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
655a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann
6566fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            /**
6576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             * User has chosen to set the selected photo as the (super) primary photo
6586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             */
6597e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell            public void useAsPrimaryChosen() {
6606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // Set the IsSuperPrimary for each editor
6616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                int count = mContent.getChildCount();
6626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                for (int i = 0; i < count; i++) {
6636fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    final View childView = mContent.getChildAt(i);
6646fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    if (childView instanceof BaseRawContactEditorView) {
6656fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                        final BaseRawContactEditorView editor =
6666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                                (BaseRawContactEditorView) childView;
6676fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                        final PhotoEditorView photoEditor = editor.getPhotoEditor();
6686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                        photoEditor.setSuperPrimary(editor == mEditor);
6696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    }
6706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                }
67191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                bindEditors();
6726fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6739442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann
6746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            /**
6756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             * User has chosen to remove a picture
6766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro             */
6776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
6786fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onRemovePictureChosen() {
679c300521331c04767cd19dfe05ab77567514bbaa0Brian Attwell                mEditor.setPhotoEntry(null);
68028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus
68128eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus                // Prevent bitmap from being restored if rotate the device.
68228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus                // (only if we first chose a new photo before removing it)
68328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus                mUpdatedPhotos.remove(String.valueOf(mRawContactId));
68491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                bindEditors();
6856fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6866fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
6876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
688637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee            public void onPhotoSelected(Uri uri) throws FileNotFoundException {
689637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(mContext, uri);
690637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                setPhoto(mRawContactId, bitmap, uri);
69191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                mCurrentPhotoHandler = null;
69291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu                bindEditors();
6936fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6946fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
6956fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
696637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee            public Uri getCurrentPhotoUri() {
697637a38ec9de6b1f434d7a13105f2e747faae5107Yorke Lee                return mCurrentPhotoUri;
6986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
6996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
7006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            @Override
7016fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            public void onPhotoSelectionDismissed() {
7026fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                // Nothing to do.
7039442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann            }
7044a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann        }
7054a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann    }
7062ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey}
707