1/*
2 * Copyright (C) 2016 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 */
16package com.android.contacts.group;
17
18import android.content.Context;
19import android.content.CursorLoader;
20import android.database.Cursor;
21import android.net.Uri;
22import android.provider.ContactsContract;
23import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
24import android.provider.ContactsContract.Contacts;
25import android.provider.ContactsContract.Data;
26import android.provider.ContactsContract.Directory;
27import android.view.View;
28import android.view.ViewGroup;
29
30import com.android.contacts.R;
31import com.android.contacts.list.ContactListItemView;
32import com.android.contacts.list.MultiSelectEntryContactListAdapter;
33import com.android.contacts.preference.ContactsPreferences;
34
35/** Group members cursor adapter. */
36public class GroupMembersAdapter extends MultiSelectEntryContactListAdapter {
37
38    public static class GroupMembersQuery {
39
40        private static final String[] PROJECTION_PRIMARY = new String[] {
41                Data.CONTACT_ID,
42                Data.RAW_CONTACT_ID,
43                Data.PHOTO_ID,
44                Data.LOOKUP_KEY,
45                Data.CONTACT_PRESENCE,
46                Data.CONTACT_STATUS,
47                Data.DISPLAY_NAME_PRIMARY,
48        };
49
50        private static final String[] PROJECTION_ALTERNATIVE = new String[] {
51                Data.CONTACT_ID,
52                Data.RAW_CONTACT_ID,
53                Data.PHOTO_ID,
54                Data.LOOKUP_KEY,
55                Data.CONTACT_PRESENCE,
56                Data.CONTACT_STATUS,
57                Data.DISPLAY_NAME_ALTERNATIVE,
58        };
59
60        public static final int CONTACT_ID                   = 0;
61        public static final int RAW_CONTACT_ID               = 1;
62        public static final int CONTACT_PHOTO_ID             = 2;
63        public static final int CONTACT_LOOKUP_KEY           = 3;
64        public static final int CONTACT_PRESENCE             = 4;
65        public static final int CONTACT_STATUS               = 5;
66        public static final int CONTACT_DISPLAY_NAME         = 6;
67    }
68
69    private final CharSequence mUnknownNameText;
70    private long mGroupId;
71    private boolean mDisplayDeleteButtons;
72
73    public GroupMembersAdapter(Context context) {
74        super(context, GroupMembersQuery.CONTACT_ID);
75
76        mUnknownNameText = context.getText(R.string.missing_name);
77    }
78
79    /** Sets the ID of the group whose members will be displayed. */
80    public void setGroupId(long groupId) {
81        mGroupId = groupId;
82    }
83
84    /** Returns the lookup Uri for the contact at the given position in the underlying cursor. */
85    public Uri getContactUri(int position) {
86        final Cursor cursor = (Cursor) getItem(position);
87        final long contactId = cursor.getLong(GroupMembersQuery.CONTACT_ID);
88        final String lookupKey = cursor.getString(GroupMembersQuery.CONTACT_LOOKUP_KEY);
89        return Contacts.getLookupUri(contactId, lookupKey);
90    }
91
92    /** Returns the ID of the contact at the given position in the underlying cursor. */
93    public long getContactId(int position) {
94        final Cursor cursor = (Cursor) getItem(position);
95        return cursor.getLong(GroupMembersQuery.CONTACT_ID);
96    }
97
98    public void setDisplayDeleteButtons(boolean displayDeleteButtons) {
99        mDisplayDeleteButtons = displayDeleteButtons;
100        notifyDataSetChanged();
101    }
102
103    public boolean getDisplayDeleteButtons() {
104        return mDisplayDeleteButtons;
105    }
106
107    @Override
108    public void configureLoader(CursorLoader loader, long directoryId) {
109        loader.setUri(Data.CONTENT_URI.buildUpon()
110                .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
111                        String.valueOf(Directory.DEFAULT))
112                .appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true")
113                .build());
114
115        loader.setSelection(Data.MIMETYPE + "=?" + " AND " + GroupMembership.GROUP_ROW_ID + "=?");
116
117        final String[] selectionArgs = new String[2];
118        selectionArgs[0] = GroupMembership.CONTENT_ITEM_TYPE;
119        selectionArgs[1] = String.valueOf(mGroupId);
120        loader.setSelectionArgs(selectionArgs);
121
122        loader.setProjection(
123                getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY
124                        ? GroupMembersQuery.PROJECTION_PRIMARY
125                        : GroupMembersQuery.PROJECTION_ALTERNATIVE);
126
127        loader.setSortOrder(
128                getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY
129                        ? Contacts.SORT_KEY_PRIMARY : Contacts.SORT_KEY_ALTERNATIVE);
130    }
131
132    @Override
133    public String getContactDisplayName(int position) {
134        return ((Cursor) getItem(position)).getString(GroupMembersQuery.CONTACT_DISPLAY_NAME);
135    }
136
137    @Override
138    protected ContactListItemView newView(Context context, int partition, Cursor cursor,
139            int position, ViewGroup parent) {
140        final ContactListItemView view =
141                super.newView(context, partition, cursor, position, parent);
142        view.setUnknownNameText(mUnknownNameText);
143        return view;
144    }
145
146    @Override
147    protected void bindView(View v, int partition, Cursor cursor, int position) {
148        super.bindView(v, partition, cursor, position);
149        final ContactListItemView view = (ContactListItemView) v;
150        bindSectionHeaderAndDivider(view, position);
151        bindName(view, cursor);
152        bindPhoto(view, cursor, GroupMembersQuery.CONTACT_PHOTO_ID,
153                GroupMembersQuery.CONTACT_LOOKUP_KEY, GroupMembersQuery.CONTACT_DISPLAY_NAME);
154        bindDeleteButton(view, position);
155    }
156
157    protected void bindSectionHeaderAndDivider(ContactListItemView view, int position) {
158        view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
159        if (isSectionHeaderDisplayEnabled()) {
160            final Placement placement = getItemPlacementInSection(position);
161            view.setSectionHeader(placement.sectionHeader);
162        } else {
163            view.setSectionHeader(null);
164        }
165    }
166
167    private void bindName(ContactListItemView view, Cursor cursor) {
168        view.showDisplayName(cursor, GroupMembersQuery.CONTACT_DISPLAY_NAME,
169                getContactNameDisplayOrder());
170    }
171
172    private void bindDeleteButton(final ContactListItemView view, int position) {
173        if (mDisplayDeleteButtons) {
174            view.getDeleteImageButton(getDeleteContactListener(), position);
175        } else {
176            view.hideDeleteImageButton();
177        }
178    }
179}
180