1d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/*
2d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Copyright (C) 2010 The Android Open Source Project
3d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
4d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * you may not use this file except in compliance with the License.
6d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * You may obtain a copy of the License at
7d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
8d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
10d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Unless required by applicable law or agreed to in writing, software
11d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * See the License for the specific language governing permissions and
14d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * limitations under the License.
15d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */
16d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpackage com.android.contacts.common.list;
17d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
18d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.Context;
19d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.Cursor;
20d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.net.Uri;
21d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract;
22d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Contacts;
23d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Directory;
24b321f58e96516c007297492bc0e9287c9150b39cYorke Leeimport android.provider.ContactsContract.SearchSnippets;
25d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils;
26d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.View;
27d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.ViewGroup;
28d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.ListView;
29d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
306084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Leeimport com.android.contacts.common.ContactPhotoManager;
316084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Leeimport com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
32d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.R;
33495c732e471c1c68db91ca6e824440130fdb7146Yorke Leeimport com.android.contacts.common.preference.ContactsPreferences;
34d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
35d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/**
36d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type.
37d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Also includes support for including the {@link ContactsContract.Profile} record in the
38d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * list.
39d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */
40d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpublic abstract class ContactListAdapter extends ContactEntryListAdapter {
41d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
42d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected static class ContactQuery {
43d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] CONTACT_PROJECTION_PRIMARY = new String[] {
44d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
45d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_PRIMARY,          // 1
46d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
47d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
48d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
49d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
50d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
51d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
52d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
53d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
54d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] CONTACT_PROJECTION_ALTERNATIVE = new String[] {
55d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
56d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_ALTERNATIVE,      // 1
57d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
58d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
59d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
60d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
61d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
62d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
63d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
64d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
65d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] FILTER_PROJECTION_PRIMARY = new String[] {
66d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
67d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_PRIMARY,          // 1
68d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
69d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
70d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
71d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
72d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
73d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
74b321f58e96516c007297492bc0e9287c9150b39cYorke Lee            SearchSnippets.SNIPPET,           // 8
75d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
76d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
77d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] FILTER_PROJECTION_ALTERNATIVE = new String[] {
78d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
79d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_ALTERNATIVE,      // 1
80d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
81d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
82d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
83d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
84d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
85d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
86b321f58e96516c007297492bc0e9287c9150b39cYorke Lee            SearchSnippets.SNIPPET,           // 8
87d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
88d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
89d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_ID               = 0;
90d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_DISPLAY_NAME     = 1;
91d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_PRESENCE_STATUS  = 2;
92d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_CONTACT_STATUS   = 3;
93d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_PHOTO_ID         = 4;
94d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_PHOTO_URI        = 5;
95d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_LOOKUP_KEY       = 6;
96d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_IS_USER_PROFILE  = 7;
97d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_SNIPPET          = 8;
98d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
99d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
100d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private CharSequence mUnknownNameText;
101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
102d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private long mSelectedContactDirectoryId;
103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private String mSelectedContactLookupKey;
104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private long mSelectedContactId;
105e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    private ContactListItemView.PhotoPosition mPhotoPosition;
106d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
107d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public ContactListAdapter(Context context) {
108d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        super(context);
109d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
110d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mUnknownNameText = context.getText(R.string.missing_name);
111d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
112d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
113e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
114e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        mPhotoPosition = photoPosition;
115e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    }
116e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski
117e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    public ContactListItemView.PhotoPosition getPhotoPosition() {
118e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        return mPhotoPosition;
119e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    }
120e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski
121d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public CharSequence getUnknownNameText() {
122d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mUnknownNameText;
123d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
124d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
125d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public long getSelectedContactDirectoryId() {
126d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mSelectedContactDirectoryId;
127d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
128d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
129d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public String getSelectedContactLookupKey() {
130d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mSelectedContactLookupKey;
131d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
132d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
133d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public long getSelectedContactId() {
134d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mSelectedContactId;
135d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
136d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
137d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public void setSelectedContact(long selectedDirectoryId, String lookupKey, long contactId) {
138d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mSelectedContactDirectoryId = selectedDirectoryId;
139d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mSelectedContactLookupKey = lookupKey;
140d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mSelectedContactId = contactId;
141d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
142d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
143d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected static Uri buildSectionIndexerUri(Uri uri) {
144d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return uri.buildUpon()
145d9ba7ce0739281fc903ece843b5c84e10344adb3Yorke Lee                .appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true").build();
146d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
147d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
148d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
149d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public String getContactDisplayName(int position) {
150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return ((Cursor) getItem(position)).getString(ContactQuery.CONTACT_DISPLAY_NAME);
151d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
152d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
153d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * Builds the {@link Contacts#CONTENT_LOOKUP_URI} for the given
155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * {@link ListView} position.
156d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Uri getContactUri(int position) {
158d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionIndex = getPartitionForPosition(position);
159d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Cursor item = (Cursor)getItem(position);
160d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return item != null ? getContactUri(partitionIndex, item) : null;
161d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
162d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
163d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Uri getContactUri(int partitionIndex, Cursor cursor) {
164d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
165d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
166d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Uri uri = Contacts.getLookupUri(contactId, lookupKey);
167d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long directoryId = ((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId();
168d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (directoryId != Directory.DEFAULT) {
169d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            uri = uri.buildUpon().appendQueryParameter(
170d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build();
171d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return uri;
173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
174d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
175d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
176d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * Returns true if the specified contact is selected in the list. For a
177d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * contact to be shown as selected, we need both the directory and and the
178d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * lookup key to be the same. We are paying no attention to the contactId,
179d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * because it is volatile, especially in the case of directories.
180d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
181d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public boolean isSelectedContact(int partitionIndex, Cursor cursor) {
182d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long directoryId = ((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId();
183d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (getSelectedContactDirectoryId() != directoryId) {
184d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return false;
185d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
186d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        String lookupKey = getSelectedContactLookupKey();
187d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (lookupKey != null && TextUtils.equals(lookupKey,
188d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY))) {
189d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return true;
190d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
191d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
192d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return directoryId != Directory.DEFAULT && directoryId != Directory.LOCAL_INVISIBLE
193d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                && getSelectedContactId() == cursor.getLong(ContactQuery.CONTACT_ID);
194d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
195d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
196d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
1971f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee    protected ContactListItemView newView(
1981f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee            Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
1991f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee        ContactListItemView view = super.newView(context, partition, cursor, position, parent);
200d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.setUnknownNameText(mUnknownNameText);
201d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.setQuickContactEnabled(isQuickContactEnabled());
202fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee        view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled());
203d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.setActivatedStateSupported(isSelectionVisible());
204e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        if (mPhotoPosition != null) {
205e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski            view.setPhotoPosition(mPhotoPosition);
206e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        }
207d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return view;
208d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
210d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindSectionHeaderAndDivider(ContactListItemView view, int position,
211d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Cursor cursor) {
21283ee19795e9e017da83a2c0cf2ecfd0b12d0b7b3Yorke Lee        view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
213d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (isSectionHeaderDisplayEnabled()) {
214d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Placement placement = getItemPlacementInSection(position);
215d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            view.setSectionHeader(placement.sectionHeader);
216d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } else {
217d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            view.setSectionHeader(null);
218d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
219d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
220d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) {
222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (!isPhotoSupported(partitionIndex)) {
223d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            view.removePhotoView();
224d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return;
225d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
226d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
227d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // Set the photo, if available
228d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long photoId = 0;
229d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (!cursor.isNull(ContactQuery.CONTACT_PHOTO_ID)) {
230d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            photoId = cursor.getLong(ContactQuery.CONTACT_PHOTO_ID);
231d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
232d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
233d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (photoId != 0) {
2343f9c2f426058413055fa54c08c69ad9461717658Yorke Lee            getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false,
2353f9c2f426058413055fa54c08c69ad9461717658Yorke Lee                    getCircularPhotos(), null);
236d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } else {
237d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI);
238d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
2396084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            DefaultImageRequest request = null;
2406084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            if (photoUri == null) {
2413f9c2f426058413055fa54c08c69ad9461717658Yorke Lee                request = getDefaultImageRequestFromCursor(cursor,
2423f9c2f426058413055fa54c08c69ad9461717658Yorke Lee                        ContactQuery.CONTACT_DISPLAY_NAME,
2433f9c2f426058413055fa54c08c69ad9461717658Yorke Lee                        ContactQuery.CONTACT_LOOKUP_KEY);
2446084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            }
2453f9c2f426058413055fa54c08c69ad9461717658Yorke Lee            getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, false,
2463f9c2f426058413055fa54c08c69ad9461717658Yorke Lee                    getCircularPhotos(), request);
247d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
248d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
249d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
2504cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell    protected void bindNameAndViewId(final ContactListItemView view, Cursor cursor) {
251d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.showDisplayName(
252d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                cursor, ContactQuery.CONTACT_DISPLAY_NAME, getContactNameDisplayOrder());
253d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // Note: we don't show phonetic any more (See issue 5265330)
2544cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell
2554cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell        bindViewId(view, cursor, ContactQuery.CONTACT_ID);
256d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
257d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
258d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindPresenceAndStatusMessage(final ContactListItemView view, Cursor cursor) {
259d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.showPresenceAndStatusMessage(cursor, ContactQuery.CONTACT_PRESENCE_STATUS,
260d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                ContactQuery.CONTACT_CONTACT_STATUS);
261d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
262d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
263d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
264d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.showSnippet(cursor, ContactQuery.CONTACT_SNIPPET);
265d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
266d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
267d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public int getSelectedContactPosition() {
268d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (mSelectedContactLookupKey == null && mSelectedContactId == 0) {
269d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
270d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
271d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
272d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Cursor cursor = null;
273d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionIndex = -1;
274d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionCount = getPartitionCount();
275d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        for (int i = 0; i < partitionCount; i++) {
276d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            DirectoryPartition partition = (DirectoryPartition) getPartition(i);
277d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (partition.getDirectoryId() == mSelectedContactDirectoryId) {
278d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                partitionIndex = i;
279d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                break;
280d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
281d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
282d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (partitionIndex == -1) {
283d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
284d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
285d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
286d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        cursor = getCursor(partitionIndex);
287d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (cursor == null) {
288d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
289d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
290d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
291d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        cursor.moveToPosition(-1);      // Reset cursor
292d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int offset = -1;
293d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        while (cursor.moveToNext()) {
294d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (mSelectedContactLookupKey != null) {
295d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
296d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                if (mSelectedContactLookupKey.equals(lookupKey)) {
297d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    offset = cursor.getPosition();
298d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    break;
299d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                }
300d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
301d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (mSelectedContactId != 0 && (mSelectedContactDirectoryId == Directory.DEFAULT
302d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    || mSelectedContactDirectoryId == Directory.LOCAL_INVISIBLE)) {
303d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
304d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                if (contactId == mSelectedContactId) {
305d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    offset = cursor.getPosition();
306d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    break;
307d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                }
308d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
309d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
310d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (offset == -1) {
311d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
312d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
313d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
314d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int position = getPositionForPartition(partitionIndex) + offset;
315d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (hasHeader(partitionIndex)) {
316d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            position++;
317d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
318d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return position;
319d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
320d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
321d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public boolean hasValidSelection() {
322d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return getSelectedContactPosition() != -1;
323d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
324d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
325d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Uri getFirstContactUri() {
326d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionCount = getPartitionCount();
327d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        for (int i = 0; i < partitionCount; i++) {
328d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            DirectoryPartition partition = (DirectoryPartition) getPartition(i);
329d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (partition.isLoading()) {
330d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                continue;
331d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
332d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
333d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Cursor cursor = getCursor(i);
334d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (cursor == null) {
335d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                continue;
336d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
337d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
338d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (!cursor.moveToFirst()) {
339d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                continue;
340d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
341d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
342d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return getContactUri(i, cursor);
343d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
345d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return null;
346d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
347d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
348d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
349d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public void changeCursor(int partitionIndex, Cursor cursor) {
350d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        super.changeCursor(partitionIndex, cursor);
351d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // Check if a profile exists
353d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (cursor != null && cursor.getCount() > 0) {
354d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            cursor.moveToFirst();
355d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            setProfileExists(cursor.getInt(ContactQuery.CONTACT_IS_USER_PROFILE) == 1);
356d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
357d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
358d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
359d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
360d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * @return Projection useful for children.
361d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
362d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected final String[] getProjection(boolean forSearch) {
363d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        final int sortOrder = getContactNameDisplayOrder();
364d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (forSearch) {
365495c732e471c1c68db91ca6e824440130fdb7146Yorke Lee            if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
366d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.FILTER_PROJECTION_PRIMARY;
367d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            } else {
368d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.FILTER_PROJECTION_ALTERNATIVE;
369d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
370d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } else {
371495c732e471c1c68db91ca6e824440130fdb7146Yorke Lee            if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
372d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.CONTACT_PROJECTION_PRIMARY;
373d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            } else {
374d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.CONTACT_PROJECTION_ALTERNATIVE;
375d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
376d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
377d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
378d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng}
379