16e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov/* 26e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 36e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * 46e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 56e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * you may not use this file except in compliance with the License. 66e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * You may obtain a copy of the License at 76e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * 86e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 96e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * 106e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 116e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 126e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * See the License for the specific language governing permissions and 146e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * limitations under the License. 156e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov */ 166e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovpackage com.android.contacts.list; 176e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov 18e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.app.Activity; 19e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikovimport android.app.LoaderManager.LoaderCallbacks; 20e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.content.ContentUris; 213c46291ef057eaf7b7f8ca5971e59bebe734a660Jeff Hamiltonimport android.content.CursorLoader; 22e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikovimport android.content.Intent; 233c46291ef057eaf7b7f8ca5971e59bebe734a660Jeff Hamiltonimport android.content.Loader; 24e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.database.Cursor; 25097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmannimport android.net.Uri; 26e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.os.Bundle; 27e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 28ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawaimport android.text.TextUtils; 29caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikovimport android.view.LayoutInflater; 30caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikovimport android.view.View; 3159fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikovimport android.view.ViewGroup; 32e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.widget.TextView; 336e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov 34e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 35e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.list.JoinContactLoader.JoinContactLoaderResult; 360a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.logging.ListEvent; 37e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 386e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov/** 3959fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikov * Fragment for the Join Contact list. 406e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov */ 41e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovpublic class JoinContactListFragment extends ContactEntryListFragment<JoinContactListAdapter> { 42e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 43e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov private static final int DISPLAY_NAME_LOADER = -2; 44e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 45a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa private static final String KEY_TARGET_CONTACT_ID = "targetContactId"; 46d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov 47e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov private OnContactPickerActionListener mListener; 48e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov private long mTargetContactId; 49e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 50a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa private final LoaderCallbacks<Cursor> mLoaderCallbacks = new LoaderCallbacks<Cursor>() { 51e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov 52e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov @Override 53e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov public Loader<Cursor> onCreateLoader(int id, Bundle args) { 54e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov switch (id) { 55e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov case DISPLAY_NAME_LOADER: { 56e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov // Loader for the display name of the target contact 57e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov return new CursorLoader(getActivity(), 58e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov ContentUris.withAppendedId(Contacts.CONTENT_URI, mTargetContactId), 59e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov new String[] { Contacts.DISPLAY_NAME }, null, null, null); 60e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 61e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov case JoinContactListAdapter.PARTITION_ALL_CONTACTS: { 62e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov JoinContactLoader loader = new JoinContactLoader(getActivity()); 63e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov JoinContactListAdapter adapter = getAdapter(); 64e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov if (adapter != null) { 65e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov adapter.configureLoader(loader, 0); 66e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 67e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov return loader; 68e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 69e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 70e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov throw new IllegalArgumentException("No loader for ID=" + id); 71e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 72e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov 73e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov @Override 74e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 75e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov switch (loader.getId()) { 76e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov case DISPLAY_NAME_LOADER: { 77e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov if (data != null && data.moveToFirst()) { 78e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov showTargetContactName(data.getString(0)); 79e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 80e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov break; 81e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 82e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov case JoinContactListAdapter.PARTITION_ALL_CONTACTS: { 8374b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner if (data != null) { 8474b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner final Cursor suggestionsCursor = 8574b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner ((JoinContactLoaderResult) data).suggestionCursor; 8674b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner onContactListLoaded(suggestionsCursor, data); 876158b814d330f2c61522387b9e0ce40208b5ef63Walter Jang maybeLogListEvent(); 8874b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 89e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov break; 90e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 91e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 92e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov } 93d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov 9414ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki @Override 954ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn public void onLoaderReset(Loader<Cursor> loader) { 964ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn } 97e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov }; 98e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov 99e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public JoinContactListFragment() { 100e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov setPhotoLoaderEnabled(true); 101e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov setSectionHeaderDisplayEnabled(true); 1025245ea63b4cca18ee504b27abd534fc13d33dea9Dmitri Plotnikov setVisibleScrollbarEnabled(false); 103b22ca30163f5f99f07b906c20fd1a798541448a5Dmitri Plotnikov setQuickContactEnabled(false); 1046158b814d330f2c61522387b9e0ce40208b5ef63Walter Jang setListType(ListEvent.ListType.PICK_JOIN); 1056158b814d330f2c61522387b9e0ce40208b5ef63Walter Jang setLogListEvents(true); 106e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 107e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 108e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public void setOnContactPickerActionListener(OnContactPickerActionListener listener) { 109e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov mListener = listener; 110e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 111e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 112e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov @Override 113fec29c7320c6c45aff69dbd6ec0edb267fb402f4Daniel Lehmann protected void startLoading() { 1144e0ce3fb44125453e0ad723d7e3d3e89ad639e01Dmitri Plotnikov configureAdapter(); 1154e0ce3fb44125453e0ad723d7e3d3e89ad639e01Dmitri Plotnikov 116e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov getLoaderManager().initLoader(DISPLAY_NAME_LOADER, null, mLoaderCallbacks); 117ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa 118ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa // When this method is called, Uri to be used may be changed. We should use restartLoader() 119ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa // to load the parameter again. 120ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa getLoaderManager().restartLoader(JoinContactListAdapter.PARTITION_ALL_CONTACTS, 121e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov null, mLoaderCallbacks); 122e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 123e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 124a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa private void onContactListLoaded(Cursor suggestionsCursor, Cursor allContactsCursor) { 125d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov JoinContactListAdapter adapter = getAdapter(); 126d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov adapter.setSuggestionsCursor(suggestionsCursor); 127a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa setVisibleScrollbarEnabled(true); 128a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa onPartitionLoaded(JoinContactListAdapter.PARTITION_ALL_CONTACTS, allContactsCursor); 129d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov } 130d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov 131e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov private void showTargetContactName(String displayName) { 132e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov Activity activity = getActivity(); 133a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa TextView blurbView = (TextView) activity.findViewById(R.id.join_contact_blurb); 13476c1a51953eccb49eb843e9aee0cbc2f23451042Jay Shrauner final String name = !TextUtils.isEmpty(displayName) ? displayName 13576c1a51953eccb49eb843e9aee0cbc2f23451042Jay Shrauner : activity.getString(R.string.missing_name); 13676c1a51953eccb49eb843e9aee0cbc2f23451042Jay Shrauner String blurb = activity.getString(R.string.blurbJoinContactDataWith, name); 137e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov blurbView.setText(blurb); 138e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 139e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 140e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public void setTargetContactId(long targetContactId) { 141e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov mTargetContactId = targetContactId; 142e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 143e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 144e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov @Override 145e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public JoinContactListAdapter createListAdapter() { 146fd4df88d03a745728bb1c1df9648e7b5989641b6Paul Sliwowski JoinContactListAdapter adapter = new JoinContactListAdapter(getActivity()); 14785405d033aab3d6b5858ba0beb1e14acdca6b9a7Sean Midford adapter.setPhotoPosition(ContactListItemView.getDefaultPhotoPosition(false /* opposite */)); 148fd4df88d03a745728bb1c1df9648e7b5989641b6Paul Sliwowski return adapter; 149e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 1506e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov 1516e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov @Override 152e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov protected void configureAdapter() { 153e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov super.configureAdapter(); 154e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov JoinContactListAdapter adapter = getAdapter(); 155e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov adapter.setTargetContactId(mTargetContactId); 1566e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov } 1576e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov 1586e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov @Override 15959fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikov protected View inflateView(LayoutInflater inflater, ViewGroup container) { 160d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov return inflater.inflate(R.layout.join_contact_picker_list_content, null); 1616e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov } 162caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikov 163caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikov @Override 16459fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikov protected void onItemClick(int position, long id) { 165097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann final Uri contactUri = getAdapter().getContactUri(position); 166097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann if (contactUri != null) mListener.onPickContactAction(contactUri); 167caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikov } 168e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov 169e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov @Override 170e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov public void onPickerResult(Intent data) { 171097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann final Uri contactUri = data.getData(); 172097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann if (contactUri != null) mListener.onPickContactAction(contactUri); 173e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov } 174d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov 175d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov @Override 176d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov public void onSaveInstanceState(Bundle outState) { 177d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov super.onSaveInstanceState(outState); 178a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa outState.putLong(KEY_TARGET_CONTACT_ID, mTargetContactId); 179d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov } 180d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov 181d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov @Override 182d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov public void restoreSavedState(Bundle savedState) { 183d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov super.restoreSavedState(savedState); 184d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov if (savedState != null) { 185a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa mTargetContactId = savedState.getLong(KEY_TARGET_CONTACT_ID); 186d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov } 187d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov } 188ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa 189ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa @Override 190ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa public void setQueryString(String queryString, boolean delaySelection) { 191ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa super.setQueryString(queryString, delaySelection); 192ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa 193ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa setSearchMode(!TextUtils.isEmpty(queryString)); 194ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa } 1956e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov} 196