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 */
16package com.android.contacts.list;
17
18import android.content.Intent;
19import android.content.Loader;
20import android.database.Cursor;
21import android.net.Uri;
22import android.os.Bundle;
23import android.util.Log;
24import android.view.LayoutInflater;
25import android.view.MenuItem;
26import android.view.View;
27import android.view.View.OnClickListener;
28import android.view.ViewGroup;
29
30import com.android.contacts.R;
31import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
32import com.android.contacts.util.AccountFilterUtil;
33
34/**
35 * Fragment containing a phone number list for picking.
36 */
37public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactEntryListAdapter>
38        implements OnShortcutIntentCreatedListener {
39    private static final String TAG = PhoneNumberPickerFragment.class.getSimpleName();
40
41    private static final int REQUEST_CODE_ACCOUNT_FILTER = 1;
42
43    private static final String KEY_SHORTCUT_ACTION = "shortcutAction";
44
45    private OnPhoneNumberPickerActionListener mListener;
46    private String mShortcutAction;
47
48    private ContactListFilter mFilter;
49
50    private View mAccountFilterHeader;
51    /**
52     * Lives as ListView's header and is shown when {@link #mAccountFilterHeader} is set
53     * to View.GONE.
54     */
55    private View mPaddingView;
56
57    private static final String KEY_FILTER = "filter";
58
59    /** true if the loader has started at least once. */
60    private boolean mLoaderStarted;
61
62    private boolean mUseCallableUri;
63
64    private ContactListItemView.PhotoPosition mPhotoPosition =
65            ContactListItemView.DEFAULT_PHOTO_POSITION;
66
67    private class FilterHeaderClickListener implements OnClickListener {
68        @Override
69        public void onClick(View view) {
70            AccountFilterUtil.startAccountFilterActivityForResult(
71                    PhoneNumberPickerFragment.this,
72                    REQUEST_CODE_ACCOUNT_FILTER,
73                    mFilter);
74        }
75    }
76    private OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener();
77
78    public PhoneNumberPickerFragment() {
79        setQuickContactEnabled(false);
80        setPhotoLoaderEnabled(true);
81        setSectionHeaderDisplayEnabled(true);
82        setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DATA_SHORTCUT);
83
84        // Show nothing instead of letting caller Activity show something.
85        setHasOptionsMenu(true);
86    }
87
88    public void setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener) {
89        this.mListener = listener;
90    }
91
92    @Override
93    protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
94        super.onCreateView(inflater, container);
95
96        View paddingView = inflater.inflate(R.layout.contact_detail_list_padding, null, false);
97        mPaddingView = paddingView.findViewById(R.id.contact_detail_list_padding);
98        getListView().addHeaderView(paddingView);
99
100        mAccountFilterHeader = getView().findViewById(R.id.account_filter_header_container);
101        mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
102        updateFilterHeaderView();
103
104        setVisibleScrollbarEnabled(!isLegacyCompatibilityMode());
105    }
106
107    @Override
108    protected void setSearchMode(boolean flag) {
109        super.setSearchMode(flag);
110        updateFilterHeaderView();
111    }
112
113    private void updateFilterHeaderView() {
114        final ContactListFilter filter = getFilter();
115        if (mAccountFilterHeader == null || filter == null) {
116            return;
117        }
118        final boolean shouldShowHeader =
119                !isSearchMode() &&
120                AccountFilterUtil.updateAccountFilterTitleForPhone(
121                        mAccountFilterHeader, filter, false);
122        if (shouldShowHeader) {
123            mPaddingView.setVisibility(View.GONE);
124            mAccountFilterHeader.setVisibility(View.VISIBLE);
125        } else {
126            mPaddingView.setVisibility(View.VISIBLE);
127            mAccountFilterHeader.setVisibility(View.GONE);
128        }
129    }
130
131    @Override
132    public void restoreSavedState(Bundle savedState) {
133        super.restoreSavedState(savedState);
134
135        if (savedState == null) {
136            return;
137        }
138
139        mFilter = savedState.getParcelable(KEY_FILTER);
140        mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION);
141    }
142
143    @Override
144    public void onSaveInstanceState(Bundle outState) {
145        super.onSaveInstanceState(outState);
146        outState.putParcelable(KEY_FILTER, mFilter);
147        outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction);
148    }
149
150    @Override
151    public boolean onOptionsItemSelected(MenuItem item) {
152        final int itemId = item.getItemId();
153        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
154            if (mListener != null) {
155                mListener.onHomeInActionBarSelected();
156            }
157            return true;
158        }
159        return super.onOptionsItemSelected(item);
160    }
161
162    /**
163     * @param shortcutAction either {@link Intent#ACTION_CALL} or
164     *            {@link Intent#ACTION_SENDTO} or null.
165     */
166    public void setShortcutAction(String shortcutAction) {
167        this.mShortcutAction = shortcutAction;
168    }
169
170    @Override
171    protected void onItemClick(int position, long id) {
172        final Uri phoneUri;
173        if (!isLegacyCompatibilityMode()) {
174            PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
175            phoneUri = adapter.getDataUri(position);
176
177        } else {
178            LegacyPhoneNumberListAdapter adapter = (LegacyPhoneNumberListAdapter) getAdapter();
179            phoneUri = adapter.getPhoneUri(position);
180        }
181
182        if (phoneUri != null) {
183            pickPhoneNumber(phoneUri);
184        } else {
185            Log.w(TAG, "Item at " + position + " was clicked before adapter is ready. Ignoring");
186        }
187    }
188
189    @Override
190    protected void startLoading() {
191        mLoaderStarted = true;
192        super.startLoading();
193    }
194
195    @Override
196    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
197        super.onLoadFinished(loader, data);
198
199        // disable scroll bar if there is no data
200        setVisibleScrollbarEnabled(data.getCount() > 0);
201    }
202
203    public void setUseCallableUri(boolean useCallableUri) {
204        mUseCallableUri = useCallableUri;
205    }
206
207    public boolean usesCallableUri() {
208        return mUseCallableUri;
209    }
210
211    @Override
212    protected ContactEntryListAdapter createListAdapter() {
213        if (!isLegacyCompatibilityMode()) {
214            PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
215            adapter.setDisplayPhotos(true);
216            adapter.setUseCallableUri(mUseCallableUri);
217            return adapter;
218        } else {
219            LegacyPhoneNumberListAdapter adapter = new LegacyPhoneNumberListAdapter(getActivity());
220            adapter.setDisplayPhotos(true);
221            return adapter;
222        }
223    }
224
225    @Override
226    protected void configureAdapter() {
227        super.configureAdapter();
228
229        final ContactEntryListAdapter adapter = getAdapter();
230        if (adapter == null) {
231            return;
232        }
233
234        if (!isSearchMode() && mFilter != null) {
235            adapter.setFilter(mFilter);
236        }
237
238        if (!isLegacyCompatibilityMode()) {
239            ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition);
240        }
241    }
242
243    @Override
244    protected View inflateView(LayoutInflater inflater, ViewGroup container) {
245        return inflater.inflate(R.layout.contact_list_content, null);
246    }
247
248    public void pickPhoneNumber(Uri uri) {
249        if (mShortcutAction == null) {
250            mListener.onPickPhoneNumberAction(uri);
251        } else {
252            if (isLegacyCompatibilityMode()) {
253                throw new UnsupportedOperationException();
254            }
255            ShortcutIntentBuilder builder = new ShortcutIntentBuilder(getActivity(), this);
256            builder.createPhoneNumberShortcutIntent(uri, mShortcutAction);
257        }
258    }
259
260    public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
261        mListener.onShortcutIntentCreated(shortcutIntent);
262    }
263
264    @Override
265    public void onPickerResult(Intent data) {
266        mListener.onPickPhoneNumberAction(data.getData());
267    }
268
269    @Override
270    public void onActivityResult(int requestCode, int resultCode, Intent data) {
271        if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) {
272            if (getActivity() != null) {
273                AccountFilterUtil.handleAccountFilterResult(
274                        ContactListFilterController.getInstance(getActivity()), resultCode, data);
275            } else {
276                Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()");
277            }
278        }
279    }
280
281    public ContactListFilter getFilter() {
282        return mFilter;
283    }
284
285    public void setFilter(ContactListFilter filter) {
286        if ((mFilter == null && filter == null) ||
287                (mFilter != null && mFilter.equals(filter))) {
288            return;
289        }
290
291        mFilter = filter;
292        if (mLoaderStarted) {
293            reloadData();
294        }
295        updateFilterHeaderView();
296    }
297
298    public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
299        mPhotoPosition = photoPosition;
300        if (!isLegacyCompatibilityMode()) {
301            final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
302            if (adapter != null) {
303                adapter.setPhotoPosition(photoPosition);
304            }
305        } else {
306            Log.w(TAG, "setPhotoPosition() is ignored in legacy compatibility mode.");
307        }
308    }
309}
310