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