1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.contacts.list; 17 18 import android.content.Context; 19 import android.content.CursorLoader; 20 import android.database.Cursor; 21 import android.net.Uri; 22 import android.net.Uri.Builder; 23 import android.provider.ContactsContract; 24 import android.provider.ContactsContract.Contacts; 25 import android.provider.ContactsContract.Contacts.AggregationSuggestions; 26 import android.provider.ContactsContract.Directory; 27 import android.text.TextUtils; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.widget.TextView; 32 33 import com.android.contacts.R; 34 import com.android.contacts.common.list.ContactListAdapter; 35 import com.android.contacts.common.list.ContactListItemView; 36 import com.android.contacts.common.list.DirectoryListLoader; 37 import com.android.contacts.common.preference.ContactsPreferences; 38 39 public class JoinContactListAdapter extends ContactListAdapter { 40 41 /** Maximum number of suggestions shown for joining aggregates */ 42 private static final int MAX_SUGGESTIONS = 4; 43 44 public static final int PARTITION_SUGGESTIONS = 0; 45 public static final int PARTITION_ALL_CONTACTS = 1; 46 47 private long mTargetContactId; 48 JoinContactListAdapter(Context context)49 public JoinContactListAdapter(Context context) { 50 super(context); 51 setPinnedPartitionHeadersEnabled(true); 52 setSectionHeaderDisplayEnabled(true); 53 setIndexedPartition(PARTITION_ALL_CONTACTS); 54 setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE); 55 } 56 57 @Override addPartitions()58 protected void addPartitions() { 59 // Partition 0: suggestions 60 addPartition(false, true); 61 62 // Partition 1: All contacts 63 addPartition(createDefaultDirectoryPartition()); 64 } 65 setTargetContactId(long targetContactId)66 public void setTargetContactId(long targetContactId) { 67 this.mTargetContactId = targetContactId; 68 } 69 70 @Override configureLoader(CursorLoader cursorLoader, long directoryId)71 public void configureLoader(CursorLoader cursorLoader, long directoryId) { 72 JoinContactLoader loader = (JoinContactLoader) cursorLoader; 73 74 final Builder builder = Contacts.CONTENT_URI.buildUpon(); 75 builder.appendEncodedPath(String.valueOf(mTargetContactId)); 76 builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY); 77 78 final String filter = getQueryString(); 79 if (!TextUtils.isEmpty(filter)) { 80 builder.appendEncodedPath(Uri.encode(filter)); 81 } 82 83 builder.appendQueryParameter("limit", String.valueOf(MAX_SUGGESTIONS)); 84 85 loader.setSuggestionUri(builder.build()); 86 87 // TODO simplify projection 88 loader.setProjection(getProjection(false)); 89 final Uri allContactsUri; 90 if (!TextUtils.isEmpty(filter)) { 91 allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_FILTER_URI).buildUpon() 92 .appendEncodedPath(Uri.encode(filter)) 93 .appendQueryParameter( 94 ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT)) 95 .build(); 96 } else { 97 allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_URI).buildUpon() 98 .appendQueryParameter( 99 ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT)) 100 .build(); 101 } 102 loader.setUri(allContactsUri); 103 loader.setSelection(Contacts._ID + "!=?"); 104 loader.setSelectionArgs(new String[]{ String.valueOf(mTargetContactId) }); 105 if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) { 106 loader.setSortOrder(Contacts.SORT_KEY_PRIMARY); 107 } else { 108 loader.setSortOrder(Contacts.SORT_KEY_ALTERNATIVE); 109 } 110 } 111 112 @Override isEmpty()113 public boolean isEmpty() { 114 return false; 115 } 116 setSuggestionsCursor(Cursor cursor)117 public void setSuggestionsCursor(Cursor cursor) { 118 changeCursor(PARTITION_SUGGESTIONS, cursor); 119 } 120 121 @Override changeCursor(Cursor cursor)122 public void changeCursor(Cursor cursor) { 123 changeCursor(PARTITION_ALL_CONTACTS, cursor); 124 } 125 126 @Override configureDefaultPartition(boolean showIfEmpty, boolean hasHeader)127 public void configureDefaultPartition(boolean showIfEmpty, boolean hasHeader) { 128 // Don't change default partition parameters from these defaults 129 super.configureDefaultPartition(false, true); 130 } 131 132 @Override getViewTypeCount()133 public int getViewTypeCount() { 134 return super.getViewTypeCount(); 135 } 136 137 @Override getItemViewType(int partition, int position)138 public int getItemViewType(int partition, int position) { 139 return super.getItemViewType(partition, position); 140 } 141 142 @Override newHeaderView(Context context, int partition, Cursor cursor, ViewGroup parent)143 protected View newHeaderView(Context context, int partition, Cursor cursor, 144 ViewGroup parent) { 145 switch (partition) { 146 case PARTITION_SUGGESTIONS: { 147 View view = inflate(R.layout.join_contact_picker_section_header, parent); 148 ((TextView) view.findViewById(R.id.text)).setText( 149 R.string.separatorJoinAggregateSuggestions); 150 return view; 151 } 152 case PARTITION_ALL_CONTACTS: { 153 View view = inflate(R.layout.join_contact_picker_section_header, parent); 154 ((TextView) view.findViewById(R.id.text)).setText( 155 R.string.separatorJoinAggregateAll); 156 return view; 157 } 158 } 159 160 return null; 161 } 162 163 @Override bindHeaderView(View view, int partitionIndex, Cursor cursor)164 protected void bindHeaderView(View view, int partitionIndex, Cursor cursor) { 165 // Header views are static - nothing needs to be bound 166 } 167 168 @Override newView( Context context, int partition, Cursor cursor, int position, ViewGroup parent)169 protected ContactListItemView newView( 170 Context context, int partition, Cursor cursor, int position, ViewGroup parent) { 171 switch (partition) { 172 case PARTITION_SUGGESTIONS: 173 case PARTITION_ALL_CONTACTS: 174 return super.newView(context, partition, cursor, position, parent); 175 } 176 return null; 177 } 178 inflate(int layoutId, ViewGroup parent)179 private View inflate(int layoutId, ViewGroup parent) { 180 return LayoutInflater.from(getContext()).inflate(layoutId, parent, false); 181 } 182 183 @Override bindView(View itemView, int partition, Cursor cursor, int position)184 protected void bindView(View itemView, int partition, Cursor cursor, int position) { 185 super.bindView(itemView, partition, cursor, position); 186 switch (partition) { 187 case PARTITION_SUGGESTIONS: { 188 final ContactListItemView view = (ContactListItemView) itemView; 189 view.setSectionHeader(null); 190 bindPhoto(view, partition, cursor); 191 bindNameAndViewId(view, cursor); 192 break; 193 } 194 case PARTITION_ALL_CONTACTS: { 195 final ContactListItemView view = (ContactListItemView) itemView; 196 bindSectionHeaderAndDivider(view, position, cursor); 197 bindPhoto(view, partition, cursor); 198 bindNameAndViewId(view, cursor); 199 break; 200 } 201 } 202 } 203 204 @Override getContactUri(int partitionIndex, Cursor cursor)205 public Uri getContactUri(int partitionIndex, Cursor cursor) { 206 long contactId = cursor.getLong(ContactQuery.CONTACT_ID); 207 String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY); 208 return Contacts.getLookupUri(contactId, lookupKey); 209 } 210 } 211