ContactEditorFragment.java revision 36184f630cdb97d0a642de25f69962ef2abfedb1
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 19f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport android.accounts.Account; 20cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.app.Activity; 21bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikovimport android.app.AlertDialog; 22bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikovimport android.app.Dialog; 23bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikovimport android.app.DialogFragment; 24222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmannimport android.app.Fragment; 25222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmannimport android.app.LoaderManager; 26222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmannimport android.app.LoaderManager.LoaderCallbacks; 27cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.ContentUris; 28cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.ContentValues; 29cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Context; 30e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikovimport android.content.CursorLoader; 31bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikovimport android.content.DialogInterface; 32cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Intent; 33cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.content.Loader; 34f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport android.database.Cursor; 35f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport android.graphics.Bitmap; 3628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargusimport android.graphics.BitmapFactory; 37cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.net.Uri; 38cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.os.Bundle; 399767e09ae37332d74b5558a3ec16ded20a9328dcDaniel Lehmannimport android.os.SystemClock; 40cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Email; 41362acdb3da27524d42c4bb44423d6276c5738616Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Event; 42362acdb3da27524d42c4bb44423d6276c5738616Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Organization; 43cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Phone; 4491004b37683c15650eccde68ff04defcf94a1c84Maurice Chuimport android.provider.ContactsContract.CommonDataKinds.Photo; 45362acdb3da27524d42c4bb44423d6276c5738616Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 46f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 47be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuanimport android.provider.ContactsContract.Groups; 482013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmannimport android.provider.ContactsContract.Intents; 49f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 50cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.util.Log; 51cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.LayoutInflater; 52cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.Menu; 53cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.MenuInflater; 54cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.MenuItem; 55cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.View; 56cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.view.ViewGroup; 57d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.AdapterView; 586c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawaimport android.widget.AdapterView.OnItemClickListener; 596c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawaimport android.widget.BaseAdapter; 6080d527c94389cab477e2c75ded03eec877ea6835Daniel Lehmannimport android.widget.LinearLayout; 61d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.widget.ListPopupWindow; 62cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.widget.Toast; 63cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 64e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService; 65e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.GroupMetaDataLoader; 66e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 67e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ContactEditorAccountsChangedActivity; 68e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ContactEditorActivity; 69e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.JoinContactActivity; 70e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.PhotoSelectionHandler; 71e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.AggregationSuggestionEngine.Suggestion; 72e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.Editor.EditorListener; 730d5588da244d0992c3ff8f25d0875fdf95a8c644Chiao Chengimport com.android.contacts.common.model.AccountTypeManager; 74851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.Contact; 75851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.ContactLoader; 76851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContact; 77851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta; 78738ff8623dc77dd91a1b9023861e924ba5e4c27eChiao Chengimport com.android.contacts.common.model.ValuesDelta; 79851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDeltaList; 80851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactModifier; 81428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountType; 82428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountWithDataSet; 83428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.GoogleAccountType; 8487c71f43c70cd970e54eecbfa4c8d79259922c5dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter; 8587c71f43c70cd970e54eecbfa4c8d79259922c5dChiao Chengimport com.android.contacts.common.util.AccountsListAdapter.AccountListFilter; 86e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.ContactPhotoUtils; 87e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.HelpUtils; 88851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.google.common.collect.ImmutableList; 89e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 90f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport java.io.File; 91cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport java.util.ArrayList; 92f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport java.util.Collections; 93f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmannimport java.util.Comparator; 94f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.List; 95f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 96a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmannpublic class ContactEditorFragment extends Fragment implements 97d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa SplitContactConfirmationDialogFragment.Listener, 98fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov AggregationSuggestionEngine.Listener, AggregationSuggestionView.Listener, 992b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann RawContactReadOnlyEditorView.Listener { 100cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 1012245870a1354df03512010e4968b144840894fb7Frank Sposaro private static final String TAG = ContactEditorFragment.class.getSimpleName(); 102cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 103f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private static final int LOADER_DATA = 1; 104e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov private static final int LOADER_GROUPS = 2; 105f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 106d364314c460152db7089b304beec81b3675893baDmitri Plotnikov private static final String KEY_URI = "uri"; 107d364314c460152db7089b304beec81b3675893baDmitri Plotnikov private static final String KEY_ACTION = "action"; 108f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private static final String KEY_EDIT_STATE = "state"; 1094bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester"; 110f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private static final String KEY_VIEW_ID_GENERATOR = "viewidgenerator"; 111f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private static final String KEY_CURRENT_PHOTO_FILE = "currentphotofile"; 112f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin"; 113623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann private static final String KEY_CONTACT_WRITABLE_FOR_JOIN = "contactwritableforjoin"; 1149302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov private static final String KEY_SHOW_JOIN_SUGGESTIONS = "showJoinSuggestions"; 11502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov private static final String KEY_ENABLED = "enabled"; 116ce37f3017c666bcea483a75322e80d5cc1ba6f64Dmitri Plotnikov private static final String KEY_STATUS = "status"; 117ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson private static final String KEY_NEW_LOCAL_PROFILE = "newLocalProfile"; 118ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson private static final String KEY_IS_USER_PROFILE = "isUserProfile"; 11928eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus private static final String KEY_UPDATED_PHOTOS = "updatedPhotos"; 120f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 121a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov public static final String SAVE_MODE_EXTRA_KEY = "saveMode"; 122a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov 123098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng 12415972398b530b91612418dc11d41c356d4f43739Daniel Lehmann /** 1257d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov * An intent extra that forces the editor to add the edited contact 1267d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov * to the default group (e.g. "My Contacts"). 1277d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov */ 1287d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov public static final String INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY = "addToDefaultDirectory"; 1297d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov 130ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson public static final String INTENT_EXTRA_NEW_LOCAL_PROFILE = "newLocalProfile"; 131ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson 1327d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov /** 13315972398b530b91612418dc11d41c356d4f43739Daniel Lehmann * Modes that specify what the AsyncTask has to perform after saving 13415972398b530b91612418dc11d41c356d4f43739Daniel Lehmann */ 1359df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov public interface SaveMode { 13615972398b530b91612418dc11d41c356d4f43739Daniel Lehmann /** 13715972398b530b91612418dc11d41c356d4f43739Daniel Lehmann * Close the editor after saving 13815972398b530b91612418dc11d41c356d4f43739Daniel Lehmann */ 13915972398b530b91612418dc11d41c356d4f43739Daniel Lehmann public static final int CLOSE = 0; 14015972398b530b91612418dc11d41c356d4f43739Daniel Lehmann 14115972398b530b91612418dc11d41c356d4f43739Daniel Lehmann /** 14215972398b530b91612418dc11d41c356d4f43739Daniel Lehmann * Reload the data so that the user can continue editing 14315972398b530b91612418dc11d41c356d4f43739Daniel Lehmann */ 14415972398b530b91612418dc11d41c356d4f43739Daniel Lehmann public static final int RELOAD = 1; 14515972398b530b91612418dc11d41c356d4f43739Daniel Lehmann 14615972398b530b91612418dc11d41c356d4f43739Daniel Lehmann /** 14715972398b530b91612418dc11d41c356d4f43739Daniel Lehmann * Split the contact after saving 14815972398b530b91612418dc11d41c356d4f43739Daniel Lehmann */ 14915972398b530b91612418dc11d41c356d4f43739Daniel Lehmann public static final int SPLIT = 2; 15015972398b530b91612418dc11d41c356d4f43739Daniel Lehmann 15115972398b530b91612418dc11d41c356d4f43739Daniel Lehmann /** 15215972398b530b91612418dc11d41c356d4f43739Daniel Lehmann * Join another contact after saving 15315972398b530b91612418dc11d41c356d4f43739Daniel Lehmann */ 15415972398b530b91612418dc11d41c356d4f43739Daniel Lehmann public static final int JOIN = 3; 1559df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov 1569df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov /** 1579df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov * Navigate to Contacts Home activity after saving. 1589df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov */ 1599df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov public static final int HOME = 4; 16015972398b530b91612418dc11d41c356d4f43739Daniel Lehmann } 161a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 162825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann private interface Status { 163825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann /** 164825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann * The loader is fetching data 165825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann */ 166825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann public static final int LOADING = 0; 167825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann 168825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann /** 169825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann * Not currently busy. We are waiting for the user to enter data 170825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann */ 171825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann public static final int EDITING = 1; 172825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann 173825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann /** 174f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov * The data is currently being saved. This is used to prevent more 175f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov * auto-saves (they shouldn't overlap) 176825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann */ 177825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann public static final int SAVING = 2; 178825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann 179825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann /** 180a10775d625339d168337e03de05d02f5e0a4f55dDaniel Lehmann * Prevents any more saves. This is used if in the following cases: 181a10775d625339d168337e03de05d02f5e0a4f55dDaniel Lehmann * - After Save/Close 182a10775d625339d168337e03de05d02f5e0a4f55dDaniel Lehmann * - After Revert 183a10775d625339d168337e03de05d02f5e0a4f55dDaniel Lehmann * - After the user has accepted an edit suggestion 184825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann */ 185825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann public static final int CLOSING = 3; 186f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov 187f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov /** 188f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov * Prevents saving while running a child activity. 189f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov */ 190f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov public static final int SUB_ACTIVITY = 4; 191825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann } 192825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann 193a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann private static final int REQUEST_CODE_JOIN = 0; 1946fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private static final int REQUEST_CODE_ACCOUNTS_CHANGED = 1; 195f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1964bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki /** 1974bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * The raw contact for which we started "take photo" or "choose photo from gallery" most 1984bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * recently. Used to restore {@link #mCurrentPhotoHandler} after orientation change. 1994bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki */ 2004bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki private long mRawContactIdRequestingPhoto; 2014bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki /** 2024bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * The {@link PhotoHandler} for the photo editor for the {@link #mRawContactIdRequestingPhoto} 2034bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * raw contact. 2044bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * 2054bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * A {@link PhotoHandler} is created for each photo editor in {@link #bindPhotoHandler}, but 2064bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * the only "active" one should get the activity result. This member represents the active 2074bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki * one. 2084bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki */ 20991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu private PhotoHandler mCurrentPhotoHandler; 210cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 211f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private final EntityDeltaComparator mComparator = new EntityDeltaComparator(); 212f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 213e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov private Cursor mGroupMetaData; 214e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 215ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus private String mCurrentPhotoFile; 21628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus private Bundle mUpdatedPhotos = new Bundle(); 217cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 218cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann private Context mContext; 219f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private String mAction; 220b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann private Uri mLookupUri; 221f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private Bundle mIntentExtras; 222cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann private Listener mListener; 223cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 224f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private long mContactIdForJoin; 225623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann private boolean mContactWritableForJoin; 226cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 2270353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan private ContactEditorUtils mEditorUtils; 2280353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 229f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private LinearLayout mContent; 230851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private RawContactDeltaList mState; 231cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 232f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private ViewIdGenerator mViewIdGenerator; 233cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 2349767e09ae37332d74b5558a3ec16ded20a9328dcDaniel Lehmann private long mLoaderStartTime; 2359767e09ae37332d74b5558a3ec16ded20a9328dcDaniel Lehmann 236825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann private int mStatus; 237825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann 238f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov private AggregationSuggestionEngine mAggregationSuggestionEngine; 2399302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov private long mAggregationSuggestionsRawContactId; 2409302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov private View mAggregationSuggestionView; 241f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 2426c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private ListPopupWindow mAggregationSuggestionPopup; 2436c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2446c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private static final class AggregationSuggestionAdapter extends BaseAdapter { 2456c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private final Activity mActivity; 2466c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private final boolean mSetNewContact; 2476c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private final AggregationSuggestionView.Listener mListener; 2486c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private final List<Suggestion> mSuggestions; 2496c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2506c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa public AggregationSuggestionAdapter(Activity activity, boolean setNewContact, 2516c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa AggregationSuggestionView.Listener listener, List<Suggestion> suggestions) { 2526c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mActivity = activity; 2536c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mSetNewContact = setNewContact; 2546c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mListener = listener; 2556c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mSuggestions = suggestions; 2566c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2576c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2586c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa @Override 2596c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa public View getView(int position, View convertView, ViewGroup parent) { 2606c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa Suggestion suggestion = (Suggestion) getItem(position); 2616c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa LayoutInflater inflater = mActivity.getLayoutInflater(); 2626c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa AggregationSuggestionView suggestionView = 2636c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa (AggregationSuggestionView) inflater.inflate( 2646c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa R.layout.aggregation_suggestions_item, null); 2656c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa suggestionView.setNewContact(mSetNewContact); 2666c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa suggestionView.setListener(mListener); 2676c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa suggestionView.bindSuggestion(suggestion); 2686c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa return suggestionView; 2696c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2706c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2716c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa @Override 2726c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa public long getItemId(int position) { 2736c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa return position; 2746c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2756c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2766c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa @Override 2776c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa public Object getItem(int position) { 2786c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa return mSuggestions.get(position); 2796c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2806c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2816c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa @Override 2826c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa public int getCount() { 2836c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa return mSuggestions.size(); 2846c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2856c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2866c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2876c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa private OnItemClickListener mAggregationSuggestionItemClickListener = 2886c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa new OnItemClickListener() { 2896c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa @Override 2906c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 2916c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa final AggregationSuggestionView suggestionView = (AggregationSuggestionView) view; 2926c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa suggestionView.handleItemClickEvent(); 2936c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.dismiss(); 2946c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup = null; 2956c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa } 2966c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa }; 2976c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa 2987d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov private boolean mAutoAddToDefaultGroup; 2997d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov 30002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov private boolean mEnabled = true; 301eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov private boolean mRequestFocus; 302ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson private boolean mNewLocalProfile = false; 303ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson private boolean mIsUserProfile = false; 30402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov 305cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public ContactEditorFragment() { 306cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 307cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 30802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov public void setEnabled(boolean enabled) { 30902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mEnabled != enabled) { 31002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov mEnabled = enabled; 31102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mContent != null) { 31202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov int count = mContent.getChildCount(); 31302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov for (int i = 0; i < count; i++) { 31402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov mContent.getChildAt(i).setEnabled(enabled); 31502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov } 31602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov } 317a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov setAggregationSuggestionViewEnabled(enabled); 31802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov final Activity activity = getActivity(); 31902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (activity != null) activity.invalidateOptionsMenu(); 32002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov } 32102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov } 32202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov 323cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann @Override 324cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public void onAttach(Activity activity) { 325cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann super.onAttach(activity); 326cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann mContext = activity; 3270353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan mEditorUtils = ContactEditorUtils.getInstance(mContext); 328cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 329cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 330cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann @Override 331f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void onStop() { 332f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov super.onStop(); 333825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // If anything was left unsaved, save it now but keep the editor open. 334f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov if (!getActivity().isChangingConfigurations() && mStatus == Status.EDITING) { 335623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann save(SaveMode.RELOAD); 336825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann } 337f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 338f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 339f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 34036184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee public void onDestroy() { 34136184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee super.onDestroy(); 34236184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee if (mAggregationSuggestionEngine != null) { 34336184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee mAggregationSuggestionEngine.quit(); 34436184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee } 34536184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee } 34636184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee 34736184f630cdb97d0a642de25f69962ef2abfedb1Yorke Lee @Override 348cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { 349cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann final View view = inflater.inflate(R.layout.contact_editor_fragment, container, false); 350cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 351f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent = (LinearLayout) view.findViewById(R.id.editors); 352e8767a1136d2a2f9cb3e3ca5f44b2142baab9709Daniel Lehmann 3533648d2ea76a6649230d1fdd3dba92797ae7cfb26Daniel Lehmann setHasOptionsMenu(true); 354cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 355cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann return view; 356cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 357cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 358222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann @Override 359222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann public void onActivityCreated(Bundle savedInstanceState) { 360222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann super.onActivityCreated(savedInstanceState); 361222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann 362098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng validateAction(mAction); 363098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng 364825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // Handle initial actions only when existing state missing 3654a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann final boolean hasIncomingState = savedInstanceState != null; 366825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann 367098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng if (mState == null) { 368098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // The delta list may not have finished loading before orientation change happens. 369098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // In this case, there will be a saved state but deltas will be missing. Reload from 370098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // database. 371825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann if (Intent.ACTION_EDIT.equals(mAction)) { 372098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // Either... 373098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // 1) orientation change but load never finished. 374098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // or 375098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // 2) not an orientation change. data needs to be loaded for first time. 376825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann getLoaderManager().initLoader(LOADER_DATA, null, mDataLoaderListener); 377098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng } 378098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng } else { 379098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng // Orientation change, we already have mState, it was loaded by onCreate 380098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng bindEditors(); 381098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng } 382098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng 383098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng if (!hasIncomingState) { 384098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng if (Intent.ACTION_INSERT.equals(mAction)) { 3852013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann final Account account = mIntentExtras == null ? null : 3862b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro (Account) mIntentExtras.getParcelable(Intents.Insert.ACCOUNT); 3872b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final String dataSet = mIntentExtras == null ? null : 3882b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro mIntentExtras.getString(Intents.Insert.DATA_SET); 3892013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann 3902013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann if (account != null) { 3912013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann // Account specified in Intent 3922b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro createContact(new AccountWithDataSet(account.name, account.type, dataSet)); 3932013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann } else { 3942013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann // No Account specified. Let the user choose 39540bb481d29bf490fddc65b88c957dd4b5dbc4d82Dmitri Plotnikov // Load Accounts async so that we can present them 3960353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan selectAccountAndCreateContact(); 3972013058703aa110a1d7aac87ef408c96a3919472Daniel Lehmann } 398098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng } 399098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng } 400098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng } 401098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng 402098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng /** 403098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng * Checks if the requested action is valid. 404098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng * 405098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng * @param action The action to test. 406098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng * @throws IllegalArgumentException when the action is invalid. 407098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng */ 408098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng private void validateAction(String action) { 409e8e94423b463688951f806419dbd73e10e7bf7b4Chiao Cheng if (Intent.ACTION_EDIT.equals(action) || Intent.ACTION_INSERT.equals(action) || 410e8e94423b463688951f806419dbd73e10e7bf7b4Chiao Cheng ContactEditorActivity.ACTION_SAVE_COMPLETED.equals(action)) { 411e8e94423b463688951f806419dbd73e10e7bf7b4Chiao Cheng return; 412825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann } 413098f630c3dd0d993a423425e138f95dba0d7612cChiao Cheng throw new IllegalArgumentException("Unknown Action String " + mAction + 414e8e94423b463688951f806419dbd73e10e7bf7b4Chiao Cheng ". Only support " + Intent.ACTION_EDIT + " or " + Intent.ACTION_INSERT + " or " + 415e8e94423b463688951f806419dbd73e10e7bf7b4Chiao Cheng ContactEditorActivity.ACTION_SAVE_COMPLETED); 416222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann } 417222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann 418e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov @Override 419e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov public void onStart() { 420e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupLoaderListener); 421e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov super.onStart(); 422e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov } 423e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 4241015d629f848de9d331a47c819f55854549d661dDmitri Plotnikov public void load(String action, Uri lookupUri, Bundle intentExtras) { 425f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mAction = action; 426b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann mLookupUri = lookupUri; 427f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mIntentExtras = intentExtras; 4287d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov mAutoAddToDefaultGroup = mIntentExtras != null 4297d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov && mIntentExtras.containsKey(INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY); 430ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson mNewLocalProfile = mIntentExtras != null 43136d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro && mIntentExtras.getBoolean(INTENT_EXTRA_NEW_LOCAL_PROFILE); 432f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 433f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 434f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void setListener(Listener value) { 435f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mListener = value; 436cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 437cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 438cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann @Override 439f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void onCreate(Bundle savedState) { 440d364314c460152db7089b304beec81b3675893baDmitri Plotnikov if (savedState != null) { 441d364314c460152db7089b304beec81b3675893baDmitri Plotnikov // Restore mUri before calling super.onCreate so that onInitializeLoaders 442d364314c460152db7089b304beec81b3675893baDmitri Plotnikov // would already have a uri and an action to work with 443b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann mLookupUri = savedState.getParcelable(KEY_URI); 444d364314c460152db7089b304beec81b3675893baDmitri Plotnikov mAction = savedState.getString(KEY_ACTION); 445d364314c460152db7089b304beec81b3675893baDmitri Plotnikov } 446d364314c460152db7089b304beec81b3675893baDmitri Plotnikov 447f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann super.onCreate(savedState); 448f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 449f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (savedState == null) { 450f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // If savedState is non-null, onRestoreInstanceState() will restore the generator. 451f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mViewIdGenerator = new ViewIdGenerator(); 452f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } else { 453825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // Read state from savedState. No loading involved here 454851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mState = savedState.<RawContactDeltaList> getParcelable(KEY_EDIT_STATE); 4554bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki mRawContactIdRequestingPhoto = savedState.getLong( 4564bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki KEY_RAW_CONTACT_ID_REQUESTING_PHOTO); 457f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mViewIdGenerator = savedState.getParcelable(KEY_VIEW_ID_GENERATOR); 458ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus mCurrentPhotoFile = savedState.getString(KEY_CURRENT_PHOTO_FILE); 459f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN); 460623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann mContactWritableForJoin = savedState.getBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN); 4619302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov mAggregationSuggestionsRawContactId = savedState.getLong(KEY_SHOW_JOIN_SUGGESTIONS); 46202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov mEnabled = savedState.getBoolean(KEY_ENABLED); 463ce37f3017c666bcea483a75322e80d5cc1ba6f64Dmitri Plotnikov mStatus = savedState.getInt(KEY_STATUS); 464ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson mNewLocalProfile = savedState.getBoolean(KEY_NEW_LOCAL_PROFILE); 465ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson mIsUserProfile = savedState.getBoolean(KEY_IS_USER_PROFILE); 46628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS); 467cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 468cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 469cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 470851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void setData(Contact data) { 471d3f1e3128b709d7d9a0229f1d1843f015f4977baDaniel Lehmann // If we have already loaded data, we do not want to change it here to not confuse the user 472d3f1e3128b709d7d9a0229f1d1843f015f4977baDaniel Lehmann if (mState != null) { 473d3f1e3128b709d7d9a0229f1d1843f015f4977baDaniel Lehmann Log.v(TAG, "Ignoring background change. This will have to be rebased later"); 474d3f1e3128b709d7d9a0229f1d1843f015f4977baDaniel Lehmann return; 475d3f1e3128b709d7d9a0229f1d1843f015f4977baDaniel Lehmann } 476d3f1e3128b709d7d9a0229f1d1843f015f4977baDaniel Lehmann 477fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov // See if this edit operation needs to be redirected to a custom editor 478851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu ImmutableList<RawContact> rawContacts = data.getRawContacts(); 479851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (rawContacts.size() == 1) { 480851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContact rawContact = rawContacts.get(0); 481851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String type = rawContact.getAccountTypeString(); 482851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String dataSet = rawContact.getDataSet(); 48347b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng AccountType accountType = rawContact.getAccountType(mContext); 4842b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann if (accountType.getEditContactActivityClassName() != null && 4852b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann !accountType.areContactsWritable()) { 486fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov if (mListener != null) { 487851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String name = rawContact.getAccountName(); 488851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu long rawContactId = rawContact.getId(); 4892b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro mListener.onCustomEditContactActivityRequested( 4902b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro new AccountWithDataSet(name, type, dataSet), 491fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), 492fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov mIntentExtras, true); 493fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 494fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov return; 495fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 496fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 497fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 498fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov bindEditorsForExistingContact(data); 499fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 500fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 501fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov @Override 5022b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro public void onExternalEditorRequest(AccountWithDataSet account, Uri uri) { 503fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov mListener.onCustomEditContactActivityRequested(account, uri, null, false); 504fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 505fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 506851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private void bindEditorsForExistingContact(Contact contact) { 50702bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov setEnabled(true); 50802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov 509851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mState = contact.createRawContactDeltaList(); 5101ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov setIntentExtras(mIntentExtras); 5111ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov mIntentExtras = null; 512e579a175bdc18153014da00d989cf0a5343d25a9Dmitri Plotnikov 513ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson // For user profile, change the contacts query URI 514e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus mIsUserProfile = contact.isUserProfile(); 51548ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson boolean localProfileExists = false; 51648ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson 517ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson if (mIsUserProfile) { 518851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu for (RawContactDelta state : mState) { 51948ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson // For profile contacts, we need a different query URI 520ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson state.setProfileQueryUri(); 52148ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson // Try to find a local profile contact 52248ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson if (state.getValues().getAsString(RawContacts.ACCOUNT_TYPE) == null) { 52348ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson localProfileExists = true; 52448ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson } 52548ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson } 52648ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson // Editor should always present a local profile for editing 52748ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson if (!localProfileExists) { 52847b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng final RawContact rawContact = new RawContact(); 529851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu rawContact.setAccountToLocal(); 530851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu 531851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDelta insert = new RawContactDelta(ValuesDelta.fromAfter( 532851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu rawContact.getValues())); 53348ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson insert.setProfileQueryUri(); 53448ed982e078de00f6be49319ccf09bbb2aaadf5eIsaac Katzenelson mState.add(insert); 535ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson } 536ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson } 537eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov mRequestFocus = true; 538eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov 5391ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov bindEditors(); 5401ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov } 5411ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov 5421ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov /** 5431ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov * Merges extras from the intent. 5441ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov */ 5451ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov public void setIntentExtras(Bundle extras) { 5461ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov if (extras == null || extras.size() == 0) { 5471ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov return; 548bb11be3f5867453e7561cdc7bebe6a380eff6881Daniel Lehmann } 549916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov 550a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 551851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu for (RawContactDelta state : mState) { 552851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final AccountType type = state.getAccountType(accountTypes); 55396e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann if (type.areContactsWritable()) { 5541ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov // Apply extras to the first writable raw contact only 555851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.parseExtras(mContext, type, state, extras); 5561ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov break; 5571ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov } 5581ac58b6f2a925c5a4f759346e5244dfd174acd08Dmitri Plotnikov } 559f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 560cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 5610353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan private void selectAccountAndCreateContact() { 5620353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // If this is a local profile, then skip the logic about showing the accounts changed 5630353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // activity and create a phone-local contact. 5640353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (mNewLocalProfile) { 5650353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan createContact(null); 5660353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan return; 5670353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 5680353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 5690353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // If there is no default account or the accounts have changed such that we need to 5700353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // prompt the user again, then launch the account prompt. 5710353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (mEditorUtils.shouldShowAccountChangedNotification()) { 5720353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan Intent intent = new Intent(mContext, ContactEditorAccountsChangedActivity.class); 5730353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan mStatus = Status.SUB_ACTIVITY; 5740353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan startActivityForResult(intent, REQUEST_CODE_ACCOUNTS_CHANGED); 5750353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } else { 5760353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Otherwise, there should be a default account. Then either create a local contact 5770353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // (if default account is null) or create a contact with the specified account. 5780353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan AccountWithDataSet defaultAccount = mEditorUtils.getDefaultAccount(); 5790353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (defaultAccount == null) { 5800353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan createContact(null); 5810353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } else { 5820353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan createContact(defaultAccount); 5830353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 5840353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 5850353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 5860353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 587d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa /** 5880353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan * Create a contact by automatically selecting the first account. If there's no available 5890353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan * account, a device-local contact should be created. 590d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa */ 591d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa private void createContact() { 5922b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final List<AccountWithDataSet> accounts = 593a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov AccountTypeManager.getInstance(mContext).getAccounts(true); 5940353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // No Accounts available. Create a phone-local contact. 5950353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (accounts.isEmpty()) { 59640bb481d29bf490fddc65b88c957dd4b5dbc4d82Dmitri Plotnikov createContact(null); 5970353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan return; 598f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 599cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 600d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa // We have an account switcher in "create-account" screen, so don't need to ask a user to 601d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa // select an account here. 602d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa createContact(accounts.get(0)); 603cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 604cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 605cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann /** 606d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * Shows account creation screen associated with a given account. 607d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * 608d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * @param account may be null to signal a device-local contact should be created. 609cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann */ 6102b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro private void createContact(AccountWithDataSet account) { 611a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 612b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType accountType = 6132b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro accountTypes.getAccountType(account != null ? account.type : null, 6142b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro account != null ? account.dataSet : null); 615fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 616b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov if (accountType.getCreateContactActivityClassName() != null) { 617fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov if (mListener != null) { 618fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov mListener.onCustomCreateContactActivityRequested(account, mIntentExtras); 619fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 620fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } else { 621b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov bindEditorsForNewContact(account, accountType); 622fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 623fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } 624fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 625d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa /** 626d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * Removes a current editor ({@link #mState}) and rebinds new editor for a new account. 627d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * Some of old data are reused with new restriction enforced by the new account. 628d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * 6292b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro * @param oldState Old data being edited. 630d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * @param oldAccount Old account associated with oldState. 631d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa * @param newAccount New account to be used. 632d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa */ 633d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa private void rebindEditorsForNewContact( 634851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDelta oldState, AccountWithDataSet oldAccount, 635851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu AccountWithDataSet newAccount) { 636d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 6372b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro AccountType oldAccountType = accountTypes.getAccountType( 6382b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro oldAccount.type, oldAccount.dataSet); 6392b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro AccountType newAccountType = accountTypes.getAccountType( 6402b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro newAccount.type, newAccount.dataSet); 641d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 642d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (newAccountType.getCreateContactActivityClassName() != null) { 643d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa Log.w(TAG, "external activity called in rebind situation"); 644d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (mListener != null) { 645d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa mListener.onCustomCreateContactActivityRequested(newAccount, mIntentExtras); 646d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 647d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } else { 648d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa mState = null; 649d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa bindEditorsForNewContact(newAccount, newAccountType, oldState, oldAccountType); 650d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 651d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 652d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 6532b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro private void bindEditorsForNewContact(AccountWithDataSet account, 6542b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final AccountType accountType) { 655d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa bindEditorsForNewContact(account, accountType, null, null); 656d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 657d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 6582b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro private void bindEditorsForNewContact(AccountWithDataSet newAccount, 659851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final AccountType newAccountType, RawContactDelta oldState, 660851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu AccountType oldAccountType) { 661a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov mStatus = Status.EDITING; 662a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov 66347b6f70eadb118d815b4aaf5426c070bd75a38fbChiao Cheng final RawContact rawContact = new RawContact(); 664d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (newAccount != null) { 665851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu rawContact.setAccount(newAccount); 666f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } else { 667851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu rawContact.setAccountToLocal(); 668cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 669cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 670851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDelta insert = new RawContactDelta(ValuesDelta.fromAfter(rawContact.getValues())); 671d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (oldState == null) { 672d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa // Parse any values from incoming intent 673851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.parseExtras(mContext, newAccountType, insert, mIntentExtras); 674d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } else { 675851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.migrateStateForNewContact(mContext, oldState, insert, 676d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa oldAccountType, newAccountType); 677d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 678f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 67969f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov // Ensure we have some default fields (if the account type does not support a field, 680362acdb3da27524d42c4bb44423d6276c5738616Daniel Lehmann // ensureKind will not add it, so it is safe to add e.g. Event) 681851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.ensureKindExists(insert, newAccountType, Phone.CONTENT_ITEM_TYPE); 682851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.ensureKindExists(insert, newAccountType, Email.CONTENT_ITEM_TYPE); 683851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.ensureKindExists(insert, newAccountType, Organization.CONTENT_ITEM_TYPE); 684851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.ensureKindExists(insert, newAccountType, Event.CONTENT_ITEM_TYPE); 685851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.ensureKindExists(insert, newAccountType, 686851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu StructuredPostal.CONTENT_ITEM_TYPE); 687f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 688ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson // Set the correct URI for saving the contact as a profile 689ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson if (mNewLocalProfile) { 690ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson insert.setProfileQueryUri(); 691ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson } 692ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson 693f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (mState == null) { 694f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Create state if none exists yet 695851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mState = RawContactDeltaList.fromSingle(insert); 696f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } else { 697f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Add contact onto end of existing state 698f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mState.add(insert); 699cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 700f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 701eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov mRequestFocus = true; 702eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov 703f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann bindEditors(); 704cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 705cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 706f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private void bindEditors() { 7075671c7e7718c3285dc0391807401083986fcfd51Maurice Chu // bindEditors() can only bind views if there is data in mState, so immediately return 7085671c7e7718c3285dc0391807401083986fcfd51Maurice Chu // if mState is null 7095671c7e7718c3285dc0391807401083986fcfd51Maurice Chu if (mState == null) { 7105671c7e7718c3285dc0391807401083986fcfd51Maurice Chu return; 7115671c7e7718c3285dc0391807401083986fcfd51Maurice Chu } 7125671c7e7718c3285dc0391807401083986fcfd51Maurice Chu 713f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Sort the editors 714f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann Collections.sort(mState, mComparator); 715cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 716f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Remove any existing editors and rebuild any visible 717f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent.removeAllViews(); 718cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 719f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( 720f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann Context.LAYOUT_INFLATER_SERVICE); 721a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 722a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan int numRawContacts = mState.size(); 723a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan for (int i = 0; i < numRawContacts; i++) { 724f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // TODO ensure proper ordering of entities in the list 725851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta rawContactDelta = mState.get(i); 726851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (!rawContactDelta.isVisible()) continue; 727f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 728851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final AccountType type = rawContactDelta.getAccountType(accountTypes); 729851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final long rawContactId = rawContactDelta.getRawContactId(); 730f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 73172af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann final BaseRawContactEditorView editor; 7322b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann if (!type.areContactsWritable()) { 733fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov editor = (BaseRawContactEditorView) inflater.inflate( 7342b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann R.layout.raw_contact_readonly_editor_view, mContent, false); 7352b3ee0f34801444c7d775ce747125459f69712bbDaniel Lehmann ((RawContactReadOnlyEditorView) editor).setListener(this); 736fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov } else { 737fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view, 738fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan mContent, false); 739cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 740a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan if (Intent.ACTION_INSERT.equals(mAction) && numRawContacts == 1) { 7412b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final List<AccountWithDataSet> accounts = 742d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa AccountTypeManager.getInstance(mContext).getAccounts(true); 743ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson if (accounts.size() > 1 && !mNewLocalProfile) { 744d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa addAccountSwitcher(mState.get(0), editor); 745a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan } else { 746a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan disableAccountSwitcher(editor); 747d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 748a3e69af03dd35124941a48c3bfaea87468d66863Katherine Kuan } else { 749a3e69af03dd35124941a48c3bfaea87468d66863Katherine Kuan disableAccountSwitcher(editor); 750d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 751a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan 75202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov editor.setEnabled(mEnabled); 753cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 754f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent.addView(editor); 7557d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov 756851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile()); 757f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 7586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Set up the photo handler. 7596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro bindPhotoHandler(editor, type, mState); 7606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 76128eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus // If a new photo was chosen but not yet saved, we need to 76228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus // update the thumbnail to reflect this. 76328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus Bitmap bitmap = updatedBitmapForRawContact(rawContactId); 76428eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus if (bitmap != null) editor.setPhotoBitmap(bitmap); 76528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 76672af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann if (editor instanceof RawContactEditorView) { 7672828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki final Activity activity = getActivity(); 76872af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann final RawContactEditorView rawContactEditor = (RawContactEditorView) editor; 7695ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov EditorListener listener = new EditorListener() { 770f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 771f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 772f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void onRequest(int request) { 7732828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki if (activity.isFinishing()) { // Make sure activity is still running. 7742828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki return; 7752828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki } 7762bbfae8f92d5c218c83a49621a4c8f98f4d7a394Isaac Katzenelson if (request == EditorListener.FIELD_CHANGED && !isEditingUserProfile()) { 7772828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki acquireAggregationSuggestions(activity, rawContactEditor); 77811bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov } 779f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 780f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 781f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 7822293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan public void onDeleteRequested(Editor removedEditor) { 783f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 7845ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov }; 7855ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 7865ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov final TextFieldsEditorView nameEditor = rawContactEditor.getNameEditor(); 7875ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov if (mRequestFocus) { 7885ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov nameEditor.requestFocus(); 7895ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov mRequestFocus = false; 7905ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 7915ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov nameEditor.setEditorListener(listener); 792f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 7935ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov final TextFieldsEditorView phoneticNameEditor = 7945ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov rawContactEditor.getPhoneticNameEditor(); 7955ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov phoneticNameEditor.setEditorListener(listener); 7967d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup); 7977d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov 7989302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov if (rawContactId == mAggregationSuggestionsRawContactId) { 7992828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki acquireAggregationSuggestions(activity, rawContactEditor); 800f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 801f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 802cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 803f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 804eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov mRequestFocus = false; 805eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov 806e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov bindGroupMetaData(); 807e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 808f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Show editor now that we've loaded state 809f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContent.setVisibility(View.VISIBLE); 810a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 811a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann // Refresh Action Bar as the visibility of the join command 812825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // Activity can be null if we have been detached from the Activity 813825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann final Activity activity = getActivity(); 814825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann if (activity != null) activity.invalidateOptionsMenu(); 8156fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 816eeb68a341734ded343004d4eecb585420e70605bDmitri Plotnikov 81728eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus /** 81828eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus * If we've stashed a temporary file containing a contact's new photo, 81928eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus * decode it and return the bitmap. 82028eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus * @param rawContactId identifies the raw-contact whose Bitmap we'll try to return. 82128eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus * @return Bitmap of photo for specified raw-contact, or null 82228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus */ 82328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus private Bitmap updatedBitmapForRawContact(long rawContactId) { 82428eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus String path = mUpdatedPhotos.getString(String.valueOf(rawContactId)); 82528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus return BitmapFactory.decodeFile(path); 82628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus } 82728eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 8286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type, 829851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDeltaList state) { 8306fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final int mode; 8316fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (type.areContactsWritable()) { 8326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (editor.hasSetPhoto()) { 8336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (hasMoreThanOnePhoto()) { 834ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mode = PhotoActionPopup.Modes.PHOTO_ALLOW_PRIMARY; 8356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 836ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mode = PhotoActionPopup.Modes.PHOTO_DISALLOW_PRIMARY; 8376fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 8386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 839ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mode = PhotoActionPopup.Modes.NO_PHOTO; 8406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 8416fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 8426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) { 843ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus mode = PhotoActionPopup.Modes.READ_ONLY_ALLOW_PRIMARY; 8446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } else { 8456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Read-only and either no photo or the only photo ==> no options 846740552201d103b80bc49ea8a39a30536222672eaDaniel Lehmann editor.getPhotoEditor().setEditorListener(null); 8476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return; 8486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 8496fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 85091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state); 8516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro editor.getPhotoEditor().setEditorListener( 85291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu (PhotoHandler.PhotoEditorListener) photoHandler.getListener()); 8534bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki 8544bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki // Note a newly created raw contact gets some random negative ID, so any value is valid 8554bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki // here. (i.e. don't check against -1 or anything.) 8564bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki if (mRawContactIdRequestingPhoto == editor.getRawContactId()) { 8574bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki mCurrentPhotoHandler = photoHandler; 8584bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki } 859cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 860cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 861e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov private void bindGroupMetaData() { 862e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov if (mGroupMetaData == null) { 863e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov return; 864e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov } 865e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 866e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov int editorCount = mContent.getChildCount(); 867e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov for (int i = 0; i < editorCount; i++) { 86872af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann BaseRawContactEditorView editor = (BaseRawContactEditorView) mContent.getChildAt(i); 869e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov editor.setGroupMetaData(mGroupMetaData); 870e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov } 871e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov } 872e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 8730353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan private void saveDefaultAccountIfNecessary() { 8740353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Verify that this is a newly created contact, that the contact is composed of only 8750353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // 1 raw contact, and that the contact is not a user profile. 8760353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (!Intent.ACTION_INSERT.equals(mAction) && mState.size() == 1 && 8770353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan !isEditingUserProfile()) { 8780353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan return; 8790353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 8800353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 8810353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Find the associated account for this contact (retrieve it here because there are 8820353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // multiple paths to creating a contact and this ensures we always have the correct 8830353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // account). 884851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta rawContactDelta = mState.get(0); 885851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String name = rawContactDelta.getAccountName(); 886851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String type = rawContactDelta.getAccountType(); 887851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String dataSet = rawContactDelta.getDataSet(); 8880353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 8890353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan AccountWithDataSet account = (name == null || type == null) ? null : 8900353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan new AccountWithDataSet(name, type, dataSet); 8910353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan mEditorUtils.saveDefaultAndAllAccounts(account); 8920353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 8930353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 894d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa private void addAccountSwitcher( 895851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta currentState, BaseRawContactEditorView editor) { 8962b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final AccountWithDataSet currentAccount = new AccountWithDataSet( 897851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu currentState.getAccountName(), 898851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu currentState.getAccountType(), 899851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu currentState.getDataSet()); 900d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa final View accountView = editor.findViewById(R.id.account); 901fd70903236883f47b21f23b8cb49a1ccacdfcdf1Katherine Kuan final View anchorView = editor.findViewById(R.id.account_container); 902d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa accountView.setOnClickListener(new View.OnClickListener() { 903d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa @Override 904d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa public void onClick(View v) { 905d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa final ListPopupWindow popup = new ListPopupWindow(mContext, null); 906a6c8f2daa80f1816dd25237457d7f6287c6b1b7cDaisuke Miyakawa final AccountsListAdapter adapter = 9076f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki new AccountsListAdapter(mContext, 9086f74c0f3313cbb08ee8a8fbb79bfefc5b03fe215Makoto Onuki AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, currentAccount); 909d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setWidth(anchorView.getWidth()); 910d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setAnchorView(anchorView); 911d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setAdapter(adapter); 912d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setModal(true); 913d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 914d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.setOnItemClickListener(new AdapterView.OnItemClickListener() { 915d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa @Override 916d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa public void onItemClick(AdapterView<?> parent, View view, int position, 917d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa long id) { 918d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.dismiss(); 9192b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro AccountWithDataSet newAccount = adapter.getItem(position); 920d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa if (!newAccount.equals(currentAccount)) { 921d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa rebindEditorsForNewContact(currentState, currentAccount, newAccount); 922d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 923d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 924d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa }); 925d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa popup.show(); 926d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 927d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa }); 928d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa } 929d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa 930a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan private void disableAccountSwitcher(BaseRawContactEditorView editor) { 931a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan // Remove the pressed state from the account header because the user cannot switch accounts 932a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan // on an existing contact 933a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan final View accountView = editor.findViewById(R.id.account); 934740552201d103b80bc49ea8a39a30536222672eaDaniel Lehmann accountView.setBackground(null); 935a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan accountView.setEnabled(false); 936a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan } 937a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan 938b85b83ee4adc8b72fe68499f669ca530d58e6815Daniel Lehmann @Override 939eb4d1bf9868dfddd958d8f028e36a4d2da7a8731Dianne Hackborn public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) { 940c6b8afe730255537978f2c938cca6986cae63c34Katherine Kuan inflater.inflate(R.menu.edit_contact, menu); 941cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 942cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 943b85b83ee4adc8b72fe68499f669ca530d58e6815Daniel Lehmann @Override 944eb4d1bf9868dfddd958d8f028e36a4d2da7a8731Dianne Hackborn public void onPrepareOptionsMenu(Menu menu) { 9459b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan // This supports the keyboard shortcut to save changes to a contact but shouldn't be visible 9469b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan // because the custom action bar contains the "save" button now (not the overflow menu). 9479b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan // TODO: Find a better way to handle shortcuts, i.e. onKeyDown()? 948692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu final MenuItem doneMenu = menu.findItem(R.id.menu_done); 949692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu final MenuItem splitMenu = menu.findItem(R.id.menu_split); 950692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu final MenuItem joinMenu = menu.findItem(R.id.menu_join); 951692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu final MenuItem helpMenu = menu.findItem(R.id.menu_help); 952692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu 953692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu // Set visibility of menus 954692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu doneMenu.setVisible(false); 9559b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan 95603587ecd46c0a524f3cdc5ffd2959be2bc30bb34Isaac Katzenelson // Split only if more than one raw profile and not a user profile 957692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu splitMenu.setVisible(mState != null && mState.size() > 1 && !isEditingUserProfile()); 95803587ecd46c0a524f3cdc5ffd2959be2bc30bb34Isaac Katzenelson 959692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu // Cannot join a user profile 960692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu joinMenu.setVisible(!isEditingUserProfile()); 961692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu 962692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu // help menu depending on whether this is inserting or editing 963692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu if (Intent.ACTION_INSERT.equals(mAction)) { 964692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu // inserting 965ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus HelpUtils.prepareHelpMenuItem(mContext, helpMenu, R.string.help_url_people_add); 966692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu } else if (Intent.ACTION_EDIT.equals(mAction)) { 967692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu // editing 968ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus HelpUtils.prepareHelpMenuItem(mContext, helpMenu, R.string.help_url_people_edit); 969692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu } else { 970692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu // something else, so don't show the help menu 971692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu helpMenu.setVisible(false); 972692d46364f2f0e32fd481b977c9e16832e70de5cMaurice Chu } 97303587ecd46c0a524f3cdc5ffd2959be2bc30bb34Isaac Katzenelson 97402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov int size = menu.size(); 97502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov for (int i = 0; i < size; i++) { 97602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov menu.getItem(i).setEnabled(mEnabled); 97702bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov } 978cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 979cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 980b85b83ee4adc8b72fe68499f669ca530d58e6815Daniel Lehmann @Override 981cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public boolean onOptionsItemSelected(MenuItem item) { 982cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann switch (item.getItemId()) { 983f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann case R.id.menu_done: 9849df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov return save(SaveMode.CLOSE); 985f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann case R.id.menu_discard: 986d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov return revert(); 987f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann case R.id.menu_split: 988f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return doSplitContactAction(); 989f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann case R.id.menu_join: 990f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return doJoinContactAction(); 991f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 992f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return false; 993f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 994cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 995f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private boolean doSplitContactAction() { 996f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (!hasValidState()) return false; 997f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 998a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann final SplitContactConfirmationDialogFragment dialog = 9994a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann new SplitContactConfirmationDialogFragment(); 10004a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann dialog.setTargetFragment(this, 0); 10014a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann dialog.show(getFragmentManager(), SplitContactConfirmationDialogFragment.TAG); 1002f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return true; 1003f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1004f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1005f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private boolean doJoinContactAction() { 10064c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov if (!hasValidState()) { 10074c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov return false; 10084c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov } 10094c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov 10104c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov // If we just started creating a new contact and haven't added any data, it's too 10114c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov // early to do a join 1012764637aba745612a9fdc07adb99c615263916fa8Josh Gargus if (mState.size() == 1 && mState.get(0).isContactInsert() && !hasPendingChanges()) { 1013ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus Toast.makeText(mContext, R.string.toast_join_with_empty_contact, 1014a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov Toast.LENGTH_LONG).show(); 1015a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov return true; 10164c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov } 10174c699fc698763b3e271efb7654fb5e38ffb6f556Dmitri Plotnikov 10189df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov return save(SaveMode.JOIN); 1019f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1020f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1021f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1022f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * Check if our internal {@link #mState} is valid, usually checked before 1023f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * performing user actions. 1024f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 1025f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private boolean hasValidState() { 1026f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return mState != null && mState.size() > 0; 1027f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1028f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1029f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1030764637aba745612a9fdc07adb99c615263916fa8Josh Gargus * Return true if there are any edits to the current contact which need to 1031764637aba745612a9fdc07adb99c615263916fa8Josh Gargus * be saved. 1032764637aba745612a9fdc07adb99c615263916fa8Josh Gargus */ 1033764637aba745612a9fdc07adb99c615263916fa8Josh Gargus private boolean hasPendingChanges() { 1034764637aba745612a9fdc07adb99c615263916fa8Josh Gargus final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 1035851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu return RawContactModifier.hasChanges(mState, accountTypes); 1036764637aba745612a9fdc07adb99c615263916fa8Josh Gargus } 1037764637aba745612a9fdc07adb99c615263916fa8Josh Gargus 1038764637aba745612a9fdc07adb99c615263916fa8Josh Gargus /** 1039f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * Saves or creates the contact based on the mode, and if successful 1040f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * finishes the activity. 1041f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 10429df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov public boolean save(int saveMode) { 1043a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov if (!hasValidState() || mStatus != Status.EDITING) { 1044f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return false; 1045f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1046f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 10478c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov // If we are about to close the editor - there is no need to refresh the data 1048a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov if (saveMode == SaveMode.CLOSE || saveMode == SaveMode.SPLIT) { 10499d2bcfb40d0ee107886eb99eba13a840e944ba43Dianne Hackborn getLoaderManager().destroyLoader(LOADER_DATA); 10508c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov } 10518c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov 1052825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann mStatus = Status.SAVING; 10536cb8fe23106bc05139798318f19b29c569140628Dmitri Plotnikov 1054764637aba745612a9fdc07adb99c615263916fa8Josh Gargus if (!hasPendingChanges()) { 1055ba69014263332f2056263cddc41cc6d7cfd7b7caDaniel Lehmann if (mLookupUri == null && saveMode == SaveMode.RELOAD) { 1056ba69014263332f2056263cddc41cc6d7cfd7b7caDaniel Lehmann // We don't have anything to save and there isn't even an existing contact yet. 1057ba69014263332f2056263cddc41cc6d7cfd7b7caDaniel Lehmann // Nothing to do, simply go back to editing mode 1058ba69014263332f2056263cddc41cc6d7cfd7b7caDaniel Lehmann mStatus = Status.EDITING; 1059ba69014263332f2056263cddc41cc6d7cfd7b7caDaniel Lehmann return true; 1060ba69014263332f2056263cddc41cc6d7cfd7b7caDaniel Lehmann } 106136d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro onSaveCompleted(false, saveMode, mLookupUri != null, mLookupUri); 10626cb8fe23106bc05139798318f19b29c569140628Dmitri Plotnikov return true; 10636cb8fe23106bc05139798318f19b29c569140628Dmitri Plotnikov } 10646cb8fe23106bc05139798318f19b29c569140628Dmitri Plotnikov 1065a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov setEnabled(false); 1066f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 10670353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Store account as default account, only if this is a new contact 10680353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan saveDefaultAccountIfNecessary(); 10690353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan 10700353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Save contact 1071ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState, 1072ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(), 1073ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus ((Activity)mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED, 1074ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus mUpdatedPhotos); 1075ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus mContext.startService(intent); 107687270e1b58e669354bb1571ced686421c56deb7aJosh Gargus 107787270e1b58e669354bb1571ced686421c56deb7aJosh Gargus // Don't try to save the same photos twice. 107887270e1b58e669354bb1571ced686421c56deb7aJosh Gargus mUpdatedPhotos = new Bundle(); 107987270e1b58e669354bb1571ced686421c56deb7aJosh Gargus 1080f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return true; 1081f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1082f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1083d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov public static class CancelEditDialogFragment extends DialogFragment { 1084d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov 1085d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov public static void show(ContactEditorFragment fragment) { 1086d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov CancelEditDialogFragment dialog = new CancelEditDialogFragment(); 1087d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov dialog.setTargetFragment(fragment, 0); 1088d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov dialog.show(fragment.getFragmentManager(), "cancelEditor"); 1089d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1090d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov 1091d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov @Override 1092d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov public Dialog onCreateDialog(Bundle savedInstanceState) { 1093d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov AlertDialog dialog = new AlertDialog.Builder(getActivity()) 10944292dfa46123a6c0e1de9862b4d8694bfb87875aDmitri Plotnikov .setIconAttribute(android.R.attr.alertDialogIcon) 1095d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov .setMessage(R.string.cancel_confirmation_dialog_message) 10961ba8b6fea4c3f82ded19305874e72a326612aed1Katherine Kuan .setPositiveButton(android.R.string.ok, 1097d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov new DialogInterface.OnClickListener() { 1098d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov @Override 1099f30723782e801deaf159aea2443e9507596ef11dDaniel Lehmann public void onClick(DialogInterface dialogInterface, int whichButton) { 1100d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov ((ContactEditorFragment)getTargetFragment()).doRevertAction(); 1101d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1102d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1103d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov ) 1104d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov .setNegativeButton(android.R.string.cancel, null) 1105d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov .create(); 1106d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov return dialog; 1107d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1108d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1109d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov 1110d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov private boolean revert() { 1111764637aba745612a9fdc07adb99c615263916fa8Josh Gargus if (mState == null || !hasPendingChanges()) { 1112d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov doRevertAction(); 1113d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } else { 1114d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov CancelEditDialogFragment.show(this); 1115d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1116d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov return true; 1117d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov } 1118d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov 1119d3eedfc5f518a081d76d6b9e31a39c5adf988bc0Dmitri Plotnikov private void doRevertAction() { 1120825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // When this Fragment is closed we don't want it to auto-save 1121825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann mStatus = Status.CLOSING; 112222fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann if (mListener != null) mListener.onReverted(); 1123f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1124f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 11259b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan public void doSaveAction() { 11269b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan save(SaveMode.CLOSE); 11279b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan } 11289b3dfd0bc36568558bfdc32a5d4c30f2d0df5fedKatherine Kuan 11292b46f0301c51973d6e3b02b78b398af097244af9Dmitri Plotnikov public void onJoinCompleted(Uri uri) { 113036d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro onSaveCompleted(false, SaveMode.RELOAD, uri != null, uri); 11312b46f0301c51973d6e3b02b78b398af097244af9Dmitri Plotnikov } 11322b46f0301c51973d6e3b02b78b398af097244af9Dmitri Plotnikov 113336d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro public void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded, 113436d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro Uri contactLookupUri) { 1135a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov if (hadChanges) { 113636d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro if (saveSucceeded) { 1137a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov if (saveMode != SaveMode.JOIN) { 1138a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov Toast.makeText(mContext, R.string.contactSavedToast, Toast.LENGTH_SHORT).show(); 1139a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov } 1140a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov } else { 1141a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov Toast.makeText(mContext, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show(); 1142a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov } 1143a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov } 1144f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann switch (saveMode) { 114515972398b530b91612418dc11d41c356d4f43739Daniel Lehmann case SaveMode.CLOSE: 11469df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov case SaveMode.HOME: 1147f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final Intent resultIntent; 114836d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro if (saveSucceeded && contactLookupUri != null) { 1149b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann final String requestAuthority = 1150b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann mLookupUri == null ? null : mLookupUri.getAuthority(); 1151f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1152f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final String legacyAuthority = "contacts"; 1153f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1154f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann resultIntent = new Intent(); 11555649a12fe551855f00c8dbeacfc96511c2a5fb71Katherine Kuan resultIntent.setAction(Intent.ACTION_VIEW); 1156f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (legacyAuthority.equals(requestAuthority)) { 1157f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Build legacy Uri when requested by caller 1158f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final long contactId = ContentUris.parseId(Contacts.lookupContact( 1159f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContext.getContentResolver(), contactLookupUri)); 1160f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final Uri legacyContentUri = Uri.parse("content://contacts/people"); 1161f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final Uri legacyUri = ContentUris.withAppendedId( 1162f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann legacyContentUri, contactId); 1163f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann resultIntent.setData(legacyUri); 1164f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } else { 1165f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Otherwise pass back a lookup-style Uri 1166f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann resultIntent.setData(contactLookupUri); 1167f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1168f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1169f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } else { 1170f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann resultIntent = null; 1171f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1172825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann // It is already saved, so prevent that it is saved again 1173825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann mStatus = Status.CLOSING; 11745649a12fe551855f00c8dbeacfc96511c2a5fb71Katherine Kuan if (mListener != null) mListener.onSaveFinished(resultIntent); 1175f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann break; 1176a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov 117715972398b530b91612418dc11d41c356d4f43739Daniel Lehmann case SaveMode.RELOAD: 1178dd0dee6c55ea83d541b28e90cd4ad87ffd026f68Dmitri Plotnikov case SaveMode.JOIN: 117936d24d7ede42a252c82c4aa783b2231c5e2eea79Dave Santoro if (saveSucceeded && contactLookupUri != null) { 1180623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann // If it was a JOIN, we are now ready to bring up the join activity. 1181e813f5e56ddc6395c5e08e9245e2c5ad41e91724Daniel Lehmann if (saveMode == SaveMode.JOIN && hasValidState()) { 1182623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann showJoinAggregateActivity(contactLookupUri); 1183623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann } 1184623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann 118515972398b530b91612418dc11d41c356d4f43739Daniel Lehmann // If this was in INSERT, we are changing into an EDIT now. 118615972398b530b91612418dc11d41c356d4f43739Daniel Lehmann // If it already was an EDIT, we are changing to the new Uri now 118715972398b530b91612418dc11d41c356d4f43739Daniel Lehmann mState = null; 11881015d629f848de9d331a47c819f55854549d661dDmitri Plotnikov load(Intent.ACTION_EDIT, contactLookupUri, null); 1189825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann mStatus = Status.LOADING; 119015972398b530b91612418dc11d41c356d4f43739Daniel Lehmann getLoaderManager().restartLoader(LOADER_DATA, null, mDataLoaderListener); 119115972398b530b91612418dc11d41c356d4f43739Daniel Lehmann } 119215972398b530b91612418dc11d41c356d4f43739Daniel Lehmann break; 1193a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov 119415972398b530b91612418dc11d41c356d4f43739Daniel Lehmann case SaveMode.SPLIT: 1195a011414b12955a91c8f3efe528f374654d930098Dmitri Plotnikov mStatus = Status.CLOSING; 1196a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann if (mListener != null) { 11978c91dfb9ef1c7ac1a4b2feed0b9a8585d4873542Dmitri Plotnikov mListener.onContactSplit(contactLookupUri); 1198a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann } else { 1199a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann Log.d(TAG, "No listener registered, can not call onSplitFinished"); 1200a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann } 1201f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann break; 1202f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1203f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1204f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1205f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1206f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * Shows a list of aggregates that can be joined into the currently viewed aggregate. 1207f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * 1208f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * @param contactLookupUri the fresh URI for the currently edited contact (after saving it) 1209f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 1210f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private void showJoinAggregateActivity(Uri contactLookupUri) { 121173a45b4ad96b21f468dbacde0da213d190979835Dmitri Plotnikov if (contactLookupUri == null || !isAdded()) { 1212f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return; 1213f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1214f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1215f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann mContactIdForJoin = ContentUris.parseId(contactLookupUri); 1216623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann mContactWritableForJoin = isContactWritable(); 1217f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final Intent intent = new Intent(JoinContactActivity.JOIN_CONTACT); 1218f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann intent.putExtra(JoinContactActivity.EXTRA_TARGET_CONTACT_ID, mContactIdForJoin); 1219a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann startActivityForResult(intent, REQUEST_CODE_JOIN); 1220f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1221f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1222f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1223f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * Performs aggregation with the contact selected by the user from suggestions or A-Z list. 1224f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 1225f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann private void joinAggregate(final long contactId) { 12262b46f0301c51973d6e3b02b78b398af097244af9Dmitri Plotnikov Intent intent = ContactSaveService.createJoinContactsIntent(mContext, mContactIdForJoin, 1227623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann contactId, mContactWritableForJoin, 12282b46f0301c51973d6e3b02b78b398af097244af9Dmitri Plotnikov ContactEditorActivity.class, ContactEditorActivity.ACTION_JOIN_COMPLETED); 12292b46f0301c51973d6e3b02b78b398af097244af9Dmitri Plotnikov mContext.startService(intent); 1230f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1231f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1232f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1233ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov * Returns true if there is at least one writable raw contact in the current contact. 1234ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov */ 1235ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov private boolean isContactWritable() { 1236a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 1237ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov int size = mState.size(); 1238ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov for (int i = 0; i < size; i++) { 1239851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDelta entity = mState.get(i); 1240851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final AccountType type = entity.getAccountType(accountTypes); 124196e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann if (type.areContactsWritable()) { 1242ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov return true; 1243ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov } 1244ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov } 1245ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov return false; 1246ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov } 1247ec502e886a94d23f03282ed2ee0cd8400678e8d7Dmitri Plotnikov 12482bbfae8f92d5c218c83a49621a4c8f98f4d7a394Isaac Katzenelson private boolean isEditingUserProfile() { 12492bbfae8f92d5c218c83a49621a4c8f98f4d7a394Isaac Katzenelson return mNewLocalProfile || mIsUserProfile; 12502bbfae8f92d5c218c83a49621a4c8f98f4d7a394Isaac Katzenelson } 12512bbfae8f92d5c218c83a49621a4c8f98f4d7a394Isaac Katzenelson 1252cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public static interface Listener { 1253cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann /** 125422fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann * Contact was not found, so somehow close this fragment. This is raised after a contact 125522fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann * is removed via Menu/Delete (unless it was a new contact) 1256cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann */ 125722fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann void onContactNotFound(); 1258f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1259f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 12608c91dfb9ef1c7ac1a4b2feed0b9a8585d4873542Dmitri Plotnikov * Contact was split, so we can close now. 1261a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann * @param newLookupUri The lookup uri of the new contact that should be shown to the user. 1262a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann * The editor tries best to chose the most natural contact here. 1263f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 12648c91dfb9ef1c7ac1a4b2feed0b9a8585d4873542Dmitri Plotnikov void onContactSplit(Uri newLookupUri); 1265f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1266f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1267f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * User has tapped Revert, close the fragment now. 1268f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 126922fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann void onReverted(); 1270f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1271f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 127222fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann * Contact was saved and the Fragment can now be closed safely. 1273f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 12745649a12fe551855f00c8dbeacfc96511c2a5fb71Katherine Kuan void onSaveFinished(Intent resultIntent); 1275b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann 1276b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann /** 1277e47dd262a9880121fc2b75fe82b002bc101fc682Dmitri Plotnikov * User switched to editing a different contact (a suggestion from the 1278e47dd262a9880121fc2b75fe82b002bc101fc682Dmitri Plotnikov * aggregation engine). 1279e47dd262a9880121fc2b75fe82b002bc101fc682Dmitri Plotnikov */ 1280e47dd262a9880121fc2b75fe82b002bc101fc682Dmitri Plotnikov void onEditOtherContactRequested( 1281e47dd262a9880121fc2b75fe82b002bc101fc682Dmitri Plotnikov Uri contactLookupUri, ArrayList<ContentValues> contentValues); 1282fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 1283fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov /** 1284fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * Contact is being created for an external account that provides its own 1285fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * new contact activity. 1286fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov */ 12872b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro void onCustomCreateContactActivityRequested(AccountWithDataSet account, 12882b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro Bundle intentExtras); 1289fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov 1290fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov /** 1291fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * The edited raw contact belongs to an external account that provides 1292fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * its own edit activity. 1293fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * 1294fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * @param redirect indicates that the current editor should be closed 1295fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov * before the custom editor is shown. 1296fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov */ 12972b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro void onCustomEditContactActivityRequested(AccountWithDataSet account, Uri rawContactUri, 1298fff6f07a02d3e3bbeff2ecf94a703782b71aea66Dmitri Plotnikov Bundle intentExtras, boolean redirect); 1299f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1300f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1301851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private class EntityDeltaComparator implements Comparator<RawContactDelta> { 1302f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1303f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann * Compare EntityDeltas for sorting the stack of editors. 1304f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann */ 13054a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann @Override 1306851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public int compare(RawContactDelta one, RawContactDelta two) { 1307f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Check direct equality 1308f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (one.equals(two)) { 1309f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return 0; 1310f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1311f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1312a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext); 13132b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro String accountType1 = one.getValues().getAsString(RawContacts.ACCOUNT_TYPE); 13142b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro String dataSet1 = one.getValues().getAsString(RawContacts.DATA_SET); 13152b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final AccountType type1 = accountTypes.getAccountType(accountType1, dataSet1); 13162b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro String accountType2 = two.getValues().getAsString(RawContacts.ACCOUNT_TYPE); 13172b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro String dataSet2 = two.getValues().getAsString(RawContacts.DATA_SET); 13182b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro final AccountType type2 = accountTypes.getAccountType(accountType2, dataSet2); 1319f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1320f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Check read-only 132196e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann if (!type1.areContactsWritable() && type2.areContactsWritable()) { 1322f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return 1; 132396e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann } else if (type1.areContactsWritable() && !type2.areContactsWritable()) { 1324f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return -1; 1325f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1326f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1327f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Check account type 1328f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann boolean skipAccountTypeCheck = false; 1329b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov boolean isGoogleAccount1 = type1 instanceof GoogleAccountType; 1330b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov boolean isGoogleAccount2 = type2 instanceof GoogleAccountType; 133169f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov if (isGoogleAccount1 && !isGoogleAccount2) { 1332f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return -1; 133369f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov } else if (!isGoogleAccount1 && isGoogleAccount2) { 1334f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return 1; 133569f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov } else if (isGoogleAccount1 && isGoogleAccount2){ 1336f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann skipAccountTypeCheck = true; 1337f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1338f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1339f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann int value; 1340f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (!skipAccountTypeCheck) { 1341b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov if (type1.accountType == null) { 13422776c7fe8117773fdf773396f61ed047238470f9Jean-Baptiste Queru return 1; 13432776c7fe8117773fdf773396f61ed047238470f9Jean-Baptiste Queru } 1344b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov value = type1.accountType.compareTo(type2.accountType); 1345f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (value != 0) { 1346f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return value; 13472b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro } else { 13482b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro // Fall back to data set. 13492b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro if (type1.dataSet != null) { 13502b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro value = type1.dataSet.compareTo(type2.dataSet); 13512b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro if (value != 0) { 13522b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro return value; 13532b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro } 13542b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro } else if (type2.dataSet != null) { 13552b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro return 1; 13562b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro } 1357f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1358f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1359f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1360f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Check account name 1361851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String oneAccount = one.getAccountName(); 1362f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (oneAccount == null) oneAccount = ""; 1363851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String twoAccount = two.getAccountName(); 1364f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (twoAccount == null) twoAccount = ""; 1365f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann value = oneAccount.compareTo(twoAccount); 1366f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (value != 0) { 1367f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return value; 1368f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1369f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1370f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Both are in the same account, fall back to contact ID 1371851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu Long oneId = one.getRawContactId(); 1372851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu Long twoId = two.getRawContactId(); 1373f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (oneId == null) { 1374f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return -1; 1375f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } else if (twoId == null) { 1376f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return 1; 1377f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1378f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1379f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann return (int)(oneId - twoId); 1380f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1381f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1382f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1383f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann /** 1384f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * Returns the contact ID for the currently edited contact or 0 if the contact is new. 1385f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov */ 1386f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov protected long getContactId() { 1387c76c2e872b4d8deb0e8ac26e9558fa360d525fdeDmitri Plotnikov if (mState != null) { 1388851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu for (RawContactDelta rawContact : mState) { 1389c76c2e872b4d8deb0e8ac26e9558fa360d525fdeDmitri Plotnikov Long contactId = rawContact.getValues().getAsLong(RawContacts.CONTACT_ID); 1390c76c2e872b4d8deb0e8ac26e9558fa360d525fdeDmitri Plotnikov if (contactId != null) { 1391c76c2e872b4d8deb0e8ac26e9558fa360d525fdeDmitri Plotnikov return contactId; 1392c76c2e872b4d8deb0e8ac26e9558fa360d525fdeDmitri Plotnikov } 1393f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 1394f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 1395f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return 0; 1396f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 1397f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 1398f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov /** 1399f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * Triggers an asynchronous search for aggregation suggestions. 1400f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov */ 14012828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki private void acquireAggregationSuggestions(Context context, 14022828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki RawContactEditorView rawContactEditor) { 14039302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov long rawContactId = rawContactEditor.getRawContactId(); 14049302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov if (mAggregationSuggestionsRawContactId != rawContactId 14059302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov && mAggregationSuggestionView != null) { 14069302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov mAggregationSuggestionView.setVisibility(View.GONE); 14079302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov mAggregationSuggestionView = null; 14089302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov mAggregationSuggestionEngine.reset(); 14099302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 14109302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov 14119302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov mAggregationSuggestionsRawContactId = rawContactId; 14129302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov 1413f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (mAggregationSuggestionEngine == null) { 14142828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki mAggregationSuggestionEngine = new AggregationSuggestionEngine(context); 1415f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mAggregationSuggestionEngine.setListener(this); 1416f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mAggregationSuggestionEngine.start(); 1417f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 1418f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 1419916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov mAggregationSuggestionEngine.setContactId(getContactId()); 1420916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov 1421392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann LabeledEditorView nameEditor = rawContactEditor.getNameEditor(); 1422f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mAggregationSuggestionEngine.onNameChange(nameEditor.getValues()); 1423f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 1424f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 1425f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 1426f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void onAggregationSuggestionChange() { 1427288532cddfccdc3793dd748d1c75750e2f46cb53Yorke Lee Activity activity = getActivity(); 1428288532cddfccdc3793dd748d1c75750e2f46cb53Yorke Lee if ((activity != null && activity.isFinishing()) 1429288532cddfccdc3793dd748d1c75750e2f46cb53Yorke Lee || !isVisible() || mState == null || mStatus != Status.EDITING) { 143002cbf8b0e73a7e169445e341f387356242f0334dDmitri Plotnikov return; 143102cbf8b0e73a7e169445e341f387356242f0334dDmitri Plotnikov } 143202cbf8b0e73a7e169445e341f387356242f0334dDmitri Plotnikov 14336c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa if (mAggregationSuggestionPopup != null && mAggregationSuggestionPopup.isShowing()) { 14346c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.dismiss(); 14359302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 1436f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 14376c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa if (mAggregationSuggestionEngine.getSuggestedContactCount() == 0) { 1438f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return; 1439f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 1440f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 14416c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa final RawContactEditorView rawContactView = 14426c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa (RawContactEditorView)getRawContactEditorView(mAggregationSuggestionsRawContactId); 144302a54ebd3185948e2c1c0f39b7718cb9abaea934Makoto Onuki if (rawContactView == null) { 144402a54ebd3185948e2c1c0f39b7718cb9abaea934Makoto Onuki return; // Raw contact deleted? 144502a54ebd3185948e2c1c0f39b7718cb9abaea934Makoto Onuki } 14466c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa final View anchorView = rawContactView.findViewById(R.id.anchor_view); 14476c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup = new ListPopupWindow(mContext, null); 14486c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.setAnchorView(anchorView); 14496c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.setWidth(anchorView.getWidth()); 14506c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 14516c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.setAdapter( 14526c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa new AggregationSuggestionAdapter(getActivity(), 14536c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mState.size() == 1 && mState.get(0).isContactInsert(), 14546c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa this, mAggregationSuggestionEngine.getSuggestions())); 14556c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.setOnItemClickListener(mAggregationSuggestionItemClickListener); 14566c8c0777c823e2a2fef69299c0b36ca4a40e1feaDaisuke Miyakawa mAggregationSuggestionPopup.show(); 1457bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1458bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1459bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov @Override 1460bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public void onJoinAction(long contactId, List<Long> rawContactIdList) { 1461bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov long rawContactIds[] = new long[rawContactIdList.size()]; 1462bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov for (int i = 0; i < rawContactIds.length; i++) { 1463bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov rawContactIds[i] = rawContactIdList.get(i); 1464bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1465bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov JoinSuggestedContactDialogFragment dialog = 1466bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov new JoinSuggestedContactDialogFragment(); 1467bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov Bundle args = new Bundle(); 1468bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov args.putLongArray("rawContactIds", rawContactIds); 1469bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov dialog.setArguments(args); 1470bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov dialog.setTargetFragment(this, 0); 147174f519f81f257cd2f962fdf12e6ee9ec6fe6a5f0Dmitri Plotnikov try { 147274f519f81f257cd2f962fdf12e6ee9ec6fe6a5f0Dmitri Plotnikov dialog.show(getFragmentManager(), "join"); 147374f519f81f257cd2f962fdf12e6ee9ec6fe6a5f0Dmitri Plotnikov } catch (Exception ex) { 147474f519f81f257cd2f962fdf12e6ee9ec6fe6a5f0Dmitri Plotnikov // No problem - the activity is no longer available to display the dialog 147574f519f81f257cd2f962fdf12e6ee9ec6fe6a5f0Dmitri Plotnikov } 1476bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1477bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1478bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public static class JoinSuggestedContactDialogFragment extends DialogFragment { 1479bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1480bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov @Override 1481bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public Dialog onCreateDialog(Bundle savedInstanceState) { 1482bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov return new AlertDialog.Builder(getActivity()) 14834292dfa46123a6c0e1de9862b4d8694bfb87875aDmitri Plotnikov .setIconAttribute(android.R.attr.alertDialogIcon) 1484bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .setMessage(R.string.aggregation_suggestion_join_dialog_message) 1485bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .setPositiveButton(android.R.string.yes, 1486bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov new DialogInterface.OnClickListener() { 1487f30723782e801deaf159aea2443e9507596ef11dDaniel Lehmann @Override 1488bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public void onClick(DialogInterface dialog, int whichButton) { 1489bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov ContactEditorFragment targetFragment = 1490bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov (ContactEditorFragment) getTargetFragment(); 1491bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov long rawContactIds[] = 1492bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov getArguments().getLongArray("rawContactIds"); 1493bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov targetFragment.doJoinSuggestedContact(rawContactIds); 1494bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1495bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1496bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov ) 1497bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .setNegativeButton(android.R.string.no, null) 1498bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .create(); 1499bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1500bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1501bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1502bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov /** 1503bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov * Joins the suggested contact (specified by the id's of constituent raw 1504bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov * contacts), save all changes, and stay in the editor. 1505bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov */ 1506bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov protected void doJoinSuggestedContact(long[] rawContactIds) { 1507cd1b9a29458d30ec74cf94dc9945cbdb6186a68eDmitri Plotnikov if (!hasValidState() || mStatus != Status.EDITING) { 1508cd1b9a29458d30ec74cf94dc9945cbdb6186a68eDmitri Plotnikov return; 1509cd1b9a29458d30ec74cf94dc9945cbdb6186a68eDmitri Plotnikov } 1510cd1b9a29458d30ec74cf94dc9945cbdb6186a68eDmitri Plotnikov 1511bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov mState.setJoinWithRawContacts(rawContactIds); 15129df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov save(SaveMode.RELOAD); 1513bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1514bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1515bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov @Override 1516bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public void onEditAction(Uri contactLookupUri) { 1517bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov SuggestionEditConfirmationDialogFragment dialog = 1518bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov new SuggestionEditConfirmationDialogFragment(); 1519bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov Bundle args = new Bundle(); 1520bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov args.putParcelable("contactUri", contactLookupUri); 1521bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov dialog.setArguments(args); 1522bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov dialog.setTargetFragment(this, 0); 1523bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov dialog.show(getFragmentManager(), "edit"); 1524bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1525bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1526bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public static class SuggestionEditConfirmationDialogFragment extends DialogFragment { 1527bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1528bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov @Override 1529bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public Dialog onCreateDialog(Bundle savedInstanceState) { 1530bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov return new AlertDialog.Builder(getActivity()) 15314292dfa46123a6c0e1de9862b4d8694bfb87875aDmitri Plotnikov .setIconAttribute(android.R.attr.alertDialogIcon) 1532bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .setMessage(R.string.aggregation_suggestion_edit_dialog_message) 1533bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .setPositiveButton(android.R.string.yes, 1534bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov new DialogInterface.OnClickListener() { 1535f30723782e801deaf159aea2443e9507596ef11dDaniel Lehmann @Override 1536bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public void onClick(DialogInterface dialog, int whichButton) { 1537bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov ContactEditorFragment targetFragment = 1538bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov (ContactEditorFragment) getTargetFragment(); 1539bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov Uri contactUri = 1540bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov getArguments().getParcelable("contactUri"); 1541bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov targetFragment.doEditSuggestedContact(contactUri); 1542bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1543bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1544bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov ) 1545bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .setNegativeButton(android.R.string.no, null) 1546bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov .create(); 1547bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1548bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1549bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1550bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov /** 1551bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov * Abandons the currently edited contact and switches to editing the suggested 1552bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov * one, transferring all the data there 1553bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov */ 1554bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov protected void doEditSuggestedContact(Uri contactUri) { 1555bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov if (mListener != null) { 1556a10775d625339d168337e03de05d02f5e0a4f55dDaniel Lehmann // make sure we don't save this contact when closing down 1557a10775d625339d168337e03de05d02f5e0a4f55dDaniel Lehmann mStatus = Status.CLOSING; 1558bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov mListener.onEditOtherContactRequested( 1559bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov contactUri, mState.get(0).getContentValues()); 1560bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1561bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov } 1562bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov 1563a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov public void setAggregationSuggestionViewEnabled(boolean enabled) { 1564a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov if (mAggregationSuggestionView == null) { 1565a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov return; 1566a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov } 1567a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov 1568a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov LinearLayout itemList = (LinearLayout) mAggregationSuggestionView.findViewById( 1569a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov R.id.aggregation_suggestions); 1570a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov int count = itemList.getChildCount(); 1571a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov for (int i = 0; i < count; i++) { 1572a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov itemList.getChildAt(i).setEnabled(enabled); 1573a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov } 1574a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov } 1575a9333790f027d59a2edfd4a98c0392b144577416Dmitri Plotnikov 1576f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann @Override 1577f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void onSaveInstanceState(Bundle outState) { 1578b846fc117b2c4c0c3ed5eb3e9ce32591986a0253Daniel Lehmann outState.putParcelable(KEY_URI, mLookupUri); 1579d364314c460152db7089b304beec81b3675893baDmitri Plotnikov outState.putString(KEY_ACTION, mAction); 1580d364314c460152db7089b304beec81b3675893baDmitri Plotnikov 1581f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (hasValidState()) { 1582f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann // Store entities with modifications 1583f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann outState.putParcelable(KEY_EDIT_STATE, mState); 1584f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 15854bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto); 1586f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann outState.putParcelable(KEY_VIEW_ID_GENERATOR, mViewIdGenerator); 1587ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile); 1588f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin); 1589623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann outState.putBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN, mContactWritableForJoin); 15909302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov outState.putLong(KEY_SHOW_JOIN_SUGGESTIONS, mAggregationSuggestionsRawContactId); 159102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov outState.putBoolean(KEY_ENABLED, mEnabled); 1592ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson outState.putBoolean(KEY_NEW_LOCAL_PROFILE, mNewLocalProfile); 1593ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson outState.putBoolean(KEY_IS_USER_PROFILE, mIsUserProfile); 1594ce37f3017c666bcea483a75322e80d5cc1ba6f64Dmitri Plotnikov outState.putInt(KEY_STATUS, mStatus); 159528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos); 159628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 1597f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann super.onSaveInstanceState(outState); 1598f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1599f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 1600d364314c460152db7089b304beec81b3675893baDmitri Plotnikov @Override 1601f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann public void onActivityResult(int requestCode, int resultCode, Intent data) { 1602f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov if (mStatus == Status.SUB_ACTIVITY) { 1603f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov mStatus = Status.EDITING; 1604f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov } 1605f9ca423c867ab2cd4f0d9025a95436489c41d405Dmitri Plotnikov 16066fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // See if the photo selection handler handles this result. 160791004b37683c15650eccde68ff04defcf94a1c84Maurice Chu if (mCurrentPhotoHandler != null && mCurrentPhotoHandler.handlePhotoActivityResult( 16086fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro requestCode, resultCode, data)) { 16096fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return; 16106fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1611f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann 16126fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro switch (requestCode) { 1613a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann case REQUEST_CODE_JOIN: { 16140353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Ignore failed requests 16150353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (resultCode != Activity.RESULT_OK) return; 1616f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann if (data != null) { 1617f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann final long contactId = ContentUris.parseId(data.getData()); 1618f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann joinAggregate(contactId); 1619f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 16204a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann break; 1621f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 16220353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan case REQUEST_CODE_ACCOUNTS_CHANGED: { 16230353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // Bail if the account selector was not successful. 16240353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (resultCode != Activity.RESULT_OK) { 16250353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan mListener.onReverted(); 16260353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan return; 16270353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 16280353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // If there's an account specified, use it. 16290353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (data != null) { 16300353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan AccountWithDataSet account = data.getParcelableExtra(Intents.Insert.ACCOUNT); 16310353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan if (account != null) { 16320353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan createContact(account); 16330353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan return; 16340353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 16350353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 16360353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // If there isn't an account specified, then this is likely a phone-local 16370353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // contact, so we should continue setting up the editor by automatically selecting 16380353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan // the most appropriate account. 16390353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan createContact(); 16400353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan break; 16410353a24d97cc0266eb9bf0ee6c7d6821aeb1896eKatherine Kuan } 1642f319cf8549738feca5965a598af9a310869e1f3dDaniel Lehmann } 1643cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann } 16449cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov 1645c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann /** 1646c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann * Sets the photo stored in mPhoto and writes it to the RawContact with the given id 1647c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann */ 1648ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus private void setPhoto(long rawContact, Bitmap photo, String photoFile) { 1649bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov BaseRawContactEditorView requestingEditor = getRawContactEditorView(rawContact); 1650e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus 1651e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus if (photo == null || photo.getHeight() < 0 || photo.getWidth() < 0) { 1652e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus // This is unexpected. 1653e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus Log.w(TAG, "Invalid bitmap passed to setPhoto()"); 1654e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus } 1655e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus 16569302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov if (requestingEditor != null) { 16579302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov requestingEditor.setPhotoBitmap(photo); 16589302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } else { 16599302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov Log.w(TAG, "The contact that requested the photo is no longer present."); 16609302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 1661e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus 1662ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus final String croppedPhotoPath = 1663ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus ContactPhotoUtils.pathForCroppedPhoto(mContext, mCurrentPhotoFile); 1664ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus mUpdatedPhotos.putString(String.valueOf(rawContact), croppedPhotoPath); 16659302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 16669302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov 16679302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov /** 16689302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov * Finds raw contact editor view for the given rawContactId. 16699302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov */ 1670bd0c12c63bb0adbc78715d9d13ba588c8ae61839Dmitri Plotnikov public BaseRawContactEditorView getRawContactEditorView(long rawContactId) { 1671c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann for (int i = 0; i < mContent.getChildCount(); i++) { 1672c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann final View childView = mContent.getChildAt(i); 167372af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann if (childView instanceof BaseRawContactEditorView) { 167472af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView; 16759302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov if (editor.getRawContactId() == rawContactId) { 16769302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov return editor; 1677c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 1678c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 1679c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 16809302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov return null; 1681c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann } 1682c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann 1683fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann /** 1684fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann * Returns true if there is currently more than one photo on screen. 1685fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann */ 1686fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann private boolean hasMoreThanOnePhoto() { 1687fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann int countWithPicture = 0; 168891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final int numEntities = mState.size(); 168991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu for (int i = 0; i < numEntities; i++) { 1690851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta entity = mState.get(i); 1691851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (entity.isVisible()) { 169291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE); 1693851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu if (primary != null && primary.getPhoto() != null) { 1694fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann countWithPicture++; 169591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } else { 1696851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final long rawContactId = entity.getRawContactId(); 169791004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final String path = mUpdatedPhotos.getString(String.valueOf(rawContactId)); 169891004b37683c15650eccde68ff04defcf94a1c84Maurice Chu if (path != null) { 169991004b37683c15650eccde68ff04defcf94a1c84Maurice Chu final File file = new File(path); 170091004b37683c15650eccde68ff04defcf94a1c84Maurice Chu if (file.exists()) { 170191004b37683c15650eccde68ff04defcf94a1c84Maurice Chu countWithPicture++; 170291004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } 170391004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } 170491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu } 170591004b37683c15650eccde68ff04defcf94a1c84Maurice Chu 170691004b37683c15650eccde68ff04defcf94a1c84Maurice Chu if (countWithPicture > 1) { 170791004b37683c15650eccde68ff04defcf94a1c84Maurice Chu return true; 1708fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann } 1709fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann } 1710fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann } 1711fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann return false; 17129cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov } 1713222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann 1714222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann /** 1715222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann * The listener for the data loader 1716222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann */ 1717851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private final LoaderManager.LoaderCallbacks<Contact> mDataLoaderListener = 1718851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu new LoaderCallbacks<Contact>() { 1719222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann @Override 1720851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public Loader<Contact> onCreateLoader(int id, Bundle args) { 1721222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann mLoaderStartTime = SystemClock.elapsedRealtime(); 172245ee872fe7be69c6b3f0c59167eecd11af467812Makoto Onuki return new ContactLoader(mContext, mLookupUri, true); 1723222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann } 1724222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann 1725222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann @Override 1726851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void onLoadFinished(Loader<Contact> loader, Contact data) { 1727222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann final long loaderCurrentTime = SystemClock.elapsedRealtime(); 1728222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann Log.v(TAG, "Time needed for loading: " + (loaderCurrentTime-mLoaderStartTime)); 17292621c5bb7049401c8bce740005fa60bf1b304b86Makoto Onuki if (!data.isLoaded()) { 1730222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann // Item has been deleted 1731222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann Log.i(TAG, "No contact found. Closing activity"); 173222fb2053fe2bfe98376bf1a0e564f23ae9cecdedDaniel Lehmann if (mListener != null) mListener.onContactNotFound(); 1733222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann return; 1734222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann } 1735222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann 1736825cb62b7df3cfe208651d488278e1b57c863884Daniel Lehmann mStatus = Status.EDITING; 17376caccaeeed943db323be89853a108f422e670760Dmitri Plotnikov mLookupUri = data.getLookupUri(); 1738222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann final long setDataStartTime = SystemClock.elapsedRealtime(); 1739222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann setData(data); 1740222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann final long setDataEndTime = SystemClock.elapsedRealtime(); 1741c1406450bb2a1a214ff35e99a173ee1a28b926faDaniel Lehmann 1742222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann Log.v(TAG, "Time needed for setting UI: " + (setDataEndTime-setDataStartTime)); 1743222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann } 17444ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn 1745623932de8c18e9b83b6fd941afe415ab2e6c730bDaniel Lehmann @Override 1746851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void onLoaderReset(Loader<Contact> loader) { 17474ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn } 1748222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmann }; 1749a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 1750e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov /** 1751be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan * The listener for the group meta data loader for all groups. 1752e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov */ 1753e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov private final LoaderManager.LoaderCallbacks<Cursor> mGroupLoaderListener = 1754e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov new LoaderCallbacks<Cursor>() { 1755e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 1756e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov @Override 1757e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov public CursorLoader onCreateLoader(int id, Bundle args) { 1758be18de05d6f6a107c552e369bce58f51c946fde7Katherine Kuan return new GroupMetaDataLoader(mContext, Groups.CONTENT_URI); 1759e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov } 1760e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 1761e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov @Override 1762e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 1763e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov mGroupMetaData = data; 1764e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov bindGroupMetaData(); 1765e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov } 17664ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn 1767f30723782e801deaf159aea2443e9507596ef11dDaniel Lehmann @Override 17684ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn public void onLoaderReset(Loader<Cursor> loader) { 17694ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn } 1770e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov }; 1771e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov 1772a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann @Override 1773a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann public void onSplitContactConfirmed() { 1774b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa if (mState == null) { 1775b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa // This may happen when this Fragment is recreated by the system during users 1776b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa // confirming the split action (and thus this method is called just before onCreate()), 1777b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa // for example. 1778b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa Log.e(TAG, "mState became null during the user's confirming split action. " + 1779b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa "Cannot perform the save action."); 1780b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa return; 1781b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa } 1782b9e60280603f2fa57083c13952e4b25e2585b833Daisuke Miyakawa 1783a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann mState.markRawContactsForSplitting(); 17849df61ed9eeecb81043e7e6662ff3da83428d6865Dmitri Plotnikov save(SaveMode.SPLIT); 1785a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann } 1786a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 17876fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 17886fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * Custom photo handler for the editor. The inner listener that this creates also has a 17896fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * reference to the editor and acts as an {@link EditorListener}, and uses that editor to hold 17906fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * state information in several of the listener methods. 17916fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 17926fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final class PhotoHandler extends PhotoSelectionHandler { 179328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 179428eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus final long mRawContactId; 1795e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus private final BaseRawContactEditorView mEditor; 17964bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki private final PhotoActionListener mPhotoEditorListener; 179728eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 17986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode, 1799851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDeltaList state) { 18006fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro super(context, editor.getPhotoEditor(), photoMode, false, state); 1801e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus mEditor = editor; 180228eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus mRawContactId = editor.getRawContactId(); 18039a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann mPhotoEditorListener = new PhotoEditorListener(); 1804e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus } 1805e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus 1806e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus @Override 1807e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus public PhotoActionListener getListener() { 18089a409d474b2b4f2e4261657f864eeb866fcb8816Daniel Lehmann return mPhotoEditorListener; 1809e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus } 1810e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus 1811e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus @Override 1812ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus public void startPhotoActivity(Intent intent, int requestCode, String photoFile) { 18134bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki mRawContactIdRequestingPhoto = mEditor.getRawContactId(); 181491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu mCurrentPhotoHandler = this; 1815e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus mStatus = Status.SUB_ACTIVITY; 1816e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus mCurrentPhotoFile = photoFile; 1817e5d3f897689c8ba0f275c7679c72eacb190ae9b8Josh Gargus ContactEditorFragment.this.startActivityForResult(intent, requestCode); 18189442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 18199442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 18206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener 18216fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro implements EditorListener { 1822fe22aff8c87374cfa80a7a02ec29b442f2453d8cDaniel Lehmann 18236fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18246fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onRequest(int request) { 18256fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (!hasValidState()) return; 1826a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 18276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (request == EditorListener.REQUEST_PICK_PHOTO) { 18286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro onClick(mEditor.getPhotoEditor()); 18299442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 18309442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1831a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 18326fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onDeleteRequested(Editor removedEditor) { 18346fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // The picture cannot be deleted, it can only be removed, which is handled by 18356fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // onRemovePictureChosen() 18366fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 1837a35a7e2aabc4edfafb9b4171e279bdb4c0c03d44Daniel Lehmann 18386fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 18396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * User has chosen to set the selected photo as the (super) primary photo 18406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 18416fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18426fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onUseAsPrimaryChosen() { 18436fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Set the IsSuperPrimary for each editor 18446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro int count = mContent.getChildCount(); 18456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro for (int i = 0; i < count; i++) { 18466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final View childView = mContent.getChildAt(i); 18476fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro if (childView instanceof BaseRawContactEditorView) { 18486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final BaseRawContactEditorView editor = 18496fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro (BaseRawContactEditorView) childView; 18506fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro final PhotoEditorView photoEditor = editor.getPhotoEditor(); 18516fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro photoEditor.setSuperPrimary(editor == mEditor); 18526fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 18536fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 185491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu bindEditors(); 18556fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 18569442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 18576fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro /** 18586fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro * User has chosen to remove a picture 18596fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro */ 18606fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onRemovePictureChosen() { 18626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro mEditor.setPhotoBitmap(null); 186328eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus 186428eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus // Prevent bitmap from being restored if rotate the device. 186528eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus // (only if we first chose a new photo before removing it) 186628eadab78531e22a0d9fa22fbbcd61c451005890Josh Gargus mUpdatedPhotos.remove(String.valueOf(mRawContactId)); 186791004b37683c15650eccde68ff04defcf94a1c84Maurice Chu bindEditors(); 18686fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 18696fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 18706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18716fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onPhotoSelected(Bitmap bitmap) { 18724bff8fb686f2ac5500109a32cca9270965c620d6Makoto Onuki setPhoto(mRawContactId, bitmap, mCurrentPhotoFile); 187391004b37683c15650eccde68ff04defcf94a1c84Maurice Chu mCurrentPhotoHandler = null; 187491004b37683c15650eccde68ff04defcf94a1c84Maurice Chu bindEditors(); 18756fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 18766fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 18776fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 1878ebc17929007ecf12f25b8e90023766e8a083d11eJosh Gargus public String getCurrentPhotoFile() { 18796fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro return mCurrentPhotoFile; 18806fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro } 18816fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 18826fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro @Override 18836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro public void onPhotoSelectionDismissed() { 18846fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro // Nothing to do. 18859442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 18864a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann } 18874a62be4f5a365e5afde71becfd446381f2baa494Daniel Lehmann } 18882ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey} 1889