blob: aa8b80d693ce526ee2a60edf3837aa7baed368a8 [file] [log] [blame]
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -08001/*
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -07002 * Copyright (C) 2010 The Android Open Source Project
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dmitri Plotnikov27834b22010-07-01 14:10:08 -070017package com.android.contacts.activities;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080018
Dmitri Plotnikov27834b22010-07-01 14:10:08 -070019import com.android.contacts.R;
Dmitri Plotnikov9692f262010-06-29 18:53:11 -070020import com.android.contacts.interactions.ContactDeletionInteraction;
Dmitri Plotnikovaa1dffe2010-07-01 13:46:17 -070021import com.android.contacts.interactions.ImportExportInteraction;
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -070022import com.android.contacts.interactions.PhoneNumberInteraction;
Dmitri Plotnikov416b5692010-04-27 18:14:58 -070023import com.android.contacts.list.ContactBrowseListContextMenuAdapter;
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -070024import com.android.contacts.list.ContactBrowseListFragment;
Dmitri Plotnikov59fb48e2010-04-26 17:09:19 -070025import com.android.contacts.list.ContactEntryListFragment;
Dmitri Plotnikov009676f2010-10-08 12:13:57 -070026import com.android.contacts.list.ContactListFilter;
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -070027import com.android.contacts.list.ContactListFilterController;
Dmitri Plotnikov0906ee32010-04-22 10:46:00 -070028import com.android.contacts.list.ContactsIntentResolver;
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -070029import com.android.contacts.list.ContactsRequest;
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -070030import com.android.contacts.list.CustomContactListFilterActivity;
Dmitri Plotnikov238d9842010-05-04 14:14:57 -070031import com.android.contacts.list.DefaultContactBrowseListFragment;
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -070032import com.android.contacts.list.DirectoryListLoader;
Dmitri Plotnikov732f6522010-04-27 10:30:59 -070033import com.android.contacts.list.OnContactBrowserActionListener;
Dmitri Plotnikov238d9842010-05-04 14:14:57 -070034import com.android.contacts.list.StrequentContactListFragment;
Daniel Lehmann20130582010-10-21 20:51:15 -070035import com.android.contacts.model.AccountTypes;
Dmitri Plotnikovc85ad182010-09-17 18:12:49 -070036import com.android.contacts.preference.ContactsPreferenceActivity;
Daniel Lehmann20130582010-10-21 20:51:15 -070037import com.android.contacts.util.AccountsListAdapter;
Daniel Lehmann3391dbe2010-07-12 09:50:22 -070038import com.android.contacts.util.DialogManager;
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -070039import com.android.contacts.views.ContactSaveService;
Dmitri Plotnikov424440b2010-07-01 14:48:44 -070040import com.android.contacts.views.detail.ContactDetailFragment;
Dmitri Plotnikov1323d692010-04-27 14:54:27 -070041import com.android.contacts.widget.ContextMenuAdapter;
Tadashi G. Takaoka57cf30f2009-09-21 19:54:39 +090042
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -070043import android.accounts.Account;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080044import android.app.Activity;
Jeff Sharkey49d17b32009-09-07 02:14:21 -070045import android.app.Dialog;
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -070046import android.app.Fragment;
Daniel Lehmann60be1a12010-08-05 18:37:21 -070047import android.content.ActivityNotFoundException;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080048import android.content.ContentValues;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080049import android.content.Intent;
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -070050import android.content.SharedPreferences;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080051import android.net.Uri;
52import android.os.Bundle;
Dmitri Plotnikova6c21982010-10-27 10:21:16 -070053import android.os.Handler;
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -070054import android.os.Message;
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -070055import android.preference.PreferenceManager;
Dmitri Plotnikovd7c4af22009-06-19 18:31:00 -070056import android.provider.ContactsContract;
Jeff Hamiltone0529662009-08-21 02:43:47 -050057import android.provider.ContactsContract.Contacts;
Daniel Lehmann20130582010-10-21 20:51:15 -070058import android.provider.ContactsContract.Intents;
Dmitri Plotnikov9692f262010-06-29 18:53:11 -070059import android.provider.Settings;
Daniel Lehmanna35a7e22010-08-03 18:13:14 -070060import android.util.Log;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080061import android.view.KeyEvent;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080062import android.view.Menu;
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -070063import android.view.MenuInflater;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080064import android.view.MenuItem;
65import android.view.View;
Daniel Lehmann20130582010-10-21 20:51:15 -070066import android.view.View.OnClickListener;
Dmitri Plotnikov4af3b072010-07-01 18:40:51 -070067import android.view.Window;
Daniel Lehmann20130582010-10-21 20:51:15 -070068import android.widget.AdapterView;
69import android.widget.AdapterView.OnItemClickListener;
70import android.widget.ImageView;
71import android.widget.ListPopupWindow;
Dmitri Plotnikov424440b2010-07-01 14:48:44 -070072import android.widget.Toast;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080073
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -070074import java.util.ArrayList;
75
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080076/**
Daniel Lehmannbd772a52010-07-14 11:22:13 -070077 * Displays a list to browse contacts. For xlarge screens, this also displays a detail-pane on
78 * the right
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080079 */
Dmitri Plotnikovcfa39002010-07-09 18:05:17 -070080public class ContactBrowserActivity extends Activity
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -070081 implements View.OnCreateContextMenuListener, ActionBarAdapter.Listener,
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -070082 DialogManager.DialogShowingViewActivity,
83 ContactListFilterController.ContactListFilterListener {
Dmitri Plotnikov57d27da2009-09-28 18:06:11 -070084
Daniel Lehmannbd772a52010-07-14 11:22:13 -070085 private static final String TAG = "ContactBrowserActivity";
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080086
Daniel Lehmann22fb2052010-07-27 19:59:21 -070087 private static final int SUBACTIVITY_NEW_CONTACT = 2;
Dmitri Plotnikovc85ad182010-09-17 18:12:49 -070088 private static final int SUBACTIVITY_SETTINGS = 3;
Dmitri Plotnikov8c6955f2010-09-08 20:46:36 -070089 private static final int SUBACTIVITY_EDIT_CONTACT = 4;
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -070090 private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 5;
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -070091
Dmitri Plotnikov61835402010-09-27 18:29:02 -070092 private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20;
93
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -070094 /**
95 * The id for a delayed message that triggers automatic selection of the first
96 * found contact in search mode.
97 */
98 private static final int MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT = 1;
99
100 /**
101 * The delay that is used for automatically selecting the first found contact.
102 */
103 private static final int DELAY_AUTOSELECT_FIRST_FOUND_CONTACT_MILLIS = 500;
104
105 /**
106 * The minimum number of characters in the search query that is required
107 * before we automatically select the first found contact.
108 */
109 private static final int AUTOSELECT_FIRST_FOUND_CONTACT_MIN_QUERY_LENGTH = 2;
110
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700111 private static final String KEY_SEARCH_MODE = "searchMode";
112
Daniel Lehmann3b7d5942010-07-22 18:10:50 -0700113 private DialogManager mDialogManager = new DialogManager(this);
Daniel Lehmann3391dbe2010-07-12 09:50:22 -0700114
Dmitri Plotnikovac0f7832010-04-22 13:26:52 -0700115 private ContactsIntentResolver mIntentResolver;
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700116 private ContactsRequest mRequest;
117
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700118 private SharedPreferences mPrefs;
119
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700120 private boolean mHasActionBar;
121 private ActionBarAdapter mActionBarAdapter;
122
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700123 private boolean mSearchMode;
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700124
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700125 private ContactBrowseListFragment mListFragment;
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700126 private boolean mContactContentDisplayed;
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700127 private ContactDetailFragment mDetailFragment;
128 private DetailFragmentListener mDetailFragmentListener = new DetailFragmentListener();
129
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700130 private PhoneNumberInteraction mPhoneNumberCallInteraction;
131 private PhoneNumberInteraction mSendTextMessageInteraction;
132 private ContactDeletionInteraction mContactDeletionInteraction;
133 private ImportExportInteraction mImportExportInteraction;
134
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700135 private boolean mSearchInitiated;
136
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700137 private ContactListFilterController mContactListFilterController;
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700138
Daniel Lehmann20130582010-10-21 20:51:15 -0700139 private ImageView mAddContactImageView;
140
Dmitri Plotnikova6c21982010-10-27 10:21:16 -0700141 private Handler mHandler;
142
Dmitri Plotnikovcfa39002010-07-09 18:05:17 -0700143 public ContactBrowserActivity() {
Dmitri Plotnikov15406742010-05-07 09:22:49 -0700144 mIntentResolver = new ContactsIntentResolver(this);
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700145 mContactListFilterController = new ContactListFilterController(this);
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700146 mContactListFilterController.addListener(this);
Dmitri Plotnikov6178cb42010-04-20 11:26:05 -0700147 }
148
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700149 private Handler getHandler() {
150 if (mHandler == null) {
151 mHandler = new Handler() {
152 @Override
153 public void handleMessage(Message msg) {
154 if (msg.what == MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT) {
155 selectFirstFoundContact();
156 }
157 }
158 };
159 }
160 return mHandler;
161 }
162
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800163 @Override
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -0700164 public void onAttachFragment(Fragment fragment) {
165 if (fragment instanceof ContactBrowseListFragment) {
166 mListFragment = (ContactBrowseListFragment)fragment;
167 mListFragment.setOnContactListActionListener(new ContactBrowserActionListener());
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700168 restoreListSelection();
Dmitri Plotnikovd3643142010-07-09 13:49:07 -0700169 } else if (fragment instanceof ContactDetailFragment) {
170 mDetailFragment = (ContactDetailFragment)fragment;
171 mDetailFragment.setListener(mDetailFragmentListener);
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -0700172 }
173 }
174
175 @Override
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700176 protected void onCreate(Bundle savedState) {
177 super.onCreate(savedState);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800178
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -0700179 if (savedState != null) {
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700180 mSearchMode = savedState.getBoolean(KEY_SEARCH_MODE);
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -0700181 }
182
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700183 // Extract relevant information from the intent
184 mRequest = mIntentResolver.resolveIntent(getIntent());
185 if (!mRequest.isValid()) {
186 setResult(RESULT_CANCELED);
187 finish();
Dmitri Plotnikov59fb48e2010-04-26 17:09:19 -0700188 return;
189 }
190
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700191 Intent redirect = mRequest.getRedirectIntent();
192 if (redirect != null) {
193 // Need to start a different activity
194 startActivity(redirect);
195 finish();
196 return;
197 }
198
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700199 mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
200
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700201 setTitle(mRequest.getActivityTitle());
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700202 setContentView(R.layout.contact_browser);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700203
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700204 mHasActionBar = getWindow().hasFeature(Window.FEATURE_ACTION_BAR);
Dmitri Plotnikov65ad5ee2010-07-15 18:09:21 -0700205 mContactContentDisplayed = findViewById(R.id.detail_container) != null;
206
Dmitri Plotnikov27b97bc2010-10-07 18:06:09 -0700207 if (mRequest.getActionCode() == ContactsRequest.ACTION_VIEW_CONTACT) {
Dmitri Plotnikov27b97bc2010-10-07 18:06:09 -0700208 if (!mContactContentDisplayed) {
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700209 startActivity(new Intent(Intent.ACTION_VIEW, mRequest.getContactUri()));
Dmitri Plotnikov27b97bc2010-10-07 18:06:09 -0700210 finish();
211 return;
212 }
213 }
214
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700215 if (mHasActionBar) {
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700216 mActionBarAdapter = new ActionBarAdapter(this);
Dmitri Plotnikov1a59cff2010-09-18 12:50:45 -0700217 mActionBarAdapter.onCreate(savedState, mRequest, getActionBar());
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700218 mActionBarAdapter.setContactListFilterController(mContactListFilterController);
219 // TODO: request may ask for FREQUENT - set the filter accordingly
Daniel Lehmann20130582010-10-21 20:51:15 -0700220 mAddContactImageView = new ImageView(this);
221 mAddContactImageView.setImageResource(R.drawable.ic_menu_add_contact);
222 mAddContactImageView.setContentDescription(getString(R.string.menu_newContact));
223 mAddContactImageView.setOnClickListener(new OnClickListener() {
224 @Override
225 public void onClick(View v) {
226 createNewContact();
227 }
228 });
Dmitri Plotnikovfe42e552010-05-14 14:50:32 -0700229 }
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700230
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700231 configureListFragment(true /* from request */);
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700232
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700233 if (mContactContentDisplayed) {
234 setupContactDetailFragment(mListFragment.getSelectedContactUri());
235 }
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700236 }
237
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700238 @Override
239 protected void onNewIntent(Intent intent) {
240 super.onNewIntent(intent);
241 if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700242 mRequest = mIntentResolver.resolveIntent(getIntent());
243
244 Uri uri = mRequest.getContactUri();
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700245 if (uri == null) {
246 return;
247 }
248
249 if (mHasActionBar) {
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700250 mActionBarAdapter.setSearchMode(false);
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700251 }
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700252
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700253 mListFragment.setSelectedContactUri(uri);
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700254 mListFragment.requestSelectionOnScreen(true);
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700255 if (mContactContentDisplayed) {
256 setupContactDetailFragment(uri);
257 }
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700258 }
259 }
260
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700261 @Override
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700262 protected void onPause() {
263 if (mActionBarAdapter != null) {
264 mActionBarAdapter.setListener(null);
265 }
266 super.onPause();
267 }
268
269 @Override
270 protected void onResume() {
271 super.onResume();
272 if (mActionBarAdapter != null) {
273 mActionBarAdapter.setListener(this);
274 }
275 }
276
277 @Override
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700278 protected void onStart() {
279 if (mContactListFilterController != null) {
280 mContactListFilterController.startLoading();
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700281 }
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700282 super.onStart();
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700283 }
284
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700285 private void configureListFragment(boolean fromRequest) {
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700286 boolean searchMode = mSearchMode;
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700287 if (fromRequest) {
Dmitri Plotnikov91ab5b42010-10-08 15:26:31 -0700288 ContactListFilter filter = null;
289 int actionCode = mRequest.getActionCode();
290 switch (actionCode) {
291 case ContactsRequest.ACTION_ALL_CONTACTS:
292 filter = new ContactListFilter(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
293 break;
294 case ContactsRequest.ACTION_CONTACTS_WITH_PHONES:
295 filter = new ContactListFilter(
296 ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY);
297 break;
298
299 // TODO: handle FREQUENT and STREQUENT according to the spec
300 case ContactsRequest.ACTION_FREQUENT:
301 case ContactsRequest.ACTION_STREQUENT:
302 // For now they are treated the same as STARRED
303 case ContactsRequest.ACTION_STARRED:
304 filter = new ContactListFilter(ContactListFilter.FILTER_TYPE_STARRED);
305 break;
306 }
307
308 if (filter != null) {
309 mContactListFilterController.setContactListFilter(filter, false);
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700310 searchMode = false;
Dmitri Plotnikov48cc2502010-10-08 14:56:04 -0700311 } else if (mRequest.getActionCode() == ContactsRequest.ACTION_ALL_CONTACTS) {
312 mContactListFilterController.setContactListFilter(new ContactListFilter(
313 ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS), false);
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700314 }
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700315 } else {
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700316 if (mHasActionBar) {
317 searchMode = mActionBarAdapter.isSearchMode();
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700318 }
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700319 }
320
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700321 boolean replaceList = mListFragment == null || (mSearchMode != searchMode);
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700322 if (replaceList) {
323 closeListFragment();
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700324 mSearchMode = searchMode;
325 if (mSearchMode) {
326 mListFragment = createContactSearchFragment();
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700327 // When switching to the search mode, erase previous state of the search UI
328 mListFragment.saveSelectedUri(mPrefs);
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700329 } else {
330 mListFragment = createListFragment(ContactsRequest.ACTION_DEFAULT);
Dmitri Plotnikovab4d29f2010-10-28 12:43:54 -0700331 mListFragment.requestSelectionOnScreen(false);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700332 }
333 }
334
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700335 if (mHasActionBar && mSearchMode) {
336 mListFragment.setQueryString(mActionBarAdapter.getQueryString());
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700337 }
Dmitri Plotnikovcfc64892010-07-09 17:55:09 -0700338
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700339 if (fromRequest) {
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700340 Uri selectUri = mRequest.getContactUri();
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700341 if (selectUri != null) {
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700342 mListFragment.setSelectedContactUri(selectUri);
343 mListFragment.requestSelectionOnScreen(false);
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700344 }
345 }
346
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700347 if (replaceList) {
Daniel Lehmann3514fd32010-08-19 14:45:26 -0700348 getFragmentManager().openTransaction()
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700349 .replace(R.id.list_container, mListFragment)
350 .commit();
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700351
352 if (mContactContentDisplayed) {
353 setupContactDetailFragment(mListFragment.getSelectedContactUri());
354 }
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700355 }
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700356 }
357
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -0700358 private void closeListFragment() {
359 if (mListFragment != null) {
360 mListFragment.setOnContactListActionListener(null);
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700361 mListFragment = null;
Dmitri Plotnikov92a6fdf2010-07-09 13:19:33 -0700362 }
363 }
364
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700365 @Override
366 public void onContactListFiltersLoaded() {
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700367 restoreListSelection();
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700368
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700369 // Filters have been loaded - now we can start loading the list itself
370 mListFragment.startLoading();
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700371 }
372
373 @Override
374 public void onContactListFilterChanged() {
375 // If there was a request to show a specific contact, that's no longer the case
376 // because the user has explicitly changed the filter.
377 mRequest.setContactUri(null);
378
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700379 restoreListSelection();
380 mListFragment.reloadData();
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700381 }
382
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700383 /**
384 * Restores filter-specific persistent selection.
385 */
386 private void restoreListSelection() {
387 if (mListFragment instanceof DefaultContactBrowseListFragment
388 && mContactListFilterController != null
389 && mContactListFilterController.isLoaded()) {
390 DefaultContactBrowseListFragment fragment =
391 (DefaultContactBrowseListFragment) mListFragment;
392 fragment.setFilter(mContactListFilterController.getFilter());
393 fragment.restoreSelectedUri(mPrefs);
394 fragment.requestSelectionOnScreen(false);
395 }
396
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700397 if (mContactContentDisplayed) {
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700398 setupContactDetailFragment(mListFragment.getSelectedContactUri());
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700399 }
400 }
401
Dmitri Plotnikov3ad2f352010-10-28 22:37:51 -0700402 private void showDefaultSelection() {
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700403 if (mSearchMode) {
404 selectFirstFoundContactAfterDelay();
405 return;
406 }
407
Dmitri Plotnikov3ad2f352010-10-28 22:37:51 -0700408 Uri requestedContactUri = mRequest.getContactUri();
409 if (requestedContactUri != null
410 && mListFragment instanceof DefaultContactBrowseListFragment) {
411 // If a specific selection was requested, adjust the filter so
412 // that the requested selection is unconditionally visible.
413 DefaultContactBrowseListFragment fragment =
414 (DefaultContactBrowseListFragment) mListFragment;
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700415 ContactListFilter filter =
416 new ContactListFilter(ContactListFilter.FILTER_TYPE_SINGLE_CONTACT);
Dmitri Plotnikov3ad2f352010-10-28 22:37:51 -0700417 fragment.setFilter(filter);
418 fragment.setSelectedContactUri(requestedContactUri);
419 fragment.saveSelectedUri(mPrefs);
420 fragment.reloadData();
421 if (mContactListFilterController != null) {
422 mContactListFilterController.setContactListFilter(filter, true);
423 }
424 } else {
425 // Otherwise, choose the first contact on the list and select it
426 requestedContactUri = mListFragment.getFirstContactUri();
427 if (requestedContactUri != null) {
428 mListFragment.setSelectedContactUri(requestedContactUri);
429 mListFragment.requestSelectionOnScreen(false);
430 }
431 }
432 if (mContactContentDisplayed) {
433 setupContactDetailFragment(requestedContactUri);
434 }
435 }
436
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700437 /**
438 * Automatically selects the first found contact in search mode. The selection
439 * is updated after a delay to allow the user to type without to much UI churn
440 * and to save bandwidth on directory queries.
441 */
442 public void selectFirstFoundContactAfterDelay() {
443 Handler handler = getHandler();
444 handler.removeMessages(MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT);
445 handler.sendEmptyMessageDelayed(MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT,
446 DELAY_AUTOSELECT_FIRST_FOUND_CONTACT_MILLIS);
447 }
448
449 /**
450 * Selects the first contact in the list in search mode.
451 */
452 protected void selectFirstFoundContact() {
453 if (!mSearchMode) {
454 return;
455 }
456
457 Uri selectedUri = null;
458 String queryString = mListFragment.getQueryString();
459 if (queryString != null
460 && queryString.length() >= AUTOSELECT_FIRST_FOUND_CONTACT_MIN_QUERY_LENGTH) {
461 selectedUri = mListFragment.getFirstContactUri();
462 }
463
464 mListFragment.setSelectedContactUri(selectedUri);
465 if (mContactContentDisplayed) {
466 setupContactDetailFragment(selectedUri);
467 }
468 }
469
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700470 @Override
471 public void onContactListFilterCustomizationRequest() {
472 startActivityForResult(new Intent(this, CustomContactListFilterActivity.class),
473 SUBACTIVITY_CUSTOMIZE_FILTER);
474 }
475
Dmitri Plotnikova6c21982010-10-27 10:21:16 -0700476 private void setupContactDetailFragment(final Uri contactLookupUri) {
Dmitri Plotnikov9cd17082010-07-09 14:10:04 -0700477 if (mDetailFragment != null && contactLookupUri != null
478 && contactLookupUri.equals(mDetailFragment.getUri())) {
479 return;
480 }
481
Dmitri Plotnikov174fdc22010-10-29 13:55:01 -0700482 if (mDetailFragment == null) {
483 mDetailFragment = new ContactDetailFragment();
484 getFragmentManager().openTransaction()
485 .replace(R.id.detail_container, mDetailFragment)
486 .commit();
Dmitri Plotnikovc0ca13a2010-07-08 14:25:37 -0700487 }
Dmitri Plotnikovc0ca13a2010-07-08 14:25:37 -0700488
Dmitri Plotnikov3ad2f352010-10-28 22:37:51 -0700489 mDetailFragment.loadUri(contactLookupUri);
Dmitri Plotnikovc0ca13a2010-07-08 14:25:37 -0700490 }
491
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700492 /**
493 * Handler for action bar actions.
494 */
Dmitri Plotnikovfe42e552010-05-14 14:50:32 -0700495 @Override
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700496 public void onAction() {
Dmitri Plotnikov009676f2010-10-08 12:13:57 -0700497 configureListFragment(false /* from request */);
Dmitri Plotnikovfe42e552010-05-14 14:50:32 -0700498 }
499
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700500 /**
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700501 * Creates the list fragment for the specified mode.
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700502 */
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700503 private ContactBrowseListFragment createListFragment(int actionCode) {
504 switch (actionCode) {
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700505 case ContactsRequest.ACTION_DEFAULT: {
Dmitri Plotnikov238d9842010-05-04 14:14:57 -0700506 DefaultContactBrowseListFragment fragment = new DefaultContactBrowseListFragment();
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700507 fragment.setContactsRequest(mRequest);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700508 fragment.setOnContactListActionListener(new ContactBrowserActionListener());
Dmitri Plotnikovd94c3eb2010-10-08 13:41:12 -0700509 if (!mHasActionBar) {
510 fragment.setContextMenuAdapter(
511 new ContactBrowseListContextMenuAdapter(fragment));
512 }
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700513 fragment.setSearchMode(mRequest.isSearchMode());
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700514 fragment.setQueryString(mRequest.getQueryString());
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -0700515 if (mRequest.isSearchMode() && mRequest.isDirectorySearchEnabled()) {
516 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
517 } else {
518 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
519 }
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700520 fragment.setAizyEnabled(!mRequest.isSearchMode());
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700521 fragment.setSelectionVisible(mContactContentDisplayed);
Dmitri Plotnikov39709a62010-09-03 11:15:30 -0700522 fragment.setQuickContactEnabled(!mContactContentDisplayed);
Dmitri Plotnikov1799e6d2010-09-16 15:51:17 -0700523 fragment.setFilterEnabled(!mRequest.isSearchMode());
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700524 return fragment;
Dmitri Plotnikov59fb48e2010-04-26 17:09:19 -0700525 }
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700526
527 case ContactsRequest.ACTION_GROUP: {
528 throw new UnsupportedOperationException("Not yet implemented");
529 }
530
531 case ContactsRequest.ACTION_STARRED: {
Dmitri Plotnikov238d9842010-05-04 14:14:57 -0700532 StrequentContactListFragment fragment = new StrequentContactListFragment();
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700533 fragment.setOnContactListActionListener(new ContactBrowserActionListener());
534 fragment.setFrequentlyContactedContactsIncluded(false);
535 fragment.setStarredContactsIncluded(true);
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700536 fragment.setSelectionVisible(mContactContentDisplayed);
Dmitri Plotnikov39709a62010-09-03 11:15:30 -0700537 fragment.setQuickContactEnabled(!mContactContentDisplayed);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700538 return fragment;
Dmitri Plotnikov238d9842010-05-04 14:14:57 -0700539 }
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700540
541 case ContactsRequest.ACTION_FREQUENT: {
542 StrequentContactListFragment fragment = new StrequentContactListFragment();
543 fragment.setOnContactListActionListener(new ContactBrowserActionListener());
544 fragment.setFrequentlyContactedContactsIncluded(true);
545 fragment.setStarredContactsIncluded(false);
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700546 fragment.setSelectionVisible(mContactContentDisplayed);
Dmitri Plotnikov39709a62010-09-03 11:15:30 -0700547 fragment.setQuickContactEnabled(!mContactContentDisplayed);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700548 return fragment;
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700549 }
550
551 case ContactsRequest.ACTION_STREQUENT: {
552 StrequentContactListFragment fragment = new StrequentContactListFragment();
553 fragment.setOnContactListActionListener(new ContactBrowserActionListener());
554 fragment.setFrequentlyContactedContactsIncluded(true);
555 fragment.setStarredContactsIncluded(true);
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700556 fragment.setSelectionVisible(mContactContentDisplayed);
Dmitri Plotnikov39709a62010-09-03 11:15:30 -0700557 fragment.setQuickContactEnabled(!mContactContentDisplayed);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700558 return fragment;
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700559 }
560
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700561 default:
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700562 throw new IllegalStateException("Invalid action code: " + actionCode);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700563 }
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700564 }
565
566 private ContactBrowseListFragment createContactSearchFragment() {
567 DefaultContactBrowseListFragment fragment = new DefaultContactBrowseListFragment();
568 fragment.setOnContactListActionListener(new ContactBrowserActionListener());
Dmitri Plotnikovd94c3eb2010-10-08 13:41:12 -0700569 if (!mHasActionBar) {
570 fragment.setContextMenuAdapter(new ContactBrowseListContextMenuAdapter(fragment));
571 }
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700572 fragment.setSearchMode(true);
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -0700573 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
Dmitri Plotnikov61835402010-09-27 18:29:02 -0700574 fragment.setDirectoryResultLimit(DEFAULT_DIRECTORY_RESULT_LIMIT);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700575 fragment.setAizyEnabled(false);
Dmitri Plotnikov0d577492010-07-08 13:14:45 -0700576 fragment.setSelectionVisible(true);
Dmitri Plotnikov73216882010-09-10 18:31:34 -0700577 fragment.setQuickContactEnabled(!mContactContentDisplayed);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700578 return fragment;
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700579 }
580
581 private final class ContactBrowserActionListener implements OnContactBrowserActionListener {
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700582 @Override
583 public void onViewContactAction(Uri contactLookupUri) {
Dmitri Plotnikove1d4c062010-07-15 16:20:36 -0700584 if (mContactContentDisplayed) {
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700585 mListFragment.setSelectedContactUri(contactLookupUri);
586 mListFragment.saveSelectedUri(mPrefs);
Dmitri Plotnikovd3643142010-07-09 13:49:07 -0700587 setupContactDetailFragment(contactLookupUri);
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700588 } else {
589 startActivity(new Intent(Intent.ACTION_VIEW, contactLookupUri));
590 }
Dmitri Plotnikov26cda1a2010-04-08 17:21:36 -0700591 }
Dmitri Plotnikov59fb48e2010-04-26 17:09:19 -0700592
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700593 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700594 public void onCreateNewContactAction() {
595 Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
596 Bundle extras = getIntent().getExtras();
597 if (extras != null) {
598 intent.putExtras(extras);
599 }
600 startActivity(intent);
601 }
602
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700603 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700604 public void onEditContactAction(Uri contactLookupUri) {
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700605 Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri);
606 Bundle extras = getIntent().getExtras();
607 if (extras != null) {
608 intent.putExtras(extras);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700609 }
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700610 startActivityForResult(intent, SUBACTIVITY_EDIT_CONTACT);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700611 }
612
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700613 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700614 public void onAddToFavoritesAction(Uri contactUri) {
615 ContentValues values = new ContentValues(1);
616 values.put(Contacts.STARRED, 1);
617 getContentResolver().update(contactUri, values, null, null);
618 }
619
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700620 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700621 public void onRemoveFromFavoritesAction(Uri contactUri) {
622 ContentValues values = new ContentValues(1);
623 values.put(Contacts.STARRED, 0);
624 getContentResolver().update(contactUri, values, null, null);
625 }
626
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700627 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700628 public void onCallContactAction(Uri contactUri) {
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700629 getPhoneNumberCallInteraction().startInteraction(contactUri);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700630 }
631
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700632 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700633 public void onSmsContactAction(Uri contactUri) {
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700634 getSendTextMessageInteraction().startInteraction(contactUri);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700635 }
636
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700637 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700638 public void onDeleteContactAction(Uri contactUri) {
Dmitri Plotnikov9692f262010-06-29 18:53:11 -0700639 getContactDeletionInteraction().deleteContact(contactUri);
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700640 }
641
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700642 @Override
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700643 public void onFinishAction() {
644 onBackPressed();
645 }
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700646
647 @Override
648 public void onInvalidSelection() {
Dmitri Plotnikov3ad2f352010-10-28 22:37:51 -0700649 showDefaultSelection();
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700650 }
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700651 }
652
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700653 private class DetailFragmentListener implements ContactDetailFragment.Listener {
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700654 @Override
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700655 public void onContactNotFound() {
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700656 setupContactDetailFragment(null);
Dmitri Plotnikov3ad2f352010-10-28 22:37:51 -0700657 mRequest.setContactUri(null);
658 showDefaultSelection();
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700659 }
660
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700661 @Override
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700662 public void onEditRequested(Uri contactLookupUri) {
Dmitri Plotnikov8c6955f2010-09-08 20:46:36 -0700663 startActivityForResult(
664 new Intent(Intent.ACTION_EDIT, contactLookupUri), SUBACTIVITY_EDIT_CONTACT);
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700665 }
666
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700667 @Override
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700668 public void onItemClicked(Intent intent) {
Daniel Lehmann60be1a12010-08-05 18:37:21 -0700669 try {
670 startActivity(intent);
671 } catch (ActivityNotFoundException e) {
672 Log.e(TAG, "No activity found for intent: " + intent);
673 }
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700674 }
675
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700676 @Override
677 public void onDeleteRequested(Uri contactLookupUri) {
678 getContactDeletionInteraction().deleteContact(contactLookupUri);
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700679 }
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700680
681 @Override
682 public void onCreateRawContactRequested(ArrayList<ContentValues> values, Account account) {
683 Toast.makeText(ContactBrowserActivity.this, R.string.toast_making_personal_copy,
684 Toast.LENGTH_LONG).show();
685 Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
686 ContactBrowserActivity.this, values, account);
687 startService(serviceIntent);
688 }
Dmitri Plotnikov424440b2010-07-01 14:48:44 -0700689 }
690
Dmitri Plotnikov732f6522010-04-27 10:30:59 -0700691 public void startActivityAndForwardResult(final Intent intent) {
692 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
693
694 // Forward extras to the new activity
695 Bundle extras = getIntent().getExtras();
696 if (extras != null) {
697 intent.putExtras(extras);
698 }
699 startActivity(intent);
700 finish();
701 }
702
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800703 @Override
704 public boolean onCreateOptionsMenu(Menu menu) {
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700705 super.onCreateOptionsMenu(menu);
706
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700707 MenuInflater inflater = getMenuInflater();
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700708 if (mHasActionBar) {
Dmitri Plotnikov4af3b072010-07-01 18:40:51 -0700709 inflater.inflate(R.menu.actions, menu);
Daniel Lehmann20130582010-10-21 20:51:15 -0700710
711 // Change add contact button to button with a custom view
712 final MenuItem addContact = menu.findItem(R.id.menu_add);
713 addContact.setActionView(mAddContactImageView);
Dmitri Plotnikov4af3b072010-07-01 18:40:51 -0700714 return true;
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700715 } else if (mRequest.getActionCode() == ContactsRequest.ACTION_DEFAULT ||
716 mRequest.getActionCode() == ContactsRequest.ACTION_STREQUENT) {
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700717 inflater.inflate(R.menu.list, menu);
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700718 return true;
719 } else if (!mListFragment.isSearchMode()) {
720 inflater.inflate(R.menu.search, menu);
721 return true;
722 } else {
723 return false;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800724 }
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700725 }
Jeff Sharkey3f0b7b82009-08-12 11:28:53 -0700726
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700727 @Override
728 public boolean onPrepareOptionsMenu(Menu menu) {
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700729 MenuItem displayGroups = menu.findItem(R.id.menu_display_groups);
730 if (displayGroups != null) {
731 displayGroups.setVisible(
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700732 mRequest.getActionCode() == ContactsRequest.ACTION_DEFAULT);
Dmitri Plotnikov4af3b072010-07-01 18:40:51 -0700733 }
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700734 return true;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800735 }
736
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800737 @Override
738 public boolean onOptionsItemSelected(MenuItem item) {
739 switch (item.getItemId()) {
Dmitri Plotnikovc85ad182010-09-17 18:12:49 -0700740 case R.id.menu_settings: {
741 final Intent intent = new Intent(this, ContactsPreferenceActivity.class);
742 startActivityForResult(intent, SUBACTIVITY_SETTINGS);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800743 return true;
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700744 }
745 case R.id.menu_search: {
Dmitri Plotnikov8e86b752010-02-22 17:47:57 -0800746 onSearchRequested();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800747 return true;
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700748 }
749 case R.id.menu_add: {
750 final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
Daniel Lehmann22fb2052010-07-27 19:59:21 -0700751 startActivityForResult(intent, SUBACTIVITY_NEW_CONTACT);
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700752 return true;
753 }
Jeff Sharkey49d17b32009-09-07 02:14:21 -0700754 case R.id.menu_import_export: {
Dmitri Plotnikovaa1dffe2010-07-01 13:46:17 -0700755 getImportExportInteraction().startInteraction();
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700756 return true;
757 }
758 case R.id.menu_accounts: {
759 final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
Dmitri Plotnikovfe42e552010-05-14 14:50:32 -0700760 intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700761 ContactsContract.AUTHORITY
762 });
763 startActivity(intent);
764 return true;
765 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800766 }
767 return false;
768 }
769
Daniel Lehmann20130582010-10-21 20:51:15 -0700770 private void createNewContact() {
771 final ArrayList<Account> accounts =
772 AccountTypes.getInstance(this).getAccounts(true);
773 if (accounts.size() <= 1 || mAddContactImageView == null) {
774 // No account to choose or no control to anchor the popup-menu to
775 // ==> just go straight to the editor which will disambig if necessary
776 final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
777 startActivityForResult(intent, SUBACTIVITY_NEW_CONTACT);
778 return;
779 }
780
781 final ListPopupWindow popup = new ListPopupWindow(this, null);
782 popup.setWidth(getResources().getDimensionPixelSize(R.dimen.account_selector_popup_width));
783 popup.setAnchorView(mAddContactImageView);
784 final AccountsListAdapter adapter = new AccountsListAdapter(this, true);
785 popup.setAdapter(adapter);
786 popup.setOnItemClickListener(new OnItemClickListener() {
787 @Override
788 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
789 popup.dismiss();
790 final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
791 intent.putExtra(Intents.Insert.ACCOUNT, adapter.getItem(position));
792 startActivityForResult(intent, SUBACTIVITY_NEW_CONTACT);
793 }
794 });
795 popup.setModal(true);
796 popup.show();
797 }
798
Dmitri Plotnikov8e86b752010-02-22 17:47:57 -0800799 @Override
800 public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
801 boolean globalSearch) {
Dmitri Plotnikov12def9d2010-05-06 18:13:12 -0700802// TODO
803// if (mProviderStatus != ProviderStatus.STATUS_NORMAL) {
804// return;
805// }
Dmitri Plotnikov3b73d8b2010-03-12 19:28:21 -0800806
Dmitri Plotnikov8e86b752010-02-22 17:47:57 -0800807 if (globalSearch) {
808 super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
809 } else {
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700810 mListFragment.startSearch(initialQuery);
Dmitri Plotnikovdb3d1432010-02-09 17:45:47 -0800811 }
Dmitri Plotnikovdb3d1432010-02-09 17:45:47 -0800812 }
813
Jeff Sharkey49d17b32009-09-07 02:14:21 -0700814 @Override
Dmitri Plotnikov3b73d8b2010-03-12 19:28:21 -0800815 protected Dialog onCreateDialog(int id, Bundle bundle) {
Daniel Lehmann3b7d5942010-07-22 18:10:50 -0700816 if (DialogManager.isManagedId(id)) return mDialogManager.onCreateDialog(id, bundle);
Daniel Lehmann3391dbe2010-07-12 09:50:22 -0700817
Dmitri Plotnikov9692f262010-06-29 18:53:11 -0700818 Dialog dialog = getContactDeletionInteraction().onCreateDialog(id, bundle);
Daniel Lehmanna35a7e22010-08-03 18:13:14 -0700819 if (dialog != null) return dialog;
Dmitri Plotnikov9692f262010-06-29 18:53:11 -0700820
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700821 dialog = getPhoneNumberCallInteraction().onCreateDialog(id, bundle);
Daniel Lehmanna35a7e22010-08-03 18:13:14 -0700822 if (dialog != null) return dialog;
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700823
824 dialog = getSendTextMessageInteraction().onCreateDialog(id, bundle);
Daniel Lehmanna35a7e22010-08-03 18:13:14 -0700825 if (dialog != null) return dialog;
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700826
Dmitri Plotnikovaa1dffe2010-07-01 13:46:17 -0700827 dialog = getImportExportInteraction().onCreateDialog(id, bundle);
Daniel Lehmanna35a7e22010-08-03 18:13:14 -0700828 if (dialog != null) return dialog;
Dmitri Plotnikovaa1dffe2010-07-01 13:46:17 -0700829
Dmitri Plotnikov3b73d8b2010-03-12 19:28:21 -0800830 return super.onCreateDialog(id, bundle);
Jeff Sharkey49d17b32009-09-07 02:14:21 -0700831 }
832
Dmitri Plotnikov9692f262010-06-29 18:53:11 -0700833 @Override
834 protected void onPrepareDialog(int id, Dialog dialog, Bundle bundle) {
835 if (getContactDeletionInteraction().onPrepareDialog(id, dialog, bundle)) {
836 return;
837 }
838
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700839 if (getPhoneNumberCallInteraction().onPrepareDialog(id, dialog, bundle)) {
840 return;
841 }
842
843 if (getSendTextMessageInteraction().onPrepareDialog(id, dialog, bundle)) {
844 return;
845 }
846
Dmitri Plotnikov9692f262010-06-29 18:53:11 -0700847 super.onPrepareDialog(id, dialog, bundle);
848 }
Jeff Sharkeyd9798ae2009-08-24 20:46:23 -0700849
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700850 @Override
851 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
852 switch (requestCode) {
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700853 case SUBACTIVITY_CUSTOMIZE_FILTER: {
854 if (resultCode == Activity.RESULT_OK) {
855 mContactListFilterController.selectCustomFilter();
856 }
857 break;
858 }
Dmitri Plotnikov8c6955f2010-09-08 20:46:36 -0700859 case SUBACTIVITY_EDIT_CONTACT: {
Dmitri Plotnikov3c69e212010-09-27 11:43:39 -0700860 mListFragment.requestSelectionOnScreen(true);
Dmitri Plotnikov8c6955f2010-09-08 20:46:36 -0700861 break;
862 }
863
Daniel Lehmann22fb2052010-07-27 19:59:21 -0700864 case SUBACTIVITY_NEW_CONTACT: {
865 if (resultCode == RESULT_OK && mContactContentDisplayed) {
866 final Uri newContactUri = data.getData();
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700867 if (mContactContentDisplayed) {
868 setupContactDetailFragment(newContactUri);
869 }
870
871 mRequest.setActionCode(ContactsRequest.ACTION_VIEW_CONTACT);
872 mRequest.setContactUri(newContactUri);
873 mListFragment.setSelectedContactUri(newContactUri);
874 mListFragment.saveSelectedUri(mPrefs);
875 mListFragment.requestSelectionOnScreen(true);
Daniel Lehmann22fb2052010-07-27 19:59:21 -0700876 }
877 break;
878 }
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700879
Dmitri Plotnikovc85ad182010-09-17 18:12:49 -0700880 case SUBACTIVITY_SETTINGS:
Daniel Lehmann7aa9b282010-07-27 20:33:27 -0700881 // TODO: Force the ListFragment to reload its setting and update (don't lookup
882 // directories here)
883 break;
884
885 // TODO: Using the new startActivityWithResultFromFragment API this should not be needed
886 // anymore
Dmitri Plotnikove8a95172010-06-23 16:18:10 -0700887 case ContactEntryListFragment.ACTIVITY_REQUEST_CODE_PICKER:
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700888 if (resultCode == RESULT_OK) {
Dmitri Plotnikove8a95172010-06-23 16:18:10 -0700889 mListFragment.onPickerResult(data);
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700890 }
891
892// TODO fix or remove multipicker code
893// else if (resultCode == RESULT_CANCELED && mMode == MODE_PICK_MULTIPLE_PHONES) {
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700894// // Finish the activity if the sub activity was canceled as back key is used
895// // to confirm user selection in MODE_PICK_MULTIPLE_PHONES.
896// finish();
897// }
898// break;
Dmitri Plotnikovd3758b02010-06-17 11:34:59 -0700899 }
900 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800901
902 @Override
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800903 public boolean onContextItemSelected(MenuItem item) {
Dmitri Plotnikov502741d2010-04-27 19:06:23 -0700904 ContextMenuAdapter menuAdapter = mListFragment.getContextMenuAdapter();
905 if (menuAdapter != null) {
906 return menuAdapter.onContextItemSelected(item);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800907 }
908
909 return super.onContextItemSelected(item);
910 }
911
912 @Override
913 public boolean onKeyDown(int keyCode, KeyEvent event) {
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700914 // TODO move to the fragment
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800915 switch (keyCode) {
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700916// case KeyEvent.KEYCODE_CALL: {
917// if (callSelection()) {
918// return true;
919// }
920// break;
921// }
Dmitri Plotnikovdb3d1432010-02-09 17:45:47 -0800922
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800923 case KeyEvent.KEYCODE_DEL: {
Dmitri Plotnikov6c776bc2010-03-10 10:12:31 -0800924 if (deleteSelection()) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800925 return true;
926 }
927 break;
928 }
Daniel Lehmann7bb2add2010-07-14 21:15:17 -0700929 default: {
930 // Bring up the search UI if the user starts typing
931 final int unicodeChar = event.getUnicodeChar();
932
933 if (unicodeChar != 0) {
934 String query = new String(new int[]{ unicodeChar }, 0, 1);
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700935 if (mHasActionBar) {
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700936 if (!mActionBarAdapter.isSearchMode()) {
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700937 mActionBarAdapter.setQueryString(query);
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700938 mActionBarAdapter.setSearchMode(true);
Daniel Lehmann7bb2add2010-07-14 21:15:17 -0700939 return true;
940 }
941 } else if (!mRequest.isSearchMode()) {
942 if (!mSearchInitiated) {
943 mSearchInitiated = true;
944 startSearch(query, false, null, false);
945 return true;
946 }
947 }
948 }
949 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800950 }
951
952 return super.onKeyDown(keyCode, event);
953 }
954
Dmitri Plotnikovab4d29f2010-10-28 12:43:54 -0700955 @Override
956 public void onBackPressed() {
957 if (mSearchMode && mActionBarAdapter != null) {
958 mActionBarAdapter.setSearchMode(false);
959 } else {
960 super.onBackPressed();
961 }
962 }
963
Dmitri Plotnikov6c776bc2010-03-10 10:12:31 -0800964 private boolean deleteSelection() {
Dmitri Plotnikov1ce1e7c2010-05-13 16:41:00 -0700965 // TODO move to the fragment
966// if (mActionCode == ContactsRequest.ACTION_DEFAULT) {
967// final int position = mListView.getSelectedItemPosition();
968// if (position != ListView.INVALID_POSITION) {
969// Uri contactUri = getContactUri(position);
970// if (contactUri != null) {
971// doContactDelete(contactUri);
972// return true;
973// }
974// }
975// }
Dmitri Plotnikov6c776bc2010-03-10 10:12:31 -0800976 return false;
977 }
978
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700979 @Override
980 protected void onSaveInstanceState(Bundle outState) {
981 super.onSaveInstanceState(outState);
Dmitri Plotnikov15ccbb42010-10-05 17:29:07 -0700982 outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
Dmitri Plotnikovfcfdffb2010-07-15 18:00:55 -0700983 if (mActionBarAdapter != null) {
984 mActionBarAdapter.onSaveInstanceState(outState);
Dmitri Plotnikov08e1c4e2010-07-02 17:57:51 -0700985 }
986 }
987
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700988 private PhoneNumberInteraction getPhoneNumberCallInteraction() {
989 if (mPhoneNumberCallInteraction == null) {
990 mPhoneNumberCallInteraction = new PhoneNumberInteraction(this, false, null);
Dmitri Plotnikov7c5286e2010-05-04 16:49:36 -0700991 }
Dmitri Plotnikovb4e88862010-06-30 21:24:35 -0700992 return mPhoneNumberCallInteraction;
993 }
994
995 private PhoneNumberInteraction getSendTextMessageInteraction() {
996 if (mSendTextMessageInteraction == null) {
997 mSendTextMessageInteraction = new PhoneNumberInteraction(this, true, null);
998 }
999 return mSendTextMessageInteraction;
Dmitri Plotnikov7c5286e2010-05-04 16:49:36 -07001000 }
Dmitri Plotnikov9692f262010-06-29 18:53:11 -07001001
1002 private ContactDeletionInteraction getContactDeletionInteraction() {
1003 if (mContactDeletionInteraction == null) {
1004 mContactDeletionInteraction = new ContactDeletionInteraction();
1005 mContactDeletionInteraction.attachToActivity(this);
1006 }
1007 return mContactDeletionInteraction;
1008 }
Dmitri Plotnikovaa1dffe2010-07-01 13:46:17 -07001009
1010 private ImportExportInteraction getImportExportInteraction() {
1011 if (mImportExportInteraction == null) {
1012 mImportExportInteraction = new ImportExportInteraction(this);
1013 }
1014 return mImportExportInteraction;
1015 }
Daniel Lehmann3391dbe2010-07-12 09:50:22 -07001016
1017 @Override
1018 public DialogManager getDialogManager() {
1019 return mDialogManager;
1020 }
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -08001021}