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;
36e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
376e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov/**
3859fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikov * Fragment for the Join Contact list.
396e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov */
40e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovpublic class JoinContactListFragment extends ContactEntryListFragment<JoinContactListAdapter> {
41e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
42e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov    private static final int DISPLAY_NAME_LOADER = -2;
43e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
44a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa    private static final String KEY_TARGET_CONTACT_ID = "targetContactId";
45d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov
46e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private OnContactPickerActionListener mListener;
47e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private long mTargetContactId;
48e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
49a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa    private final LoaderCallbacks<Cursor> mLoaderCallbacks = new LoaderCallbacks<Cursor>() {
50e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov
51e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        @Override
52e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
53e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov            switch (id) {
54e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                case DISPLAY_NAME_LOADER: {
55e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    // Loader for the display name of the target contact
56e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    return new CursorLoader(getActivity(),
57e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                            ContentUris.withAppendedId(Contacts.CONTENT_URI, mTargetContactId),
58e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                            new String[] { Contacts.DISPLAY_NAME }, null, null, null);
59e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                }
60e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                case JoinContactListAdapter.PARTITION_ALL_CONTACTS: {
61e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    JoinContactLoader loader = new JoinContactLoader(getActivity());
62e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    JoinContactListAdapter adapter = getAdapter();
63e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    if (adapter != null) {
64e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                        adapter.configureLoader(loader, 0);
65e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    }
66e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    return loader;
67e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                }
68e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov            }
69e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov            throw new IllegalArgumentException("No loader for ID=" + id);
70e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        }
71e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov
72e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        @Override
73e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
74e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov            switch (loader.getId()) {
75e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                case DISPLAY_NAME_LOADER: {
76e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    if (data != null && data.moveToFirst()) {
77e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                        showTargetContactName(data.getString(0));
78e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    }
79e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    break;
80e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                }
81e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                case JoinContactListAdapter.PARTITION_ALL_CONTACTS: {
8214ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki                    Cursor suggestionsCursor = ((JoinContactLoaderResult) data).suggestionCursor;
83d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov                    onContactListLoaded(suggestionsCursor, data);
84e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                    break;
85e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                }
86e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov            }
87e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        }
88d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov
8914ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki        @Override
904ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn        public void onLoaderReset(Loader<Cursor> loader) {
914ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn        }
92e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov    };
93e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov
94e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public JoinContactListFragment() {
95e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        setPhotoLoaderEnabled(true);
96e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        setSectionHeaderDisplayEnabled(true);
975245ea63b4cca18ee504b27abd534fc13d33dea9Dmitri Plotnikov        setVisibleScrollbarEnabled(false);
98b22ca30163f5f99f07b906c20fd1a798541448a5Dmitri Plotnikov        setQuickContactEnabled(false);
99e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
100e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
101e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void setOnContactPickerActionListener(OnContactPickerActionListener listener) {
102e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        mListener = listener;
103e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
104e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
105e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
106fec29c7320c6c45aff69dbd6ec0edb267fb402f4Daniel Lehmann    protected void startLoading() {
1074e0ce3fb44125453e0ad723d7e3d3e89ad639e01Dmitri Plotnikov        configureAdapter();
1084e0ce3fb44125453e0ad723d7e3d3e89ad639e01Dmitri Plotnikov
109e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov        getLoaderManager().initLoader(DISPLAY_NAME_LOADER, null, mLoaderCallbacks);
110ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa
111ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa        // When this method is called, Uri to be used may be changed. We should use restartLoader()
112ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa        // to load the parameter again.
113ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa        getLoaderManager().restartLoader(JoinContactListAdapter.PARTITION_ALL_CONTACTS,
114e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov                null, mLoaderCallbacks);
115e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
116e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
117a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa    private void onContactListLoaded(Cursor suggestionsCursor, Cursor allContactsCursor) {
118d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        JoinContactListAdapter adapter = getAdapter();
119d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        adapter.setSuggestionsCursor(suggestionsCursor);
120a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa        setVisibleScrollbarEnabled(true);
121a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa        onPartitionLoaded(JoinContactListAdapter.PARTITION_ALL_CONTACTS, allContactsCursor);
122d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    }
123d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov
124e2bbe1db7e21e5c1ade79dd2dc74216f82b65e01Dmitri Plotnikov    private void showTargetContactName(String displayName) {
125e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        Activity activity = getActivity();
126a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa        TextView blurbView = (TextView) activity.findViewById(R.id.join_contact_blurb);
127e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        String blurb = activity.getString(R.string.blurbJoinContactDataWith, displayName);
128e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        blurbView.setText(blurb);
129e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
130e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
131e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void setTargetContactId(long targetContactId) {
132e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        mTargetContactId = targetContactId;
133e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
134e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
135e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
136e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public JoinContactListAdapter createListAdapter() {
137e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return new JoinContactListAdapter(getActivity());
138e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
1396e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1406e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
141e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    protected void configureAdapter() {
142e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        super.configureAdapter();
143e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        JoinContactListAdapter adapter = getAdapter();
144e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        adapter.setTargetContactId(mTargetContactId);
1456e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
1466e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1476e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
14859fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikov    protected View inflateView(LayoutInflater inflater, ViewGroup container) {
149d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        return inflater.inflate(R.layout.join_contact_picker_list_content, null);
1506e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
151caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikov
152caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikov    @Override
15359fb48e7e6a37f26901ad5a4996947dcd25a73d9Dmitri Plotnikov    protected void onItemClick(int position, long id) {
154097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann        final Uri contactUri = getAdapter().getContactUri(position);
155097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann        if (contactUri != null) mListener.onPickContactAction(contactUri);
156caf498bd71e2ab4b6771cfa17453dd827041f238Dmitri Plotnikov    }
157e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov
158e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov    @Override
159e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov    public void onPickerResult(Intent data) {
160097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann        final Uri contactUri = data.getData();
161097b10bbd1a2bc110556ec928db4568493a5d21eDaniel Lehmann        if (contactUri != null) mListener.onPickContactAction(contactUri);
162e8a9517483cfa0c4d521b834d872a8cb05482badDmitri Plotnikov    }
163d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov
164d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    @Override
165d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    public void onSaveInstanceState(Bundle outState) {
166d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        super.onSaveInstanceState(outState);
167a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa        outState.putLong(KEY_TARGET_CONTACT_ID, mTargetContactId);
168d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    }
169d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov
170d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    @Override
171d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    public void restoreSavedState(Bundle savedState) {
172d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        super.restoreSavedState(savedState);
173d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        if (savedState != null) {
174a8729cdf778f9ca927b06afde685f7ac6b8c917fDaisuke Miyakawa            mTargetContactId = savedState.getLong(KEY_TARGET_CONTACT_ID);
175d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov        }
176d8f84e076b762f063ae498c297d6f02574099dd2Dmitri Plotnikov    }
177ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa
178ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa    @Override
179ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa    public void setQueryString(String queryString, boolean delaySelection) {
180ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa        super.setQueryString(queryString, delaySelection);
181ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa
182ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa        setSearchMode(!TextUtils.isEmpty(queryString));
183ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa    }
1846e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov}
185