JoinContactListAdapter.java revision 3c46291ef057eaf7b7f8ca5971e59bebe734a660
16e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov/*
26e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
36e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov *
46e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
56e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * you may not use this file except in compliance with the License.
66e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * You may obtain a copy of the License at
76e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov *
86e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
96e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov *
106e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
116e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
126e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * See the License for the specific language governing permissions and
146e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov * limitations under the License.
156e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov */
166e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovpackage com.android.contacts.list;
176e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
186e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovimport com.android.contacts.R;
196e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
20e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.content.Context;
213c46291ef057eaf7b7f8ca5971e59bebe734a660Jeff Hamiltonimport android.content.CursorLoader;
226e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovimport android.database.Cursor;
23e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.database.MatrixCursor;
24e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.net.Uri;
25e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.net.Uri.Builder;
26e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.provider.ContactsContract;
27e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.provider.ContactsContract.Contacts;
28e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.provider.ContactsContract.Contacts.AggregationSuggestions;
29e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.text.TextUtils;
306e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovimport android.view.LayoutInflater;
316e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovimport android.view.View;
326e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovimport android.view.ViewGroup;
336e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikovimport android.widget.TextView;
346e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
35e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovpublic class JoinContactListAdapter extends ContactListAdapter {
36e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
37e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    /** Maximum number of suggestions shown for joining aggregates */
38e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private static final int MAX_SUGGESTIONS = 4;
39e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
40e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private Cursor mSuggestionsCursor;
41e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private int mSuggestionsCursorCount;
42e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private long mTargetContactId;
436e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
446e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    /**
456e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov     * Determines whether we display a list item with the label
466e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov     * "Show all contacts" or actually show all contacts
476e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov     */
48e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private boolean mAllContactsListShown;
496e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
50e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public JoinContactListAdapter(Context context) {
516e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        super(context);
52e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        setSectionHeaderDisplayEnabled(true);
536e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
546e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
55e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void setTargetContactId(long targetContactId) {
56e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        this.mTargetContactId = targetContactId;
576e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
586e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
59e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
60e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void configureLoader(CursorLoader cursorLoader) {
61e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        JoinContactLoader loader = (JoinContactLoader)cursorLoader;
62e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        loader.setLoadSuggestionsAndAllContacts(mAllContactsListShown);
63e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
64e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        Builder builder = Contacts.CONTENT_URI.buildUpon();
65e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        builder.appendEncodedPath(String.valueOf(mTargetContactId));
66e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY);
67e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
68e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        String filter = getQueryString();
69e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (!TextUtils.isEmpty(filter)) {
70e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            builder.appendEncodedPath(Uri.encode(filter));
71e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        }
72e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
73e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        builder.appendQueryParameter("limit", String.valueOf(MAX_SUGGESTIONS));
74e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
75e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        loader.setSuggestionUri(builder.build());
76e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
77e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        // TODO simplify projection
78e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        loader.setProjection(PROJECTION);
79e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
80e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (mAllContactsListShown) {
81e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            loader.setUri(buildSectionIndexerUri(Contacts.CONTENT_URI));
82e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            loader.setSelection(Contacts.IN_VISIBLE_GROUP + "=1 AND " + Contacts._ID + "!=?");
83e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            loader.setSelectionArgs(new String[]{String.valueOf(mTargetContactId)});
84e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
85e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                loader.setSortOrder(Contacts.SORT_KEY_PRIMARY);
86e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            } else {
87e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                loader.setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
88e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            }
89e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        }
90e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
91e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
92e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
93e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public boolean isEmpty() {
94e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return false;
95e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
96e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
97e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private boolean hasSuggestions() {
98e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return mSuggestionsCursorCount != 0;
99e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
100e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
101e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public boolean isAllContactsListShown() {
102e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return mAllContactsListShown;
103e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
104e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
105e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void setAllContactsListShown(boolean flag) {
106e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        mAllContactsListShown = flag;
1076e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
1086e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1096e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public void setSuggestionsCursor(Cursor cursor) {
1106e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        mSuggestionsCursor = cursor;
1116e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        mSuggestionsCursorCount = cursor == null ? 0 : cursor.getCount();
1126e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
1136e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
114e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public boolean isShowAllContactsItemPosition(int position) {
115e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return !mAllContactsListShown
116e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                && hasSuggestions() && position == mSuggestionsCursorCount + 2;
1176e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
1186e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1196e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
1206e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public View getView(int position, View convertView, ViewGroup parent) {
1216e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (!mDataValid) {
1226e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            throw new IllegalStateException(
1236e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov                    "this should only be called when the cursor is valid");
1246e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
1256e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1266e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        Cursor cursor;
127e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        boolean showingSuggestion = false;
128e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (hasSuggestions()) {
129e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            if (position == 0) {
130e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                // First section: "suggestions"
131e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                TextView view = (TextView) inflate(R.layout.list_separator, parent);
132e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                view.setText(R.string.separatorJoinAggregateSuggestions);
133e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                return view;
134e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            } else if (position < mSuggestionsCursorCount + 1) {
135e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                showingSuggestion = true;
136e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                cursor = mSuggestionsCursor;
137e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                cursor.moveToPosition(position - 1);
138e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            } else if (position == mSuggestionsCursorCount + 1) {
139e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                // Second section: "all contacts"
140e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                TextView view = (TextView) inflate(R.layout.list_separator, parent);
141e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                view.setText(R.string.separatorJoinAggregateAll);
142e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                return view;
143e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            } else if (!mAllContactsListShown && position == mSuggestionsCursorCount + 2) {
144e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                return inflate(R.layout.contacts_list_show_all_item, parent);
145e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            } else {
146e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                cursor = mCursor;
147e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                cursor.moveToPosition(position - mSuggestionsCursorCount - 2);
148e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            }
1496e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        } else {
1506e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            cursor = mCursor;
151e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            cursor.moveToPosition(position);
1526e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
1536e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1546e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        View v;
1556e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (convertView == null || convertView.getTag() == null) {
1566e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            v = newView(getContext(), cursor, parent);
1576e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        } else {
1586e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            v = convertView;
1596e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
160e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        bindView(position, v, cursor, showingSuggestion);
1616e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        return v;
1626e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
1636e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
164e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    private View inflate(int layoutId, ViewGroup parent) {
165e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return LayoutInflater.from(getContext()).inflate(layoutId, parent, false);
166e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
167e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
168e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
169e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void bindView(View view, Context context, Cursor cursor) {
170e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        // not used
171e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
172e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
173e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public void bindView(int position, View itemView, Cursor cursor, boolean showingSuggestion) {
174e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        final ContactListItemView view = (ContactListItemView)itemView;
175e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (!showingSuggestion) {
176e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            bindSectionHeaderAndDivider(view, position);
177e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        }
178e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        bindPhoto(view, cursor);
179e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        bindName(view, cursor);
180e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
181e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
182e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public Cursor getShowAllContactsLabelCursor() {
183e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        MatrixCursor matrixCursor = new MatrixCursor(PROJECTION);
184e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        Object[] row = new Object[PROJECTION.length];
185e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        matrixCursor.addRow(row);
186e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return matrixCursor;
187e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
188e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
1896e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
1906e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public void changeCursor(Cursor cursor) {
1916e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (cursor == null) {
1926e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            setSuggestionsCursor(null);
1936e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
1946e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
1956e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        super.changeCursor(cursor);
1966e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
197e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
1986e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
1996e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public int getItemViewType(int position) {
2006e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (isShowAllContactsItemPosition(position)) {
2016e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            return IGNORE_ITEM_VIEW_TYPE;
2026e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
2036e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2046e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        return super.getItemViewType(position);
2056e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
2066e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
207e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
208e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public int getPositionForSection(int sectionIndex) {
209e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (mSuggestionsCursorCount == 0) {
210e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            return super.getPositionForSection(sectionIndex);
2116e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
212e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
213e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        // Get section position in the full list
214e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        int position = super.getPositionForSection(sectionIndex);
215e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return position + mSuggestionsCursorCount + 2;
216e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    }
217e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
218e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    @Override
219e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public int getSectionForPosition(int position) {
220e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (mSuggestionsCursorCount == 0) {
221e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            return super.getSectionForPosition(position);
222e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        }
223e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
224e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (position < mSuggestionsCursorCount + 2) {
225e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            return -1;
226e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        }
227e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov
228e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return super.getSectionForPosition(position - mSuggestionsCursorCount - 2);
2296e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
2306e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2316e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
2326e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public boolean areAllItemsEnabled() {
2336e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        return super.areAllItemsEnabled() && mSuggestionsCursorCount == 0;
2346e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
2356e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2366e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
2376e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public boolean isEnabled(int position) {
2386e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (position == 0) {
2396e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            return false;
2406e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
2416e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2426e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (mSuggestionsCursorCount > 0) {
2436e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            return position != 0 && position != mSuggestionsCursorCount + 1;
2446e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
2456e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        return true;
2466e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
2476e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2486e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
2496e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public int getCount() {
2506e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        if (!mDataValid) {
2516e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            return 0;
2526e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
2536e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        int superCount = super.getCount();
254e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (hasSuggestions()) {
2556e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            // When showing suggestions, we have 2 additional list items: the "Suggestions"
2566e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            // and "All contacts" headers.
2576e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            return mSuggestionsCursorCount + superCount + 2;
2586e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
2596e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        return superCount;
2606e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
2616e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2626e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    public int getSuggestionsCursorCount() {
2636e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        return mSuggestionsCursorCount;
2646e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
2656e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
2666e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
267e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public Object getItem(int pos) {
268e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        if (hasSuggestions()) {
2696e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            // When showing suggestions, we have 2 additional list items: the "Suggestions"
2706e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            // and "All contacts" separators.
271e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            if (pos == 0) {
272e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                return null;
273e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            }
274e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            else if (pos < mSuggestionsCursorCount + 1) {
2756e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov                // We are in the upper partition (Suggestions). Adjusting for the "Suggestions"
2766e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov                // separator.
277e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                mSuggestionsCursor.moveToPosition(pos - 1);
278e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                return mSuggestionsCursor;
279e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            } else if (pos == mSuggestionsCursorCount + 1) {
280e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                // This is the "All contacts" separator
281e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                return null;
2826e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            } else {
283e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                if (!isAllContactsListShown()) {
284e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                    // This is the "Show all contacts" item
285e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                    return null;
286e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                } else {
287e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                    // We are in the lower partition (All contacts). Adjusting for the size
288e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                    // of the upper partition plus the two separators.
289e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                    mCursor.moveToPosition(pos - mSuggestionsCursorCount - 2);
290e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                    return mCursor;
291e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov                }
2926e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov            }
293e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        } else if (mCursor != null) {
294e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            // No separators
295e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            mCursor.moveToPosition(pos);
296e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            return mCursor;
2976e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        } else {
298e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov            return null;
2996e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov        }
3006e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
3016e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
3026e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    @Override
303e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public long getItemId(int pos) {
304e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        Cursor cursor = (Cursor)getItem(pos);
305e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return cursor == null ? 0 : cursor.getLong(mRowIDColumn);
3066e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
3076e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov
308e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov    public Uri getContactUri(int position) {
309e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        Cursor cursor = (Cursor)getItem(position);
310e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        long contactId = cursor.getLong(CONTACT_ID_COLUMN_INDEX);
311e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        String lookupKey = cursor.getString(CONTACT_LOOKUP_KEY_COLUMN_INDEX);
312e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov        return Contacts.getLookupUri(contactId, lookupKey);
3136e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov    }
3146e2009d58fdcf098cab033729d4a3b2444c2181cDmitri Plotnikov}