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.content.CursorLoader; 2080f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chenimport android.content.res.Resources; 21d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.Cursor; 22d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.net.Uri; 23d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.os.Bundle; 24d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract; 25d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Contacts; 26dc08a7cd1fc867826f4620203898847e9b27fd2dYorke Leeimport android.provider.ContactsContract.Data; 27d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Directory; 28d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils; 29d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.util.Log; 30d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.LayoutInflater; 31d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.View; 32d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.ViewGroup; 33d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.QuickContactBadge; 34d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.SectionIndexer; 35d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.TextView; 36d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 37d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.ContactPhotoManager; 386084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Leeimport com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; 39d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.R; 40cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Chengimport com.android.contacts.common.util.SearchUtil; 41d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 42d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport java.util.HashSet; 43d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 44d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/** 45d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Common base class for various contact-related lists, e.g. contact list, phone number list 46d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * etc. 47d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 48d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpublic abstract class ContactEntryListAdapter extends IndexerListAdapter { 49d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 50d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private static final String TAG = "ContactEntryListAdapter"; 51d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 52d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 53d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Indicates whether the {@link Directory#LOCAL_INVISIBLE} directory should 54d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * be included in the search. 55d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 56d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public static final boolean LOCAL_INVISIBLE_DIRECTORY_ENABLED = false; 57d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 58d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDisplayOrder; 59d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mSortOrder; 60d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 61d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mDisplayPhotos; 623f9c2f426058413055fa54c08c69ad9461717658Yorke Lee private boolean mCircularPhotos = true; 63d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mQuickContactEnabled; 64fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee private boolean mAdjustSelectionBoundsEnabled; 65d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 66d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 67d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * indicates if contact queries include profile 68d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 69d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mIncludeProfile; 70d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 71d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 72d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * indicates if query results includes a profile 73d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 74d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mProfileExists; 75d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 76c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell /** 77c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell * The root view of the fragment that this adapter is associated with. 78c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell */ 79c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell private View mFragmentRootView; 80c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell 81d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ContactPhotoManager mPhotoLoader; 82d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 83d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private String mQueryString; 84bd80fd64b9ff94c9ffbdb843beb4b363bb209463Chiao Cheng private String mUpperCaseQueryString; 85d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mSearchMode; 86d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDirectorySearchMode; 87d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private int mDirectoryResultLimit = Integer.MAX_VALUE; 88d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 89d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mEmptyListEnabled = true; 90d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 91d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mSelectionVisible; 92d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 93d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private ContactListFilter mFilter; 94d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private boolean mDarkTheme = false; 95d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 96d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** Resource used to provide header-text for default filter. */ 97d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private CharSequence mDefaultFilterHeaderText; 98d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 99d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ContactEntryListAdapter(Context context) { 100d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super(context); 101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setDefaultFilterHeaderText(R.string.local_search_label); 10288bc23f8e6a823415ef269fc523ce81e828468b6Yorke Lee addPartitions(); 103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 105c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell /** 106c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell * @param fragmentRootView Root view of the fragment. This is used to restrict the scope of 107c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell * image loading requests that get cancelled on cursor changes. 108c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell */ 109c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell protected void setFragmentRootView(View fragmentRootView) { 110c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell mFragmentRootView = fragmentRootView; 111c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell } 112c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell 113d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void setDefaultFilterHeaderText(int resourceId) { 114d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDefaultFilterHeaderText = getContext().getResources().getText(resourceId); 115d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 116d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 117d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 1181f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee protected ContactListItemView newView( 1191f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee Context context, int partition, Cursor cursor, int position, ViewGroup parent) { 1201f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee final ContactListItemView view = new ContactListItemView(context, null); 1211f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled()); 122fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled()); 1231f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee return view; 1241f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee } 1251f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee 1261f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee @Override 127aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell protected void bindView(View itemView, int partition, Cursor cursor, int position) { 128aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell final ContactListItemView view = (ContactListItemView) itemView; 129aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled()); 130aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell } 131aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell 132aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell @Override 133d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected View createPinnedSectionHeaderView(Context context, ViewGroup parent) { 13453c7dc1e9691b5b427395642a4274d37a1a15bb4Yorke Lee return new ContactListPinnedHeaderView(context, null, parent); 135d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 136d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 137d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 138d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void setPinnedSectionTitle(View pinnedHeaderView, String title) { 1391f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee ((ContactListPinnedHeaderView) pinnedHeaderView).setSectionHeaderTitle(title); 140d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 141d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 142d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void addPartitions() { 143d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addPartition(createDefaultDirectoryPartition()); 144d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 145d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 146d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected DirectoryPartition createDefaultDirectoryPartition() { 147d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng DirectoryPartition partition = new DirectoryPartition(true, true); 148d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setDirectoryId(Directory.DEFAULT); 149d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setDirectoryType(getContext().getString(R.string.contactsList)); 150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setPriorityDirectory(true); 151d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setPhotoSupported(true); 15288bc23f8e6a823415ef269fc523ce81e828468b6Yorke Lee partition.setLabel(mDefaultFilterHeaderText.toString()); 153d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return partition; 154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 156d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Remove all directories after the default directory. This is typically used when contacts 158d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * list screens are asked to exit the search mode and thus need to remove all remote directory 159d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * results for the search. 160d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * 161d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * This code assumes that the default directory and directories before that should not be 162d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * deleted (e.g. Join screen has "suggested contacts" directory before the default director, 163d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * and we should not remove the directory). 164d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 165d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void removeDirectoriesAfterDefault() { 166d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final int partitionCount = getPartitionCount(); 167d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = partitionCount - 1; i >= 0; i--) { 168d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final Partition partition = getPartition(i); 169d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if ((partition instanceof DirectoryPartition) 170d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng && ((DirectoryPartition) partition).getDirectoryId() == Directory.DEFAULT) { 171d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng break; 172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removePartition(i); 174d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 175d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 176d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 177d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 178ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad protected int getPartitionByDirectoryId(long id) { 179d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 180d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = 0; i < count; i++) { 181d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(i); 182d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition) { 183d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (((DirectoryPartition)partition).getDirectoryId() == id) { 184d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return i; 185d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 186d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 187d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 188d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return -1; 189d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 190d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 191ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad protected DirectoryPartition getDirectoryById(long id) { 192ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad int count = getPartitionCount(); 193ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad for (int i = 0; i < count; i++) { 194ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad Partition partition = getPartition(i); 195ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (partition instanceof DirectoryPartition) { 196ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final DirectoryPartition directoryPartition = (DirectoryPartition) partition; 197ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (directoryPartition.getDirectoryId() == id) { 198ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return directoryPartition; 199ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 200ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 201ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 202ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return null; 203ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 204ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 205d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public abstract String getContactDisplayName(int position); 206d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public abstract void configureLoader(CursorLoader loader, long directoryId); 207d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 208d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Marks all partitions as "loading" 210d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 211d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void onDataReload() { 212d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng boolean notify = false; 213d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 214d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = 0; i < count; i++) { 215d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(i); 216d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition) { 217d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng DirectoryPartition directoryPartition = (DirectoryPartition)partition; 218d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!directoryPartition.isLoading()) { 219d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng notify = true; 220d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng directoryPartition.setStatus(DirectoryPartition.STATUS_NOT_LOADED); 222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 223d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 224d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (notify) { 225d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng notifyDataSetChanged(); 226d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 227d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 228d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 229d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 230d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void clearPartitions() { 231d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 232d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = 0; i < count; i++) { 233d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(i); 234d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition) { 235d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng DirectoryPartition directoryPartition = (DirectoryPartition)partition; 236d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng directoryPartition.setStatus(DirectoryPartition.STATUS_NOT_LOADED); 237d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 238d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 239d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.clearPartitions(); 240d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 241d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 242d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isSearchMode() { 243d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mSearchMode; 244d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 245d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 246d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSearchMode(boolean flag) { 247d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSearchMode = flag; 248d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 249d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 250d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public String getQueryString() { 251d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mQueryString; 252d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 253d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 254d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setQueryString(String queryString) { 255d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQueryString = queryString; 256d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (TextUtils.isEmpty(queryString)) { 257d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mUpperCaseQueryString = null; 258d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 259cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng mUpperCaseQueryString = SearchUtil 260cae605bed4d43e1925fc8c1803def0ef1d0924a5Chiao Cheng .cleanStartAndEndOfSearchQuery(queryString.toUpperCase()) ; 261d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 262d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 263d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 264bd80fd64b9ff94c9ffbdb843beb4b363bb209463Chiao Cheng public String getUpperCaseQueryString() { 265d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mUpperCaseQueryString; 266d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 267d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 268d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public int getDirectorySearchMode() { 269d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDirectorySearchMode; 270d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 271d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 272d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setDirectorySearchMode(int mode) { 273d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDirectorySearchMode = mode; 274d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 275d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 276d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public int getDirectoryResultLimit() { 277d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDirectoryResultLimit; 278d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 279d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 280ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad public int getDirectoryResultLimit(DirectoryPartition directoryPartition) { 281ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final int limit = directoryPartition.getResultLimit(); 282ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return limit == DirectoryPartition.RESULT_LIMIT_DEFAULT ? mDirectoryResultLimit : limit; 283ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 284ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 285d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setDirectoryResultLimit(int limit) { 286d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng this.mDirectoryResultLimit = limit; 287d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 288d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 289d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public int getContactNameDisplayOrder() { 290d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDisplayOrder; 291d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 292d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 293d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setContactNameDisplayOrder(int displayOrder) { 294d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDisplayOrder = displayOrder; 295d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 296d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 297d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public int getSortOrder() { 298d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mSortOrder; 299d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 300d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 301d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSortOrder(int sortOrder) { 302d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mSortOrder = sortOrder; 303d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 304d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 305d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setPhotoLoader(ContactPhotoManager photoLoader) { 306d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoLoader = photoLoader; 307d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 308d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 309d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected ContactPhotoManager getPhotoLoader() { 310d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mPhotoLoader; 311d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 312d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 313d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean getDisplayPhotos() { 314d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mDisplayPhotos; 315d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 316d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 317d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setDisplayPhotos(boolean displayPhotos) { 318d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDisplayPhotos = displayPhotos; 319d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 320d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 3213f9c2f426058413055fa54c08c69ad9461717658Yorke Lee public boolean getCircularPhotos() { 3223f9c2f426058413055fa54c08c69ad9461717658Yorke Lee return mCircularPhotos; 3233f9c2f426058413055fa54c08c69ad9461717658Yorke Lee } 3243f9c2f426058413055fa54c08c69ad9461717658Yorke Lee 3253f9c2f426058413055fa54c08c69ad9461717658Yorke Lee public void setCircularPhotos(boolean circularPhotos) { 3263f9c2f426058413055fa54c08c69ad9461717658Yorke Lee mCircularPhotos = circularPhotos; 3273f9c2f426058413055fa54c08c69ad9461717658Yorke Lee } 3283f9c2f426058413055fa54c08c69ad9461717658Yorke Lee 329d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isEmptyListEnabled() { 330d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mEmptyListEnabled; 331d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 332d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 333d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setEmptyListEnabled(boolean flag) { 334d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mEmptyListEnabled = flag; 335d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 336d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 337d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isSelectionVisible() { 338d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mSelectionVisible; 339d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 340d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 341d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setSelectionVisible(boolean flag) { 342d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng this.mSelectionVisible = flag; 343d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 345d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isQuickContactEnabled() { 346d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mQuickContactEnabled; 347d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 348d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 349d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setQuickContactEnabled(boolean quickContactEnabled) { 350d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mQuickContactEnabled = quickContactEnabled; 351d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 353fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee public boolean isAdjustSelectionBoundsEnabled() { 354fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee return mAdjustSelectionBoundsEnabled; 355fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee } 356fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee 357fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee public void setAdjustSelectionBoundsEnabled(boolean enabled) { 358fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee mAdjustSelectionBoundsEnabled = enabled; 359fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee } 360fc9221ef57bfb9311dda798f67030d40215be859Andrew Lee 361d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean shouldIncludeProfile() { 362d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mIncludeProfile; 363d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 364d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 365d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setIncludeProfile(boolean includeProfile) { 366d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mIncludeProfile = includeProfile; 367d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 368d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 369d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setProfileExists(boolean exists) { 370d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mProfileExists = exists; 371d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Stick the "ME" header for the profile 372d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (exists) { 373d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng SectionIndexer indexer = getIndexer(); 374d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (indexer != null) { 375d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ((ContactsSectionIndexer) indexer).setProfileHeader( 376d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getContext().getString(R.string.user_profile_contacts_list_header)); 377d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 378d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 379d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 380d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 381d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean hasProfile() { 382d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mProfileExists; 383d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 384d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 385d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setDarkTheme(boolean value) { 386d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mDarkTheme = value; 387d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 388d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 389d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 390d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Updates partitions according to the directory meta-data contained in the supplied 391d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * cursor. 392d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 393d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void changeDirectories(Cursor cursor) { 394d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (cursor.getCount() == 0) { 395d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Directory table must have at least local directory, without which this adapter will 396d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // enter very weird state. 397d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Log.e(TAG, "Directory search loader returned an empty cursor, which implies we have " + 398d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng "no directory entries.", new RuntimeException()); 399d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return; 400d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 401d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng HashSet<Long> directoryIds = new HashSet<Long>(); 402d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 403d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int idColumnIndex = cursor.getColumnIndex(Directory._ID); 404d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int directoryTypeColumnIndex = cursor.getColumnIndex(DirectoryListLoader.DIRECTORY_TYPE); 405d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int displayNameColumnIndex = cursor.getColumnIndex(Directory.DISPLAY_NAME); 406d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int photoSupportColumnIndex = cursor.getColumnIndex(Directory.PHOTO_SUPPORT); 407d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 408d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TODO preserve the order of partition to match those of the cursor 409d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Phase I: add new directories 410d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng cursor.moveToPosition(-1); 411d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng while (cursor.moveToNext()) { 412d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng long id = cursor.getLong(idColumnIndex); 413d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng directoryIds.add(id); 414d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (getPartitionByDirectoryId(id) == -1) { 415d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng DirectoryPartition partition = new DirectoryPartition(false, true); 416d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setDirectoryId(id); 417768324c2d917f9ce79747007c57efcefbc06b472Alon Albert if (isRemoteDirectory(id)) { 418768324c2d917f9ce79747007c57efcefbc06b472Alon Albert partition.setLabel(mContext.getString(R.string.directory_search_label)); 419768324c2d917f9ce79747007c57efcefbc06b472Alon Albert } else { 420768324c2d917f9ce79747007c57efcefbc06b472Alon Albert partition.setLabel(mDefaultFilterHeaderText.toString()); 421768324c2d917f9ce79747007c57efcefbc06b472Alon Albert } 422d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setDirectoryType(cursor.getString(directoryTypeColumnIndex)); 423d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setDisplayName(cursor.getString(displayNameColumnIndex)); 424d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int photoSupport = cursor.getInt(photoSupportColumnIndex); 425d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng partition.setPhotoSupported(photoSupport == Directory.PHOTO_SUPPORT_THUMBNAIL_ONLY 426d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng || photoSupport == Directory.PHOTO_SUPPORT_FULL); 427d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng addPartition(partition); 428d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 429d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 430d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 431d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Phase II: remove deleted directories 432d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 433d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = count; --i >= 0; ) { 434d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(i); 435d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition) { 436d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng long id = ((DirectoryPartition)partition).getDirectoryId(); 437d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!directoryIds.contains(id)) { 438d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng removePartition(i); 439d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 440d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 441d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 442d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 443d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng invalidate(); 444d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng notifyDataSetChanged(); 445d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 446d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 447d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 448d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void changeCursor(int partitionIndex, Cursor cursor) { 449d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partitionIndex >= getPartitionCount()) { 450d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // There is no partition for this data 451d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return; 452d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 453d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 454d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(partitionIndex); 455d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition) { 456d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ((DirectoryPartition)partition).setStatus(DirectoryPartition.STATUS_LOADED); 457d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 458d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 459d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (mDisplayPhotos && mPhotoLoader != null && isPhotoSupported(partitionIndex)) { 460d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mPhotoLoader.refreshCache(); 461d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 462d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 463d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng super.changeCursor(partitionIndex, cursor); 464d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 465d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (isSectionHeaderDisplayEnabled() && partitionIndex == getIndexedPartition()) { 466d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng updateIndexer(cursor); 467d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 468353068614111bd79ac92e0ae98af433868ba3fb3Tyler Gunn 469353068614111bd79ac92e0ae98af433868ba3fb3Tyler Gunn // When the cursor changes, cancel any pending asynchronous photo loads. 470c3f21a33fa554f683ddbe6d9553d1b3bd9a4fd29Brian Attwell mPhotoLoader.cancelPendingRequests(mFragmentRootView); 471d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 472d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 473d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void changeCursor(Cursor cursor) { 474d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng changeCursor(0, cursor); 475d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 476d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 477d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 478d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Updates the indexer, which is used to produce section headers. 479d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 480d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng private void updateIndexer(Cursor cursor) { 481d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (cursor == null) { 482d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setIndexer(null); 483d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return; 484d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 485d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 486d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Bundle bundle = cursor.getExtras(); 487dc08a7cd1fc867826f4620203898847e9b27fd2dYorke Lee if (bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES) && 488dc08a7cd1fc867826f4620203898847e9b27fd2dYorke Lee bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS)) { 489d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String sections[] = 490dc08a7cd1fc867826f4620203898847e9b27fd2dYorke Lee bundle.getStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES); 491dc08a7cd1fc867826f4620203898847e9b27fd2dYorke Lee int counts[] = bundle.getIntArray( 492dc08a7cd1fc867826f4620203898847e9b27fd2dYorke Lee Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS); 4930631174430c169d84675123346797654f4e62b5cBrian Attwell 4940631174430c169d84675123346797654f4e62b5cBrian Attwell if (getExtraStartingSection()) { 4950631174430c169d84675123346797654f4e62b5cBrian Attwell // Insert an additional unnamed section at the top of the list. 4960631174430c169d84675123346797654f4e62b5cBrian Attwell String allSections[] = new String[sections.length + 1]; 4970631174430c169d84675123346797654f4e62b5cBrian Attwell int allCounts[] = new int[counts.length + 1]; 4980631174430c169d84675123346797654f4e62b5cBrian Attwell for (int i = 0; i < sections.length; i++) { 4990631174430c169d84675123346797654f4e62b5cBrian Attwell allSections[i + 1] = sections[i]; 5000631174430c169d84675123346797654f4e62b5cBrian Attwell allCounts[i + 1] = counts[i]; 5010631174430c169d84675123346797654f4e62b5cBrian Attwell } 5020631174430c169d84675123346797654f4e62b5cBrian Attwell allCounts[0] = 1; 5030631174430c169d84675123346797654f4e62b5cBrian Attwell allSections[0] = ""; 5040631174430c169d84675123346797654f4e62b5cBrian Attwell setIndexer(new ContactsSectionIndexer(allSections, allCounts)); 5050631174430c169d84675123346797654f4e62b5cBrian Attwell } else { 5060631174430c169d84675123346797654f4e62b5cBrian Attwell setIndexer(new ContactsSectionIndexer(sections, counts)); 5070631174430c169d84675123346797654f4e62b5cBrian Attwell } 508d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 509d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setIndexer(null); 510d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 511d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 512d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 5130631174430c169d84675123346797654f4e62b5cBrian Attwell protected boolean getExtraStartingSection() { 5140631174430c169d84675123346797654f4e62b5cBrian Attwell return false; 5150631174430c169d84675123346797654f4e62b5cBrian Attwell } 5160631174430c169d84675123346797654f4e62b5cBrian Attwell 517d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 518d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public int getViewTypeCount() { 519d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // We need a separate view type for each item type, plus another one for 520d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // each type with header, plus one for "other". 521d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return getItemViewTypeCount() * 2 + 1; 522d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 523d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 524d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 525d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public int getItemViewType(int partitionIndex, int position) { 526d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int type = super.getItemViewType(partitionIndex, position); 527d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!isUserProfile(position) 528d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng && isSectionHeaderDisplayEnabled() 529d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng && partitionIndex == getIndexedPartition()) { 530d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Placement placement = getItemPlacementInSection(position); 531d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return placement.firstInSection ? type : getItemViewTypeCount() + type; 532d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 533d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return type; 534d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 535d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 536d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 537d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 538d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isEmpty() { 539d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TODO 540d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng// if (contactsListActivity.mProviderStatus != ProviderStatus.STATUS_NORMAL) { 541d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng// return true; 542d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng// } 543d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 544d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!mEmptyListEnabled) { 545d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return false; 546d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else if (isSearchMode()) { 547d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return TextUtils.isEmpty(getQueryString()); 548d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 549d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return super.isEmpty(); 550d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 551d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 552d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 553d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isLoading() { 554d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 555d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = 0; i < count; i++) { 556d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(i); 557d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition 558d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng && ((DirectoryPartition) partition).isLoading()) { 559d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return true; 560d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 561d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 562d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return false; 563d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 564d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 565d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean areAllPartitionsEmpty() { 566d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 567d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = 0; i < count; i++) { 568d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!isPartitionEmpty(i)) { 569d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return false; 570d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 571d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 572d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return true; 573d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 574d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 575d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 576d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Changes visibility parameters for the default directory partition. 577d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 578d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void configureDefaultPartition(boolean showIfEmpty, boolean hasHeader) { 579d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int defaultPartitionIndex = -1; 580d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int count = getPartitionCount(); 581d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng for (int i = 0; i < count; i++) { 582d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(i); 583d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition && 584d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ((DirectoryPartition)partition).getDirectoryId() == Directory.DEFAULT) { 585d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng defaultPartitionIndex = i; 586d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng break; 587d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 588d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 589d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (defaultPartitionIndex != -1) { 590d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setShowIfEmpty(defaultPartitionIndex, showIfEmpty); 591d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng setHasHeader(defaultPartitionIndex, hasHeader); 592d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 593d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 594d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 595d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 596d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected View newHeaderView(Context context, int partition, Cursor cursor, 597d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ViewGroup parent) { 598d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng LayoutInflater inflater = LayoutInflater.from(context); 5992cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell View view = inflater.inflate(R.layout.directory_header, parent, false); 6002cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell if (!getPinnedPartitionHeadersEnabled()) { 6012cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell // If the headers are unpinned, there is no need for their background 6022cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell // color to be non-transparent. Setting this transparent reduces maintenance for 6032cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell // non-pinned headers. We don't need to bother synchronizing the activity's 6042cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell // background color with the header background color. 6052cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell view.setBackground(null); 6062cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell } 6072cb2e29508d59f76976c8f1742690b90f99ab803Brian Attwell return view; 608d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 609d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 610d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng @Override 611d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void bindHeaderView(View view, int partitionIndex, Cursor cursor) { 612d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(partitionIndex); 613d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!(partition instanceof DirectoryPartition)) { 614d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return; 615d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 616d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 617d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng DirectoryPartition directoryPartition = (DirectoryPartition)partition; 618d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng long directoryId = directoryPartition.getDirectoryId(); 619d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng TextView labelTextView = (TextView)view.findViewById(R.id.label); 620d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng TextView displayNameTextView = (TextView)view.findViewById(R.id.display_name); 621768324c2d917f9ce79747007c57efcefbc06b472Alon Albert labelTextView.setText(directoryPartition.getLabel()); 622768324c2d917f9ce79747007c57efcefbc06b472Alon Albert if (!isRemoteDirectory(directoryId)) { 623d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng displayNameTextView.setText(null); 624d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 625d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String directoryName = directoryPartition.getDisplayName(); 626d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String displayName = !TextUtils.isEmpty(directoryName) 627d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ? directoryName 628d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng : directoryPartition.getDirectoryType(); 629d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng displayNameTextView.setText(displayName); 630d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 63180f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen 63280f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen final Resources res = getContext().getResources(); 63380f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen final int headerPaddingTop = partitionIndex == 1 && getPartition(0).isEmpty()? 63480f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen 0 : res.getDimensionPixelOffset(R.dimen.directory_header_extra_top_padding); 63580f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen // There should be no extra padding at the top of the first directory header 63680f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen view.setPaddingRelative(view.getPaddingStart(), headerPaddingTop, view.getPaddingEnd(), 63780f8bee7990fd7f2a9fd2bace2d96b39c0f264b3Nancy Chen view.getPaddingBottom()); 638d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 639d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 640f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner // Default implementation simply returns number of rows in the cursor. 641f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner // Broken out into its own routine so can be overridden by child classes 642f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner // for eg number of unique contacts for a phone list. 643f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner protected int getResultCount(Cursor cursor) { 644f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner return cursor == null ? 0 : cursor.getCount(); 645f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner } 646f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner 647d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 648d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Checks whether the contact entry at the given position represents the user's profile. 649d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 650d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected boolean isUserProfile(int position) { 651d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // The profile only ever appears in the first position if it is present. So if the position 652d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // is anything beyond 0, it can't be the profile. 653d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng boolean isUserProfile = false; 654d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (position == 0) { 655d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int partition = getPartitionForPosition(position); 656d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition >= 0) { 657d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Save the old cursor position - the call to getItem() may modify the cursor 658d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // position. 659d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int offset = getCursor(partition).getPosition(); 660d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Cursor cursor = (Cursor) getItem(position); 661d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (cursor != null) { 662d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int profileColumnIndex = cursor.getColumnIndex(Contacts.IS_USER_PROFILE); 663d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (profileColumnIndex != -1) { 664d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng isUserProfile = cursor.getInt(profileColumnIndex) == 1; 665d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 666d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // Restore the old cursor position. 667d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng cursor.moveToPosition(offset); 668d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 669d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 670d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 671d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return isUserProfile; 672d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 673d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 674d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TODO: fix PluralRules to handle zero correctly and use Resources.getQuantityText directly 675d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public String getQuantityText(int count, int zeroResourceId, int pluralResourceId) { 676d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (count == 0) { 677d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return getContext().getString(zeroResourceId); 678d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 679d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String format = getContext().getResources() 680d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng .getQuantityText(pluralResourceId, count).toString(); 681d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return String.format(format, count); 682d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 683d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 684d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 685d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public boolean isPhotoSupported(int partitionIndex) { 686d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Partition partition = getPartition(partitionIndex); 687d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (partition instanceof DirectoryPartition) { 688d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return ((DirectoryPartition) partition).isPhotoSupported(); 689d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 690d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return true; 691d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 692d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 693d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 694d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Returns the currently selected filter. 695d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 696d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public ContactListFilter getFilter() { 697d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return mFilter; 698d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 699d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 700d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng public void setFilter(ContactListFilter filter) { 701d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng mFilter = filter; 702d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 703d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 704d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng // TODO: move sharable logic (bindXX() methods) to here with extra arguments 705d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 706d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng /** 707d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Loads the photo for the quick contact view and assigns the contact uri. 708d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param photoIdColumn Index of the photo id column 709d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param photoUriColumn Index of the photo uri column. Optional: Can be -1 710d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param contactIdColumn Index of the contact id column 711d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * @param lookUpKeyColumn Index of the lookup key column 7126084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * @param displayNameColumn Index of the display name column 713d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */ 714d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected void bindQuickContact(final ContactListItemView view, int partitionIndex, 715d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng Cursor cursor, int photoIdColumn, int photoUriColumn, int contactIdColumn, 7166084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee int lookUpKeyColumn, int displayNameColumn) { 717d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng long photoId = 0; 718d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (!cursor.isNull(photoIdColumn)) { 719d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng photoId = cursor.getLong(photoIdColumn); 720d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 721d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 722d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng QuickContactBadge quickContact = view.getQuickContact(); 723d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng quickContact.assignContactUri( 724d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn)); 725d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 726d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (photoId != 0 || photoUriColumn == -1) { 7273f9c2f426058413055fa54c08c69ad9461717658Yorke Lee getPhotoLoader().loadThumbnail(quickContact, photoId, mDarkTheme, mCircularPhotos, 7283f9c2f426058413055fa54c08c69ad9461717658Yorke Lee null); 729d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } else { 730d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final String photoUriString = cursor.getString(photoUriColumn); 731d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString); 7326084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee DefaultImageRequest request = null; 7336084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee if (photoUri == null) { 7346084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee request = getDefaultImageRequestFromCursor(cursor, displayNameColumn, 7356084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee lookUpKeyColumn); 7366084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee } 7373f9c2f426058413055fa54c08c69ad9461717658Yorke Lee getPhotoLoader().loadPhoto(quickContact, photoUri, -1, mDarkTheme, mCircularPhotos, 7383f9c2f426058413055fa54c08c69ad9461717658Yorke Lee request); 739d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 740d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 741d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 742d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 7434cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell @Override 7444cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell public boolean hasStableIds() { 7454cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell // Whenever bindViewId() is called, the values passed into setId() are stable or 7464cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell // stable-ish. For example, when one contact is modified we don't expect a second 7474cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell // contact's Contact._ID values to change. 7484cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell return true; 7494cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell } 7504cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell 7514cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell protected void bindViewId(final ContactListItemView view, Cursor cursor, int idColumn) { 7524cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell // Set a semi-stable id, so that talkback won't get confused when the list gets 7534cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell // refreshed. There is little harm in inserting the same ID twice. 7544cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell long contactId = cursor.getLong(idColumn); 7554cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell view.setId((int) (contactId % Integer.MAX_VALUE)); 7564cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell 7574cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell } 7584cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell 759d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng protected Uri getContactUri(int partitionIndex, Cursor cursor, 760d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng int contactIdColumn, int lookUpKeyColumn) { 761d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng long contactId = cursor.getLong(contactIdColumn); 762d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng String lookupKey = cursor.getString(lookUpKeyColumn); 763d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng long directoryId = ((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId(); 764adbb5e91a12aff2ef64945424e3cecdc1cdc724dJay Shrauner // Remote directories must have a lookup key or we don't have 765adbb5e91a12aff2ef64945424e3cecdc1cdc724dJay Shrauner // a working contact URI 766adbb5e91a12aff2ef64945424e3cecdc1cdc724dJay Shrauner if (TextUtils.isEmpty(lookupKey) && isRemoteDirectory(directoryId)) { 767adbb5e91a12aff2ef64945424e3cecdc1cdc724dJay Shrauner return null; 768adbb5e91a12aff2ef64945424e3cecdc1cdc724dJay Shrauner } 769adbb5e91a12aff2ef64945424e3cecdc1cdc724dJay Shrauner Uri uri = Contacts.getLookupUri(contactId, lookupKey); 770d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng if (directoryId != Directory.DEFAULT) { 771d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng uri = uri.buildUpon().appendQueryParameter( 772d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build(); 773d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 774d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng return uri; 775d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng } 776d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng 777768324c2d917f9ce79747007c57efcefbc06b472Alon Albert public static boolean isRemoteDirectory(long directoryId) { 778768324c2d917f9ce79747007c57efcefbc06b472Alon Albert return directoryId != Directory.DEFAULT 779768324c2d917f9ce79747007c57efcefbc06b472Alon Albert && directoryId != Directory.LOCAL_INVISIBLE; 780768324c2d917f9ce79747007c57efcefbc06b472Alon Albert } 7816084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee 7826084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee /** 7836084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * Retrieves the lookup key and display name from a cursor, and returns a 7846084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * {@link DefaultImageRequest} containing these contact details 7856084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * 7866084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * @param cursor Contacts cursor positioned at the current row to retrieve contact details for 7876084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * @param displayNameColumn Column index of the display name 7886084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * @param lookupKeyColumn Column index of the lookup key 7896084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * @return {@link DefaultImageRequest} with the displayName and identifier fields set to the 7906084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee * display name and lookup key of the contact. 7916084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee */ 7923f9c2f426058413055fa54c08c69ad9461717658Yorke Lee public DefaultImageRequest getDefaultImageRequestFromCursor(Cursor cursor, 7936084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee int displayNameColumn, int lookupKeyColumn) { 7946084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee final String displayName = cursor.getString(displayNameColumn); 7956084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee final String lookupKey = cursor.getString(lookupKeyColumn); 7963f9c2f426058413055fa54c08c69ad9461717658Yorke Lee return new DefaultImageRequest(displayName, lookupKey, mCircularPhotos); 7976084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee } 798d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng} 799