Home | History | Annotate | Download | only in list
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.contacts.common.list;
     17 
     18 import android.content.CursorLoader;
     19 import android.content.Intent;
     20 import android.content.Loader;
     21 import android.database.Cursor;
     22 import android.net.Uri;
     23 import android.os.Bundle;
     24 import android.text.TextUtils;
     25 import android.util.Log;
     26 import android.view.LayoutInflater;
     27 import android.view.MenuItem;
     28 import android.view.View;
     29 import android.view.View.OnClickListener;
     30 import android.view.ViewGroup;
     31 
     32 import com.android.contacts.common.R;
     33 import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
     34 import com.android.contacts.common.util.AccountFilterUtil;
     35 
     36 /**
     37  * Fragment containing a phone number list for picking.
     38  */
     39 public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactEntryListAdapter>
     40         implements OnShortcutIntentCreatedListener {
     41     private static final String TAG = PhoneNumberPickerFragment.class.getSimpleName();
     42 
     43     private static final int REQUEST_CODE_ACCOUNT_FILTER = 1;
     44 
     45     private static final String KEY_SHORTCUT_ACTION = "shortcutAction";
     46 
     47     private OnPhoneNumberPickerActionListener mListener;
     48     private String mShortcutAction;
     49 
     50     private ContactListFilter mFilter;
     51 
     52     private View mAccountFilterHeader;
     53     /**
     54      * Lives as ListView's header and is shown when {@link #mAccountFilterHeader} is set
     55      * to View.GONE.
     56      */
     57     private View mPaddingView;
     58 
     59     private static final String KEY_FILTER = "filter";
     60 
     61     /** true if the loader has started at least once. */
     62     private boolean mLoaderStarted;
     63 
     64     private boolean mUseCallableUri;
     65 
     66     private ContactListItemView.PhotoPosition mPhotoPosition =
     67             ContactListItemView.getDefaultPhotoPosition(false /* normal/non opposite */);
     68 
     69     private class FilterHeaderClickListener implements OnClickListener {
     70         @Override
     71         public void onClick(View view) {
     72             AccountFilterUtil.startAccountFilterActivityForResult(
     73                     PhoneNumberPickerFragment.this,
     74                     REQUEST_CODE_ACCOUNT_FILTER,
     75                     mFilter);
     76         }
     77     }
     78     private OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener();
     79 
     80     public PhoneNumberPickerFragment() {
     81         setQuickContactEnabled(false);
     82         setPhotoLoaderEnabled(true);
     83         setSectionHeaderDisplayEnabled(true);
     84         setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
     85 
     86         // Show nothing instead of letting caller Activity show something.
     87         setHasOptionsMenu(true);
     88     }
     89 
     90     public void setDirectorySearchEnabled(boolean flag) {
     91         setDirectorySearchMode(flag ? DirectoryListLoader.SEARCH_MODE_DEFAULT
     92                 : DirectoryListLoader.SEARCH_MODE_NONE);
     93     }
     94 
     95     public void setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener) {
     96         this.mListener = listener;
     97     }
     98 
     99     public OnPhoneNumberPickerActionListener getOnPhoneNumberPickerListener() {
    100         return mListener;
    101     }
    102 
    103     @Override
    104     protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
    105         super.onCreateView(inflater, container);
    106 
    107         View paddingView = inflater.inflate(R.layout.contact_detail_list_padding, null, false);
    108         mPaddingView = paddingView.findViewById(R.id.contact_detail_list_padding);
    109         getListView().addHeaderView(paddingView);
    110 
    111         mAccountFilterHeader = getView().findViewById(R.id.account_filter_header_container);
    112         mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
    113         updateFilterHeaderView();
    114 
    115         setVisibleScrollbarEnabled(getVisibleScrollbarEnabled());
    116     }
    117 
    118     protected boolean getVisibleScrollbarEnabled() {
    119         return true;
    120     }
    121 
    122     @Override
    123     protected void setSearchMode(boolean flag) {
    124         super.setSearchMode(flag);
    125         updateFilterHeaderView();
    126     }
    127 
    128     private void updateFilterHeaderView() {
    129         final ContactListFilter filter = getFilter();
    130         if (mAccountFilterHeader == null || filter == null) {
    131             return;
    132         }
    133         final boolean shouldShowHeader =
    134                 !isSearchMode() &&
    135                 AccountFilterUtil.updateAccountFilterTitleForPhone(
    136                         mAccountFilterHeader, filter, false);
    137         if (shouldShowHeader) {
    138             mPaddingView.setVisibility(View.GONE);
    139             mAccountFilterHeader.setVisibility(View.VISIBLE);
    140         } else {
    141             mPaddingView.setVisibility(View.VISIBLE);
    142             mAccountFilterHeader.setVisibility(View.GONE);
    143         }
    144     }
    145 
    146     @Override
    147     public void restoreSavedState(Bundle savedState) {
    148         super.restoreSavedState(savedState);
    149 
    150         if (savedState == null) {
    151             return;
    152         }
    153 
    154         mFilter = savedState.getParcelable(KEY_FILTER);
    155         mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION);
    156     }
    157 
    158     @Override
    159     public void onSaveInstanceState(Bundle outState) {
    160         super.onSaveInstanceState(outState);
    161         outState.putParcelable(KEY_FILTER, mFilter);
    162         outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction);
    163     }
    164 
    165     @Override
    166     public boolean onOptionsItemSelected(MenuItem item) {
    167         final int itemId = item.getItemId();
    168         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
    169             if (mListener != null) {
    170                 mListener.onHomeInActionBarSelected();
    171             }
    172             return true;
    173         }
    174         return super.onOptionsItemSelected(item);
    175     }
    176 
    177     /**
    178      * @param shortcutAction either {@link Intent#ACTION_CALL} or
    179      *            {@link Intent#ACTION_SENDTO} or null.
    180      */
    181     public void setShortcutAction(String shortcutAction) {
    182         this.mShortcutAction = shortcutAction;
    183     }
    184 
    185     @Override
    186     protected void onItemClick(int position, long id) {
    187         final Uri phoneUri = getPhoneUri(position);
    188 
    189         if (phoneUri != null) {
    190             pickPhoneNumber(phoneUri);
    191         } else {
    192             final String number = getPhoneNumber(position);
    193             if (!TextUtils.isEmpty(number)) {
    194                 cacheContactInfo(position);
    195                 mListener.onCallNumberDirectly(number);
    196             } else {
    197                 Log.w(TAG, "Item at " + position + " was clicked before"
    198                         + " adapter is ready. Ignoring");
    199             }
    200         }
    201     }
    202 
    203     protected void cacheContactInfo(int position) {
    204         // Not implemented. Hook for child classes
    205     }
    206 
    207     protected String getPhoneNumber(int position) {
    208         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
    209         return adapter.getPhoneNumber(position);
    210     }
    211 
    212     protected Uri getPhoneUri(int position) {
    213         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
    214         return adapter.getDataUri(position);
    215     }
    216 
    217     @Override
    218     protected void startLoading() {
    219         mLoaderStarted = true;
    220         super.startLoading();
    221     }
    222 
    223     @Override
    224     public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    225         super.onLoadFinished(loader, data);
    226 
    227         // disable scroll bar if there is no data
    228         setVisibleScrollbarEnabled(data != null && data.getCount() > 0);
    229     }
    230 
    231     public void setUseCallableUri(boolean useCallableUri) {
    232         mUseCallableUri = useCallableUri;
    233     }
    234 
    235     public boolean usesCallableUri() {
    236         return mUseCallableUri;
    237     }
    238 
    239     @Override
    240     protected ContactEntryListAdapter createListAdapter() {
    241         PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
    242         adapter.setDisplayPhotos(true);
    243         adapter.setUseCallableUri(mUseCallableUri);
    244         return adapter;
    245     }
    246 
    247     @Override
    248     protected void configureAdapter() {
    249         super.configureAdapter();
    250 
    251         final ContactEntryListAdapter adapter = getAdapter();
    252         if (adapter == null) {
    253             return;
    254         }
    255 
    256         if (!isSearchMode() && mFilter != null) {
    257             adapter.setFilter(mFilter);
    258         }
    259 
    260         setPhotoPosition(adapter);
    261     }
    262 
    263     protected void setPhotoPosition(ContactEntryListAdapter adapter) {
    264         ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition);
    265     }
    266 
    267     @Override
    268     protected View inflateView(LayoutInflater inflater, ViewGroup container) {
    269         return inflater.inflate(R.layout.contact_list_content, null);
    270     }
    271 
    272     public void pickPhoneNumber(Uri uri) {
    273         if (mShortcutAction == null) {
    274             mListener.onPickPhoneNumberAction(uri);
    275         } else {
    276             startPhoneNumberShortcutIntent(uri);
    277         }
    278     }
    279 
    280     protected void startPhoneNumberShortcutIntent(Uri uri) {
    281         ShortcutIntentBuilder builder = new ShortcutIntentBuilder(getActivity(), this);
    282         builder.createPhoneNumberShortcutIntent(uri, mShortcutAction);
    283     }
    284 
    285     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
    286         mListener.onShortcutIntentCreated(shortcutIntent);
    287     }
    288 
    289     @Override
    290     public void onPickerResult(Intent data) {
    291         mListener.onPickPhoneNumberAction(data.getData());
    292     }
    293 
    294     @Override
    295     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    296         if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) {
    297             if (getActivity() != null) {
    298                 AccountFilterUtil.handleAccountFilterResult(
    299                         ContactListFilterController.getInstance(getActivity()), resultCode, data);
    300             } else {
    301                 Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()");
    302             }
    303         }
    304     }
    305 
    306     public ContactListFilter getFilter() {
    307         return mFilter;
    308     }
    309 
    310     public void setFilter(ContactListFilter filter) {
    311         if ((mFilter == null && filter == null) ||
    312                 (mFilter != null && mFilter.equals(filter))) {
    313             return;
    314         }
    315 
    316         mFilter = filter;
    317         if (mLoaderStarted) {
    318             reloadData();
    319         }
    320         updateFilterHeaderView();
    321     }
    322 
    323     public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
    324         mPhotoPosition = photoPosition;
    325 
    326         final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
    327         if (adapter != null) {
    328             adapter.setPhotoPosition(photoPosition);
    329         }
    330     }
    331 }
    332