1fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng/*
2fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * Copyright (C) 2010 The Android Open Source Project
3fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng *
4fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * you may not use this file except in compliance with the License.
6fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * You may obtain a copy of the License at
7fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng *
8fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng *
10fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * Unless required by applicable law or agreed to in writing, software
11fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * See the License for the specific language governing permissions and
14fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * limitations under the License.
15fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng */
16fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
1769c182afb0e6d82a341a28b4317aa703af768906Gary Maipackage com.android.contacts.list;
18fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
19fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.app.Activity;
20c2e912c41b4f0fc4ca4b948b6d0aaa84eeb8d1d9Brian Attwellimport android.app.Fragment;
21fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.app.LoaderManager;
22fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.app.LoaderManager.LoaderCallbacks;
23fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.content.Context;
24fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.content.CursorLoader;
25fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.content.Intent;
26fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.content.Loader;
27fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.database.Cursor;
28fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.os.Bundle;
29fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.os.Handler;
30fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.os.Message;
31fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.os.Parcelable;
32fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.provider.ContactsContract.Directory;
33fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.text.TextUtils;
3435821295f0a7118981972f7c2ca4919041ddae49Yorke Leeimport android.util.Log;
35fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.LayoutInflater;
36fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.MotionEvent;
37fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.View;
38fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.View.OnFocusChangeListener;
39fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.View.OnTouchListener;
40fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.ViewGroup;
41fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.view.inputmethod.InputMethodManager;
42fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.widget.AbsListView;
43fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.widget.AbsListView.OnScrollListener;
44fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.widget.AdapterView;
45fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.widget.AdapterView.OnItemClickListener;
46207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwellimport android.widget.AdapterView.OnItemLongClickListener;
47fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport android.widget.ListView;
48fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
49fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengimport com.android.common.widget.CompositeCursorAdapter.Partition;
500a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.ContactPhotoManager;
5169c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.logging.ListEvent.ActionType;
5269c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.logging.Logger;
5369c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.preference.ContactsPreferences;
54fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
5529a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglioimport java.util.Locale;
5629a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio
57fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng/**
58fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng * Common base class for various contact-related list fragments.
59fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng */
60fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Chengpublic abstract class ContactEntryListFragment<T extends ContactEntryListAdapter>
61c2e912c41b4f0fc4ca4b948b6d0aaa84eeb8d1d9Brian Attwell        extends Fragment
62fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        implements OnItemClickListener, OnScrollListener, OnFocusChangeListener, OnTouchListener,
63207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell                OnItemLongClickListener, LoaderCallbacks<Cursor> {
64ffb419e08d7bab32ee489ec1e8e4a341d01a968aWenyi Wang    private static final String TAG = "ContactEntryList";
65fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
66fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    // TODO: Make this protected. This should not be used from the PeopleActivity but
67fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    // instead use the new startActivityWithResultFromFragment API
68fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public static final int ACTIVITY_REQUEST_CODE_PICKER = 1;
69fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
70fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_LIST_STATE = "liststate";
71fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_SECTION_HEADER_DISPLAY_ENABLED = "sectionHeaderDisplayEnabled";
72fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_PHOTO_LOADER_ENABLED = "photoLoaderEnabled";
73fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_QUICK_CONTACT_ENABLED = "quickContactEnabled";
744683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee    private static final String KEY_ADJUST_SELECTION_BOUNDS_ENABLED =
754683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee            "adjustSelectionBoundsEnabled";
76fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_SEARCH_MODE = "searchMode";
773376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    private static final String KEY_DISPLAY_DIRECTORY_HEADER = "displayDirectoryHeader";
78fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_VISIBLE_SCROLLBAR_ENABLED = "visibleScrollbarEnabled";
79fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_SCROLLBAR_POSITION = "scrollbarPosition";
80fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_QUERY_STRING = "queryString";
81fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_DIRECTORY_SEARCH_MODE = "directorySearchMode";
82fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_SELECTION_VISIBLE = "selectionVisible";
83fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_REQUEST = "request";
84fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_DARK_THEME = "darkTheme";
85fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_LEGACY_COMPATIBILITY = "legacyCompatibility";
86fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String KEY_DIRECTORY_RESULT_LIMIT = "directoryResultLimit";
87c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    private static final String KEY_LOGS_LIST_EVENTS = "logsListEvents";
88c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    private static final String KEY_DATA_LOADED = "dataLoaded";
89fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
90fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final String DIRECTORY_ID_ARG_KEY = "directoryId";
91fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
92fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int DIRECTORY_LOADER_ID = -1;
93fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
94fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int DIRECTORY_SEARCH_DELAY_MILLIS = 300;
95fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int DIRECTORY_SEARCH_MESSAGE = 1;
96fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
97fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20;
98fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
99fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mSectionHeaderDisplayEnabled;
100fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mPhotoLoaderEnabled;
101fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mQuickContactEnabled = true;
1024683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee    private boolean mAdjustSelectionBoundsEnabled = true;
10325774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang    private boolean mIncludeFavorites;
104fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mSearchMode;
1053376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    private boolean mDisplayDirectoryHeader = true;
106fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mVisibleScrollbarEnabled;
107d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee    private boolean mShowEmptyListForEmptyQuery;
10829a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio    private int mVerticalScrollbarPosition = getDefaultVerticalScrollbarPosition();
109fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private String mQueryString;
110fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private int mDirectorySearchMode = DirectoryListLoader.SEARCH_MODE_NONE;
111fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mSelectionVisible;
112fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mLegacyCompatibility;
113c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    // Whether we should log list LOAD events. It may be modified when list filter is changed.
114c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    private boolean mLogListEvents = true;
115c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    // Whether data has been loaded ever. It will stay true once it's set to true in the lifecycle.
116c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    // We use this flag to log LOAD events when the activity/fragment is initialized.
117c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    private boolean mDataLoaded;
118fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
119fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mEnabled = true;
120fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
121fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private T mAdapter;
122f7d733a0319956d05735d13a2b7ee46fb0f0d994Walter Jang    protected View mView;
123fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private ListView mListView;
124fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
125fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
126477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen     * Used to save the scrolling state of the list when the fragment is not recreated.
127477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen     */
128477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen    private int mListViewTopIndex;
129477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen    private int mListViewTopOffset;
130477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen
131477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen    /**
132fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Used for keeping track of the scroll state of the list.
133fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
134fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private Parcelable mListState;
135fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
136c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    /**
137c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang     * The type of the contacts list.
138c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang     */
139c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    private int mListType;
140c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang
141fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private int mDisplayOrder;
142fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private int mSortOrder;
143fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private int mDirectoryResultLimit = DEFAULT_DIRECTORY_RESULT_LIMIT;
144fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
145fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private ContactPhotoManager mPhotoManager;
146fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private ContactsPreferences mContactsPrefs;
147fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
148fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mForceLoad;
149fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
150fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mDarkTheme;
151fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
152fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int STATUS_NOT_LOADED = 0;
153fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int STATUS_LOADING = 1;
154fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private static final int STATUS_LOADED = 2;
155fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
156fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private int mDirectoryListStatus = STATUS_NOT_LOADED;
157fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
158fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
159fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Indicates whether we are doing the initial complete load of data (false) or
160fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * a refresh caused by a change notification (true)
161fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
162fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private boolean mLoadPriorityDirectoriesOnly;
163fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
164fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private Context mContext;
165fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
166fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private LoaderManager mLoaderManager;
167fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
168fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private Handler mDelayedDirectorySearchHandler = new Handler() {
169fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        @Override
170fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        public void handleMessage(Message msg) {
171fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (msg.what == DIRECTORY_SEARCH_MESSAGE) {
172fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                loadDirectoryPartition(msg.arg1, (DirectoryPartition) msg.obj);
173fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
174fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
175fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    };
17629a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio    private int defaultVerticalScrollbarPosition;
177fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
178fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);
179fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected abstract T createListAdapter();
180fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
181fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
182fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * @param position Please note that the position is already adjusted for
183fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     *            header views, so "0" means the first list item below header
184fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     *            views.
185fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
186fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected abstract void onItemClick(int position, long id);
187fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
188207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell    /**
189207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell     * @param position Please note that the position is already adjusted for
190207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell     *            header views, so "0" means the first list item below header
191207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell     *            views.
192207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell     */
193207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell    protected boolean onItemLongClick(int position, long id) {
194207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell        return false;
195207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell    }
196207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell
197fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
198fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onAttach(Activity activity) {
199fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        super.onAttach(activity);
200fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        setContext(activity);
201fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        setLoaderManager(super.getLoaderManager());
202fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
203fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
204fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
205fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Sets a context for the fragment in the unit test environment.
206fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
207fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setContext(Context context) {
208fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mContext = context;
209fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        configurePhotoLoader();
210fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
211fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
212fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public Context getContext() {
213fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mContext;
214fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
215fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
216fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setEnabled(boolean enabled) {
217fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mEnabled != enabled) {
218fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mEnabled = enabled;
219fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mAdapter != null) {
220fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                if (mEnabled) {
221fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    reloadData();
222fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                } else {
223fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    mAdapter.clearPartitions();
224fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                }
225fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
226fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
227fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
228fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
229fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
230fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Overrides a loader manager for use in unit tests.
231fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
232fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setLoaderManager(LoaderManager loaderManager) {
233fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mLoaderManager = loaderManager;
234fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
235fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
236fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
237fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public LoaderManager getLoaderManager() {
238fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mLoaderManager;
239fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
240fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
241fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public T getAdapter() {
242fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mAdapter;
243fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
244fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
245fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
246fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public View getView() {
247fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mView;
248fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
249fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
250fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public ListView getListView() {
251fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mListView;
252fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
253fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
254fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
255fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onSaveInstanceState(Bundle outState) {
256fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        super.onSaveInstanceState(outState);
257fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_SECTION_HEADER_DISPLAY_ENABLED, mSectionHeaderDisplayEnabled);
258fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_PHOTO_LOADER_ENABLED, mPhotoLoaderEnabled);
259fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_QUICK_CONTACT_ENABLED, mQuickContactEnabled);
2604683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee        outState.putBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED, mAdjustSelectionBoundsEnabled);
261fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
2623376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        outState.putBoolean(KEY_DISPLAY_DIRECTORY_HEADER, mDisplayDirectoryHeader);
263fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED, mVisibleScrollbarEnabled);
264fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putInt(KEY_SCROLLBAR_POSITION, mVerticalScrollbarPosition);
265fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putInt(KEY_DIRECTORY_SEARCH_MODE, mDirectorySearchMode);
266fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_SELECTION_VISIBLE, mSelectionVisible);
267fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_LEGACY_COMPATIBILITY, mLegacyCompatibility);
268fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putString(KEY_QUERY_STRING, mQueryString);
269fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putInt(KEY_DIRECTORY_RESULT_LIMIT, mDirectoryResultLimit);
270fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        outState.putBoolean(KEY_DARK_THEME, mDarkTheme);
271c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        outState.putBoolean(KEY_LOGS_LIST_EVENTS, mLogListEvents);
272c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        outState.putBoolean(KEY_DATA_LOADED, mDataLoaded);
273fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
274fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mListView != null) {
275fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            outState.putParcelable(KEY_LIST_STATE, mListView.onSaveInstanceState());
276fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
277fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
278fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
279fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
280fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onCreate(Bundle savedState) {
281fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        super.onCreate(savedState);
2822101c3d08c08675e778f14115d534b41e57dca3aBrian Attwell        restoreSavedState(savedState);
283a9602e7a2729f8060cb1e93ddc6c17270c90b225Yorke Lee        mAdapter = createListAdapter();
284fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mContactsPrefs = new ContactsPreferences(mContext);
285fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
286fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
287fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void restoreSavedState(Bundle savedState) {
288fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (savedState == null) {
289fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return;
290fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
291fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
292fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mSectionHeaderDisplayEnabled = savedState.getBoolean(KEY_SECTION_HEADER_DISPLAY_ENABLED);
293fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mPhotoLoaderEnabled = savedState.getBoolean(KEY_PHOTO_LOADER_ENABLED);
294fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mQuickContactEnabled = savedState.getBoolean(KEY_QUICK_CONTACT_ENABLED);
2954683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee        mAdjustSelectionBoundsEnabled = savedState.getBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED);
296fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mSearchMode = savedState.getBoolean(KEY_SEARCH_MODE);
2973376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        mDisplayDirectoryHeader = savedState.getBoolean(KEY_DISPLAY_DIRECTORY_HEADER);
298fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mVisibleScrollbarEnabled = savedState.getBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED);
299fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mVerticalScrollbarPosition = savedState.getInt(KEY_SCROLLBAR_POSITION);
300fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDirectorySearchMode = savedState.getInt(KEY_DIRECTORY_SEARCH_MODE);
301fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mSelectionVisible = savedState.getBoolean(KEY_SELECTION_VISIBLE);
302fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mLegacyCompatibility = savedState.getBoolean(KEY_LEGACY_COMPATIBILITY);
303fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mQueryString = savedState.getString(KEY_QUERY_STRING);
304fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDirectoryResultLimit = savedState.getInt(KEY_DIRECTORY_RESULT_LIMIT);
305fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDarkTheme = savedState.getBoolean(KEY_DARK_THEME);
306fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
307fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        // Retrieve list state. This will be applied in onLoadFinished
308fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListState = savedState.getParcelable(KEY_LIST_STATE);
309fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
310fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
311fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
312fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onStart() {
313fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        super.onStart();
314fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
315fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mContactsPrefs.registerChangeListener(mPreferencesChangeListener);
316fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
317fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mForceLoad = loadPreferences();
318fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
319fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDirectoryListStatus = STATUS_NOT_LOADED;
320fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mLoadPriorityDirectoriesOnly = true;
321fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
322fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        startLoading();
323fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
324fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
325fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void startLoading() {
326fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mAdapter == null) {
327fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            // The method was called before the fragment was started
328fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return;
329fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
330fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
331fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        configureAdapter();
332fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        int partitionCount = mAdapter.getPartitionCount();
333fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        for (int i = 0; i < partitionCount; i++) {
334fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            Partition partition = mAdapter.getPartition(i);
335fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (partition instanceof DirectoryPartition) {
336fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                DirectoryPartition directoryPartition = (DirectoryPartition)partition;
337fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                if (directoryPartition.getStatus() == DirectoryPartition.STATUS_NOT_LOADED) {
338fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    if (directoryPartition.isPriorityDirectory() || !mLoadPriorityDirectoriesOnly) {
339fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                        startLoadingDirectoryPartition(i);
340fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    }
341fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                }
342fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            } else {
343fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                getLoaderManager().initLoader(i, null, this);
344fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
345fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
346fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
347fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        // Next time this method is called, we should start loading non-priority directories
348fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mLoadPriorityDirectoriesOnly = false;
349fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
350fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
351fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
352fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
353fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (id == DIRECTORY_LOADER_ID) {
354fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            DirectoryListLoader loader = new DirectoryListLoader(mContext);
355fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            loader.setDirectorySearchMode(mAdapter.getDirectorySearchMode());
356fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            loader.setLocalInvisibleDirectoryEnabled(
357fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    ContactEntryListAdapter.LOCAL_INVISIBLE_DIRECTORY_ENABLED);
358fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return loader;
359fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        } else {
3609afe494fd2622d9dfae8a71ee4ebb9eda8c0baefJay Shrauner            CursorLoader loader = createCursorLoader(mContext);
361fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            long directoryId = args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
362fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    ? args.getLong(DIRECTORY_ID_ARG_KEY)
363fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    : Directory.DEFAULT;
364fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mAdapter.configureLoader(loader, directoryId);
365fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return loader;
366fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
367fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
368fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
3699afe494fd2622d9dfae8a71ee4ebb9eda8c0baefJay Shrauner    public CursorLoader createCursorLoader(Context context) {
37035821295f0a7118981972f7c2ca4919041ddae49Yorke Lee        return new CursorLoader(context, null, null, null, null, null) {
37135821295f0a7118981972f7c2ca4919041ddae49Yorke Lee            @Override
37235821295f0a7118981972f7c2ca4919041ddae49Yorke Lee            protected Cursor onLoadInBackground() {
37335821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                try {
37435821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                    return super.onLoadInBackground();
37535821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                } catch (RuntimeException e) {
37635821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                    // We don't even know what the projection should be, so no point trying to
37735821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                    // return an empty MatrixCursor with the correct projection here.
37835821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                    Log.w(TAG, "RuntimeException while trying to query ContactsProvider.");
37935821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                    return null;
38035821295f0a7118981972f7c2ca4919041ddae49Yorke Lee                }
38135821295f0a7118981972f7c2ca4919041ddae49Yorke Lee            }
38235821295f0a7118981972f7c2ca4919041ddae49Yorke Lee        };
383fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
384fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
385fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private void startLoadingDirectoryPartition(int partitionIndex) {
386fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        DirectoryPartition partition = (DirectoryPartition)mAdapter.getPartition(partitionIndex);
387fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        partition.setStatus(DirectoryPartition.STATUS_LOADING);
388fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        long directoryId = partition.getDirectoryId();
389fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mForceLoad) {
390fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (directoryId == Directory.DEFAULT) {
391fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                loadDirectoryPartition(partitionIndex, partition);
392fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            } else {
393fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                loadDirectoryPartitionDelayed(partitionIndex, partition);
394fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
395fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        } else {
396fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            Bundle args = new Bundle();
397fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            args.putLong(DIRECTORY_ID_ARG_KEY, directoryId);
398fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            getLoaderManager().initLoader(partitionIndex, args, this);
399fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
400fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
401fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
402fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
403fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Queues up a delayed request to search the specified directory. Since
404fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * directory search will likely introduce a lot of network traffic, we want
405fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * to wait for a pause in the user's typing before sending a directory request.
406fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
407fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private void loadDirectoryPartitionDelayed(int partitionIndex, DirectoryPartition partition) {
408fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDelayedDirectorySearchHandler.removeMessages(DIRECTORY_SEARCH_MESSAGE, partition);
409fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        Message msg = mDelayedDirectorySearchHandler.obtainMessage(
410fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                DIRECTORY_SEARCH_MESSAGE, partitionIndex, 0, partition);
411fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDelayedDirectorySearchHandler.sendMessageDelayed(msg, DIRECTORY_SEARCH_DELAY_MILLIS);
412fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
413fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
414fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
415fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Loads the directory partition.
416fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
417fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void loadDirectoryPartition(int partitionIndex, DirectoryPartition partition) {
418fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        Bundle args = new Bundle();
419fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId());
420fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        getLoaderManager().restartLoader(partitionIndex, args, this);
421fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
422fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
423fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
424fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Cancels all queued directory loading requests.
425fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
426fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private void removePendingDirectorySearchRequests() {
427fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDelayedDirectorySearchHandler.removeMessages(DIRECTORY_SEARCH_MESSAGE);
428fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
429fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
430fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
431fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
432fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (!mEnabled) {
433fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return;
434fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
435fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
436f69e8561c8493c0f06b2c8e5bf732e3fb8d06f19Gary Mai        getListView().setVisibility(View.VISIBLE);
437f69e8561c8493c0f06b2c8e5bf732e3fb8d06f19Gary Mai        getView().setVisibility(View.VISIBLE);
438f69e8561c8493c0f06b2c8e5bf732e3fb8d06f19Gary Mai
439fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        int loaderId = loader.getId();
440fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (loaderId == DIRECTORY_LOADER_ID) {
441fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mDirectoryListStatus = STATUS_LOADED;
442fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mAdapter.changeDirectories(data);
443fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            startLoading();
444fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        } else {
445fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            onPartitionLoaded(loaderId, data);
446fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (isSearchMode()) {
447fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                int directorySearchMode = getDirectorySearchMode();
448fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                if (directorySearchMode != DirectoryListLoader.SEARCH_MODE_NONE) {
449fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    if (mDirectoryListStatus == STATUS_NOT_LOADED) {
450fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                        mDirectoryListStatus = STATUS_LOADING;
451fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                        getLoaderManager().initLoader(DIRECTORY_LOADER_ID, null, this);
452fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    } else {
453fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                        startLoading();
454fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    }
455fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                }
456fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            } else {
4571bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang                maybeLogListEvent();
458fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mDirectoryListStatus = STATUS_NOT_LOADED;
459fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
460fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
461fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
462fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
463fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
4641bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang    protected void maybeLogListEvent() {
4651bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang        if (!mDataLoaded || mLogListEvents) {
4661bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang            Logger.logListEvent(ActionType.LOAD, getListType(), getAdapter().getCount(),
4671bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang                        /* clickedIndex */ -1, /* numSelected */ 0);
4681bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang            mLogListEvents = false;
4691bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang            mDataLoaded = true;
4701bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang        }
4711bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang    }
4721bdef2f43675c9fcd4385acfda7779bcfe257cb8Walter Jang
473fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onLoaderReset(Loader<Cursor> loader) {
474fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
475fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
476fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void onPartitionLoaded(int partitionIndex, Cursor data) {
477fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (partitionIndex >= mAdapter.getPartitionCount()) {
478fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            // When we get unsolicited data, ignore it.  This could happen
479fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            // when we are switching from search mode to the default mode.
480fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return;
481fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
482fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
483fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.changeCursor(partitionIndex, data);
484be88bed5067d5892fcc4bf1844e925eeb654f0aaWenyi Wang        setListHeader();
485fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
486fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (!isLoading()) {
487fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            completeRestoreInstanceState();
488fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
489fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
490fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
491fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isLoading() {
492fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mAdapter != null && mAdapter.isLoading()) {
493fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return true;
494fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
495fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
496fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (isLoadingDirectoryList()) {
497fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return true;
498fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
499fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
500fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return false;
501fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
502fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
503fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isLoadingDirectoryList() {
504fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return isSearchMode() && getDirectorySearchMode() != DirectoryListLoader.SEARCH_MODE_NONE
505fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                && (mDirectoryListStatus == STATUS_NOT_LOADED
506fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                        || mDirectoryListStatus == STATUS_LOADING);
507fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
508fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
509fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
510fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onStop() {
511fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        super.onStop();
512fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mContactsPrefs.unregisterChangeListener();
513fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.clearPartitions();
514fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
515fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
516fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void reloadData() {
517fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        removePendingDirectorySearchRequests();
518fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.onDataReload();
519fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mLoadPriorityDirectoriesOnly = true;
520fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mForceLoad = true;
521fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        startLoading();
522fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
523fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
524fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
525be88bed5067d5892fcc4bf1844e925eeb654f0aaWenyi Wang     * Shows a view at the top of the list.
526fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
527be88bed5067d5892fcc4bf1844e925eeb654f0aaWenyi Wang    protected void setListHeader() {}
528fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
529fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
530fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Provides logic that dismisses this fragment. The default implementation
531fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * does nothing.
532fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
533fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void finish() {
534fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
535fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
536fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setSectionHeaderDisplayEnabled(boolean flag) {
537fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mSectionHeaderDisplayEnabled != flag) {
538fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mSectionHeaderDisplayEnabled = flag;
539fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mAdapter != null) {
540fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mAdapter.setSectionHeaderDisplayEnabled(flag);
541fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
542fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            configureVerticalScrollbar();
543fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
544fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
545fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
546fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isSectionHeaderDisplayEnabled() {
547fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mSectionHeaderDisplayEnabled;
548fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
549fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
550fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setVisibleScrollbarEnabled(boolean flag) {
551fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mVisibleScrollbarEnabled != flag) {
552fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mVisibleScrollbarEnabled = flag;
553fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            configureVerticalScrollbar();
554fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
555fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
556fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
557fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isVisibleScrollbarEnabled() {
558fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mVisibleScrollbarEnabled;
559fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
560fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
561fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setVerticalScrollbarPosition(int position) {
562fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mVerticalScrollbarPosition != position) {
563fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mVerticalScrollbarPosition = position;
564fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            configureVerticalScrollbar();
565fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
566fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
567fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
568fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private void configureVerticalScrollbar() {
569fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        boolean hasScrollbar = isVisibleScrollbarEnabled() && isSectionHeaderDisplayEnabled();
570fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
571fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mListView != null) {
572fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.setFastScrollEnabled(hasScrollbar);
573fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.setVerticalScrollbarPosition(mVerticalScrollbarPosition);
574fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
575fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
576fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
577fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
578fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setPhotoLoaderEnabled(boolean flag) {
579fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mPhotoLoaderEnabled = flag;
580fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        configurePhotoLoader();
581fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
582fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
583fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isPhotoLoaderEnabled() {
584fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mPhotoLoaderEnabled;
585fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
586fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
587fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
588fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Returns true if the list is supposed to visually highlight the selected item.
589fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
590fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isSelectionVisible() {
591fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mSelectionVisible;
592fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
593fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
594fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setSelectionVisible(boolean flag) {
595fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        this.mSelectionVisible = flag;
596fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
597fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
598fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setQuickContactEnabled(boolean flag) {
599fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        this.mQuickContactEnabled = flag;
600fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
601fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
6024683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee    public void setAdjustSelectionBoundsEnabled(boolean flag) {
6034683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee        mAdjustSelectionBoundsEnabled = flag;
6044683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee    }
6054683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee
60625774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang    public void setIncludeFavorites(boolean flag) {
60725774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang        mIncludeFavorites = flag;
60825774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang        if (mAdapter != null) {
60925774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang            mAdapter.setIncludeFavorites(flag);
61025774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang        }
61125774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang    }
61225774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang
6133376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    public void setDisplayDirectoryHeader(boolean flag) {
6143376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        mDisplayDirectoryHeader = flag;
6153376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    }
6163376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang
617fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
618d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee     * Enter/exit search mode. This is method is tightly related to the current query, and should
619d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee     * only be called by {@link #setQueryString}.
620fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     *
621fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Also note this method doesn't call {@link #reloadData()}; {@link #setQueryString} does it.
622fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
623fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void setSearchMode(boolean flag) {
624fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mSearchMode != flag) {
625fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mSearchMode = flag;
626fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            setSectionHeaderDisplayEnabled(!mSearchMode);
627fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
628fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (!flag) {
629fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mDirectoryListStatus = STATUS_NOT_LOADED;
630fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
631fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
632fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
633fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mAdapter != null) {
634fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mAdapter.setSearchMode(flag);
635fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
636fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mAdapter.clearPartitions();
637fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                if (!flag) {
638fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    // If we are switching from search to regular display, remove all directory
639fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    // partitions after default one, assuming they are remote directories which
640fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    // should be cleaned up on exiting the search mode.
641fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    mAdapter.removeDirectoriesAfterDefault();
642fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                }
6433376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang                mAdapter.configureDefaultPartition(false, shouldDisplayDirectoryHeader());
644fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
645fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
646fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mListView != null) {
647fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mListView.setFastScrollEnabled(!flag);
648fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
649fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
650fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
651fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
6523376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    /**
6533376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang     * When not in search mode, directory header should always be hidden.
6543376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang     * When in search mode, directory header should be displayed when mDisplayDirectoryHeader is
6553376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang     * set to true. (mDisplayDirectoryHeader default value is true)
6563376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang     */
6573376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    private boolean shouldDisplayDirectoryHeader() {
6583376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        if (!mSearchMode) {
6593376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang            return false;
6603376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        }
6613376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        return mDisplayDirectoryHeader;
6623376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang    }
6633376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang
664fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public final boolean isSearchMode() {
665fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mSearchMode;
666fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
667fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
668fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public final String getQueryString() {
669fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mQueryString;
670fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
671fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
672a5cae5d3be2bc6abd1ab190c2e4df9068304649cWenyi Wang    // TODO: the paramter delaySelection is not in use, and let's remove it.
673fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setQueryString(String queryString, boolean delaySelection) {
674fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (!TextUtils.equals(mQueryString, queryString)) {
675d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee            if (mShowEmptyListForEmptyQuery && mAdapter != null && mListView != null) {
676d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                if (TextUtils.isEmpty(mQueryString)) {
677d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                    // Restore the adapter if the query used to be empty.
678d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                    mListView.setAdapter(mAdapter);
679d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                } else if (TextUtils.isEmpty(queryString)) {
680d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                    // Instantly clear the list view if the new query is empty.
681d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                    mListView.setAdapter(null);
682d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee                }
683d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee            }
684d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee
685fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mQueryString = queryString;
686d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee            setSearchMode(!TextUtils.isEmpty(mQueryString) || mShowEmptyListForEmptyQuery);
687fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
688fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mAdapter != null) {
689fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mAdapter.setQueryString(queryString);
690fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                reloadData();
691fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
692fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
693fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
694fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
695d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee    public void setShowEmptyListForNullQuery(boolean show) {
696d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee        mShowEmptyListForEmptyQuery = show;
697d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee    }
698d5506984b9475ccafa87f957c88b8bd323a41c10Andrew Lee
6993efbe59d5252b691af58bebdc27af7ae36bf72d6Christine Chen    public int getDirectoryLoaderId() {
7003efbe59d5252b691af58bebdc27af7ae36bf72d6Christine Chen        return DIRECTORY_LOADER_ID;
7013efbe59d5252b691af58bebdc27af7ae36bf72d6Christine Chen    }
7023efbe59d5252b691af58bebdc27af7ae36bf72d6Christine Chen
703fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public int getDirectorySearchMode() {
704fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mDirectorySearchMode;
705fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
706fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
707fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setDirectorySearchMode(int mode) {
708fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDirectorySearchMode = mode;
709fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
710fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
711fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean isLegacyCompatibilityMode() {
712fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mLegacyCompatibility;
713fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
714fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
715fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setLegacyCompatibilityMode(boolean flag) {
716fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mLegacyCompatibility = flag;
717fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
718fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
719fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected int getContactNameDisplayOrder() {
720fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mDisplayOrder;
721fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
722fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
723fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void setContactNameDisplayOrder(int displayOrder) {
724fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDisplayOrder = displayOrder;
725fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mAdapter != null) {
726fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mAdapter.setContactNameDisplayOrder(displayOrder);
727fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
728fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
729fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
730fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public int getSortOrder() {
731fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mSortOrder;
732fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
733fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
734fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setSortOrder(int sortOrder) {
735fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mSortOrder = sortOrder;
736fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mAdapter != null) {
737fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mAdapter.setSortOrder(sortOrder);
738fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
739fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
740fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
741fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setDirectoryResultLimit(int limit) {
742fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDirectoryResultLimit = limit;
743fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
744fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
745fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected boolean loadPreferences() {
746fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        boolean changed = false;
747fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) {
748fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
749fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            changed = true;
750fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
751fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
752fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (getSortOrder() != mContactsPrefs.getSortOrder()) {
753fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            setSortOrder(mContactsPrefs.getSortOrder());
754fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            changed = true;
755fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
756fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
757fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return changed;
758fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
759fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
760fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
761fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public View onCreateView(LayoutInflater inflater, ViewGroup container,
762fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            Bundle savedInstanceState) {
763fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        onCreateView(inflater, container);
764fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
765fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        boolean searchMode = isSearchMode();
766fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setSearchMode(searchMode);
7673376835e9af9b2a7c04de4f7ea6bde63e5be3c23Tingting Wang        mAdapter.configureDefaultPartition(false, shouldDisplayDirectoryHeader());
768fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setPhotoLoader(mPhotoManager);
769fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setAdapter(mAdapter);
770fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
771fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (!isSearchMode()) {
772fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.setFocusableInTouchMode(true);
773fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.requestFocus();
774fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
775fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
776c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        if (savedInstanceState != null) {
777c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang            mLogListEvents = savedInstanceState.getBoolean(KEY_LOGS_LIST_EVENTS, true);
778c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang            mDataLoaded = savedInstanceState.getBoolean(KEY_DATA_LOADED, false);
779c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        }
780c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang
781fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return mView;
782fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
783fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
784fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
785fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mView = inflateView(inflater, container);
786fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
787fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView = (ListView)mView.findViewById(android.R.id.list);
788fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mListView == null) {
789fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            throw new RuntimeException(
790fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    "Your content must have a ListView whose id attribute is " +
791fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                    "'android.R.id.list'");
792fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
793fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
794fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        View emptyView = mView.findViewById(android.R.id.empty);
795fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (emptyView != null) {
796fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.setEmptyView(emptyView);
797fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
798fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
799fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setOnItemClickListener(this);
800207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell        mListView.setOnItemLongClickListener(this);
801fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setOnFocusChangeListener(this);
802fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setOnTouchListener(this);
803fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setFastScrollEnabled(!isSearchMode());
804fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
805fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        // Tell list view to not show dividers. We'll do it ourself so that we can *not* show
806fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        // them when an A-Z headers is visible.
807fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setDividerHeight(0);
808fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
809fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        // We manually save/restore the listview state
810fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mListView.setSaveEnabled(false);
811fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
812fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        configureVerticalScrollbar();
813fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        configurePhotoLoader();
814b92b637873ce501abce1d4d5cb4ce8f949a5e4fdBrian Attwell
815b92b637873ce501abce1d4d5cb4ce8f949a5e4fdBrian Attwell        getAdapter().setFragmentRootView(getView());
816fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
817fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
818fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void configurePhotoLoader() {
819fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (isPhotoLoaderEnabled() && mContext != null) {
820fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mPhotoManager == null) {
821fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mPhotoManager = ContactPhotoManager.getInstance(mContext);
822fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
823fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mListView != null) {
824fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mListView.setOnScrollListener(this);
825fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
826fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            if (mAdapter != null) {
827fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mAdapter.setPhotoLoader(mPhotoManager);
828fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            }
829fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
830fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
831fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
832fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void configureAdapter() {
833fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mAdapter == null) {
834fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            return;
835fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
836fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
837fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setQuickContactEnabled(mQuickContactEnabled);
8384683e54c3fc18fdb1207125821c818dc08d68f47Andrew Lee        mAdapter.setAdjustSelectionBoundsEnabled(mAdjustSelectionBoundsEnabled);
83925774d2e96b2c57d457dfead06776a6250ccfc84Wenyi Wang        mAdapter.setIncludeFavorites(mIncludeFavorites);
840fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setQueryString(mQueryString);
841fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setDirectorySearchMode(mDirectorySearchMode);
8429252825655f2c60d3668c0e14ab58d92b1abe62bNancy Chen        mAdapter.setPinnedPartitionHeadersEnabled(false);
843fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setContactNameDisplayOrder(mDisplayOrder);
844fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setSortOrder(mSortOrder);
845fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setSectionHeaderDisplayEnabled(mSectionHeaderDisplayEnabled);
846fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setSelectionVisible(mSelectionVisible);
847fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setDirectoryResultLimit(mDirectoryResultLimit);
848fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mAdapter.setDarkTheme(mDarkTheme);
849fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
850fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
851fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
852fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
853fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            int totalItemCount) {
854fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
855fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
856fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
857fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onScrollStateChanged(AbsListView view, int scrollState) {
858fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
859fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mPhotoManager.pause();
860fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        } else if (isPhotoLoaderEnabled()) {
861fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mPhotoManager.resume();
862fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
863fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
864fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
865fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
866fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
867fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        hideSoftKeyboard();
868fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
869fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        int adjPosition = position - mListView.getHeaderViewsCount();
870fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (adjPosition >= 0) {
871fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            onItemClick(adjPosition, id);
872fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
873fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
874fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
875207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell    @Override
876207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
877207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell        int adjPosition = position - mListView.getHeaderViewsCount();
878207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell
879207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell        if (adjPosition >= 0) {
880207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell            return onItemLongClick(adjPosition, id);
881207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell        }
882207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell        return false;
883207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell    }
884207a8774b6c245d13a5f20c0ccd16185cf7f1676Brian Attwell
885fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private void hideSoftKeyboard() {
886fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        // Hide soft keyboard, if visible
887fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        InputMethodManager inputMethodManager = (InputMethodManager)
888fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
889fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
890fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
891fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
892fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
893fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Dismisses the soft keyboard when the list takes focus.
894fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
895fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
896fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onFocusChange(View view, boolean hasFocus) {
897fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (view == mListView && hasFocus) {
898fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            hideSoftKeyboard();
899fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
900fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
901fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
902fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
903fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Dismisses the soft keyboard when the list is touched.
904fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
905fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
906fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public boolean onTouch(View view, MotionEvent event) {
907fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (view == mListView) {
908fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            hideSoftKeyboard();
909fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
910fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        return false;
911fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
912fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
913fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    @Override
914fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onPause() {
915477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen        // Save the scrolling state of the list view
916477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen        mListViewTopIndex = mListView.getFirstVisiblePosition();
917477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen        View v = mListView.getChildAt(0);
918477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen        mListViewTopOffset = (v == null) ? 0 : (v.getTop() - mListView.getPaddingTop());
919477571646c3a41de41cd2e79c7b1f6d234f7d0e3Ta-wei Yen
920fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        super.onPause();
921fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        removePendingDirectorySearchRequests();
922fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
923fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
924721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang    @Override
925721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang    public void onResume() {
926721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang        super.onResume();
927721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang        // Restore the selection of the list view. See b/19982820.
928721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang        // This has to be done manually because if the list view has its emptyView set,
929721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang        // the scrolling state will be reset when clearPartitions() is called on the adapter.
930721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang        mListView.setSelectionFromTop(mListViewTopIndex, mListViewTopOffset);
931721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang    }
932721986622a8dea8ef380ebfcca1f9c3849f2d1d6Wenyi Wang
933fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
934fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Restore the list state after the adapter is populated.
935fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
936fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    protected void completeRestoreInstanceState() {
937fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mListState != null) {
938fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListView.onRestoreInstanceState(mListState);
939fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            mListState = null;
940fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
941fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
942fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
943fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void setDarkTheme(boolean value) {
944fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        mDarkTheme = value;
945fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        if (mAdapter != null) mAdapter.setDarkTheme(value);
946fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
947fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
948fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    /**
949fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     * Processes a result returned by the contact picker.
950fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng     */
951fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    public void onPickerResult(Intent data) {
952fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        throw new UnsupportedOperationException("Picker result handler is not implemented.");
953fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    }
954fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng
955fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    private ContactsPreferences.ChangeListener mPreferencesChangeListener =
956fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            new ContactsPreferences.ChangeListener() {
957fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        @Override
958fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        public void onChange() {
959fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            loadPreferences();
960fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng            reloadData();
961fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng        }
962fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng    };
96329a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio
96429a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio    private int getDefaultVerticalScrollbarPosition() {
96529a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio        final Locale locale = Locale.getDefault();
96629a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio        final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
96729a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio        switch (layoutDirection) {
96829a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio            case View.LAYOUT_DIRECTION_RTL:
96929a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio                return View.SCROLLBAR_POSITION_LEFT;
97029a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio            case View.LAYOUT_DIRECTION_LTR:
97129a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio            default:
97229a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio                return View.SCROLLBAR_POSITION_RIGHT;
97329a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio        }
97429a5cf98565cea89f816ff473b94e6ddb043c7a8Fabrice Di Meglio    }
975c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang
976c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    public void setListType(int listType) {
977c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        mListType = listType;
978c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    }
979c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang
980c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    public int getListType() {
981c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        return mListType;
982c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    }
983c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang
984c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    public void setLogListEvents(boolean logListEvents) {
985c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang        mLogListEvents = logListEvents;
986c9ad9b1d95e0d9486ca16c1f98e946b2c87b6292Wenyi Wang    }
987fed477c6bf40e8430336278538ecc50cad9f3c7fChiao Cheng}
988