12bebde787f9490408ceaf14166de4b016a10daf1Mason Tang/* 22bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Copyright (C) 2010 The Android Open Source Project 32bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 42bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Licensed under the Apache License, Version 2.0 (the "License"); 52bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * you may not use this file except in compliance with the License. 62bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * You may obtain a copy of the License at 72bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 82bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * http://www.apache.org/licenses/LICENSE-2.0 92bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Unless required by applicable law or agreed to in writing, software 112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * distributed under the License is distributed on an "AS IS" BASIS, 122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * See the License for the specific language governing permissions and 142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * limitations under the License. 152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 172bebde787f9490408ceaf14166de4b016a10daf1Mason Tangpackage com.android.calendar; 182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 192c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY; 202c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME; 212c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport static android.provider.CalendarContract.EXTRA_EVENT_END_TIME; 222c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport static com.android.calendar.CalendarController.EVENT_EDIT_ON_LAUNCH; 232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 248f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelsonimport android.animation.Animator; 258f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelsonimport android.animation.AnimatorListenerAdapter; 268f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelsonimport android.animation.ObjectAnimator; 272bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.app.Activity; 2871d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.app.Dialog; 2971d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.app.DialogFragment; 30ef31a98202852807f460af49ae3313d1ccf5e288Andy McFaddenimport android.app.Service; 312bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ActivityNotFoundException; 32364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erikimport android.content.ContentProviderOperation; 332bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentResolver; 342bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentUris; 352bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentValues; 362bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Context; 37b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelsonimport android.content.DialogInterface; 382bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Intent; 391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.content.SharedPreferences; 402c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport android.content.pm.ApplicationInfo; 412c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport android.content.pm.PackageManager; 422c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport android.content.pm.PackageManager.NameNotFoundException; 432bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.res.Resources; 442bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.database.Cursor; 452bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.graphics.Rect; 462c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport android.graphics.drawable.Drawable; 472bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.net.Uri; 482bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.os.Bundle; 49a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract; 50a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees; 51a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars; 52a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events; 531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.provider.CalendarContract.Reminders; 54cb81189e4868769ea016253eca104e46df2f033aErikimport android.provider.ContactsContract; 552bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.CommonDataKinds; 562bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.Intents; 572bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.QuickContact; 588ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.Spannable; 5973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.SpannableString; 608ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.SpannableStringBuilder; 6173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.Spanned; 622bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.TextUtils; 632bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.Time; 6473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.method.LinkMovementMethod; 6573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.method.MovementMethod; 668ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.ForegroundColorSpan; 6773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.style.URLSpan; 682bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Linkify; 692bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Rfc822Token; 702bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.util.Log; 7171d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Gravity; 722bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.LayoutInflater; 7360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.Menu; 7460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.MenuInflater; 7560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.MenuItem; 762bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.MotionEvent; 772bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.View; 78cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnClickListener; 79cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnTouchListener; 802bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.ViewGroup; 8171d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Window; 8271d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.WindowManager; 83259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityEvent; 84259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityManager; 852bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.AdapterView; 868b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport android.widget.AdapterView.OnItemSelectedListener; 878ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.widget.Button; 881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.widget.LinearLayout; 89259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.widget.RadioButton; 90f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup; 91f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup.OnCheckedChangeListener; 928b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport android.widget.ScrollView; 932bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.TextView; 942bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.Toast; 952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 962c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.CalendarController.EventInfo; 972c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.CalendarController.EventType; 982c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.CalendarEventModel.Attendee; 992c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.CalendarEventModel.ReminderEntry; 1007da27670d2a62e213e230989b250f047012a3bbdSara Tingimport com.android.calendar.alerts.QuickResponseActivity; 1012c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.event.AttendeesView; 1022c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.event.EditEventActivity; 1032c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.event.EditEventHelper; 1042c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chanimport com.android.calendar.event.EventViewUtils; 1058a528adbba5d46fe0d566f474bc3be190511198eMichael Chanimport com.android.calendarcommon2.EventRecurrence; 1062c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 1072bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport java.util.ArrayList; 1081ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport java.util.Arrays; 1091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport java.util.Collections; 110259b8f9a21fffd3858218581e9daaf689b6b888fErikimport java.util.List; 1118b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport java.util.regex.Pattern; 112f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson 113f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanpublic class EventInfoFragment extends DialogFragment implements OnCheckedChangeListener, 114b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson CalendarController.EventHandler, OnClickListener, DeleteEventHelper.DeleteNotifyListener { 11583efa2d50deca53c9937b19a379045c31b541cb7Michael Chan 116d845fbe558d5229102b58cce70a1b29fe6cb6967Erik public static final boolean DEBUG = false; 1172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1182c7c851a4e40afa83a741ec39d44425b705a712eMichael Chan public static final String TAG = "EventInfoFragment"; 1192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 12060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson protected static final String BUNDLE_KEY_EVENT_ID = "key_event_id"; 12160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson protected static final String BUNDLE_KEY_START_MILLIS = "key_start_millis"; 12260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson protected static final String BUNDLE_KEY_END_MILLIS = "key_end_millis"; 12360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson protected static final String BUNDLE_KEY_IS_DIALOG = "key_fragment_is_dialog"; 124b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson protected static final String BUNDLE_KEY_DELETE_DIALOG_VISIBLE = "key_delete_dialog_visible"; 1257ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson protected static final String BUNDLE_KEY_WINDOW_STYLE = "key_window_style"; 12660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson protected static final String BUNDLE_KEY_ATTENDEE_RESPONSE = "key_attendee_response"; 12771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 128259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final String PERIOD_SPACE = ". "; 129259b8f9a21fffd3858218581e9daaf689b6b888fErik 1302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 1312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * These are the corresponding indices into the array of strings 1322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * "R.array.change_response_labels" in the resource file. 1332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 1342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int UPDATE_SINGLE = 0; 1352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int UPDATE_ALL = 1; 1362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1377ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson // Style of view 1387ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson public static final int FULL_WINDOW_STYLE = 0; 1397ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson public static final int DIALOG_WINDOW_STYLE = 1; 1407ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson 1417ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson private int mWindowStyle = DIALOG_WINDOW_STYLE; 1427ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson 1432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Query tokens for QueryHandler 144259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_EVENT = 1 << 0; 145259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_CALENDARS = 1 << 1; 146259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_ATTENDEES = 1 << 2; 147259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_DUPLICATE_CALENDARS = 1 << 3; 1481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int TOKEN_QUERY_REMINDERS = 1 << 4; 1496aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting private static final int TOKEN_QUERY_VISIBLE_CALENDARS = 1 << 5; 150259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_ALL = TOKEN_QUERY_DUPLICATE_CALENDARS 1511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson | TOKEN_QUERY_ATTENDEES | TOKEN_QUERY_CALENDARS | TOKEN_QUERY_EVENT 1526aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting | TOKEN_QUERY_REMINDERS | TOKEN_QUERY_VISIBLE_CALENDARS; 1536aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting 154259b8f9a21fffd3858218581e9daaf689b6b888fErik private int mCurrentQuery = 0; 1552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String[] EVENT_PROJECTION = new String[] { 1572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events._ID, // 0 do not remove; used in DeleteEventHelper 1582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.TITLE, // 1 do not remove; used in DeleteEventHelper 1592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.RRULE, // 2 do not remove; used in DeleteEventHelper 1602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.ALL_DAY, // 3 do not remove; used in DeleteEventHelper 1612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.CALENDAR_ID, // 4 do not remove; used in DeleteEventHelper 1622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.DTSTART, // 5 do not remove; used in DeleteEventHelper 1632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events._SYNC_ID, // 6 do not remove; used in DeleteEventHelper 1642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.EVENT_TIMEZONE, // 7 do not remove; used in DeleteEventHelper 1652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.DESCRIPTION, // 8 1662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.EVENT_LOCATION, // 9 167693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan Calendars.CALENDAR_ACCESS_LEVEL, // 10 168693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan Events.DISPLAY_COLOR, // 11 If SDK < 16, set to Calendars.CALENDAR_COLOR. 16971b221ae5d0f514352584a955630f5494f686c51Michael Chan Events.HAS_ATTENDEE_DATA, // 12 17071b221ae5d0f514352584a955630f5494f686c51Michael Chan Events.ORGANIZER, // 13 1711ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Events.HAS_ALARM, // 14 1721ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Calendars.MAX_REMINDERS, //15 1731ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Calendars.ALLOWED_REMINDERS, // 16 1742c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Events.CUSTOM_APP_PACKAGE, // 17 1752c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Events.CUSTOM_APP_URI, // 18 1762c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Events.ORIGINAL_SYNC_ID, // 19 do not remove; used in DeleteEventHelper 1772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang }; 1782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_ID = 0; 1792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_TITLE = 1; 1802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_RRULE = 2; 1812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_ALL_DAY = 3; 1822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_CALENDAR_ID = 4; 1832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_SYNC_ID = 6; 1842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_EVENT_TIMEZONE = 7; 1852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_DESCRIPTION = 8; 1862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_EVENT_LOCATION = 9; 18771b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_ACCESS_LEVEL = 10; 18871b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_COLOR = 11; 18971b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_HAS_ATTENDEE_DATA = 12; 19071b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_ORGANIZER = 13; 1911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int EVENT_INDEX_HAS_ALARM = 14; 1921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int EVENT_INDEX_MAX_REMINDERS = 15; 1931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int EVENT_INDEX_ALLOWED_REMINDERS = 16; 1942c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan private static final int EVENT_INDEX_CUSTOM_APP_PACKAGE = 17; 1952c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan private static final int EVENT_INDEX_CUSTOM_APP_URI = 18; 1961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 1972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String[] ATTENDEES_PROJECTION = new String[] { 1982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees._ID, // 0 1992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_NAME, // 1 2002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_EMAIL, // 2 2012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_RELATIONSHIP, // 3 2022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_STATUS, // 4 203ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting Attendees.ATTENDEE_IDENTITY, // 5 204ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting Attendees.ATTENDEE_ID_NAMESPACE // 6 2052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang }; 2062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_ID = 0; 2072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_NAME = 1; 2082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_EMAIL = 2; 2092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_RELATIONSHIP = 3; 2102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_STATUS = 4; 211ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting private static final int ATTENDEES_INDEX_IDENTITY = 5; 212ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting private static final int ATTENDEES_INDEX_ID_NAMESPACE = 6; 2132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 214693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan static { 215fac2d1594f7ecae8e50dc7790ce67de0c9b70d22Sara Ting if (!Utils.isJellybeanOrLater()) { 216693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan EVENT_PROJECTION[EVENT_INDEX_COLOR] = Calendars.CALENDAR_COLOR; 217693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan EVENT_PROJECTION[EVENT_INDEX_CUSTOM_APP_PACKAGE] = Events._ID; // dummy value 218693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan EVENT_PROJECTION[EVENT_INDEX_CUSTOM_APP_URI] = Events._ID; // dummy value 219693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan 220693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan ATTENDEES_PROJECTION[ATTENDEES_INDEX_IDENTITY] = Attendees._ID; // dummy value 221693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan ATTENDEES_PROJECTION[ATTENDEES_INDEX_ID_NAMESPACE] = Attendees._ID; // dummy value 222693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 223693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 224693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan 2252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=?"; 2262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String ATTENDEES_SORT_ORDER = Attendees.ATTENDEE_NAME + " ASC, " 2282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang + Attendees.ATTENDEE_EMAIL + " ASC"; 2292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2301ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final String[] REMINDERS_PROJECTION = new String[] { 2311ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Reminders._ID, // 0 2321ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Reminders.MINUTES, // 1 2331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Reminders.METHOD // 2 2341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson }; 2351ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int REMINDERS_INDEX_ID = 0; 2361ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int REMINDERS_MINUTES_ID = 1; 2371ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int REMINDERS_METHOD_ID = 2; 2381ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=?"; 2401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final String[] CALENDARS_PROJECTION = new String[] { 2422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Calendars._ID, // 0 243ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik Calendars.CALENDAR_DISPLAY_NAME, // 1 2442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Calendars.OWNER_ACCOUNT, // 2 24542896f76d81dbae873614340a3a78b29e7d463d2Sara Ting Calendars.CAN_ORGANIZER_RESPOND, // 3 24642896f76d81dbae873614340a3a78b29e7d463d2Sara Ting Calendars.ACCOUNT_NAME // 4 2472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang }; 2482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int CALENDARS_INDEX_DISPLAY_NAME = 1; 2492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int CALENDARS_INDEX_OWNER_ACCOUNT = 2; 2502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int CALENDARS_INDEX_OWNER_CAN_RESPOND = 3; 25142896f76d81dbae873614340a3a78b29e7d463d2Sara Ting static final int CALENDARS_INDEX_ACCOUNT_NAME = 4; 2522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final String CALENDARS_WHERE = Calendars._ID + "=?"; 254ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.CALENDAR_DISPLAY_NAME + "=?"; 2556aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting static final String CALENDARS_VISIBLE_WHERE = Calendars.VISIBLE + "=?"; 2562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 257fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden private static final String NANP_ALLOWED_SYMBOLS = "()+-*#."; 258fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden private static final int NANP_MIN_DIGITS = 7; 259fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden private static final int NANP_MAX_DIGITS = 11; 260fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 261fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 2622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private View mView; 2632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Uri mUri; 2652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private long mEventId; 2662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Cursor mEventCursor; 2672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Cursor mAttendeesCursor; 2682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Cursor mCalendarsCursor; 2691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private Cursor mRemindersCursor; 2701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2710a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan private static float mScale = 0; // Used for supporting different screen densities 2722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2732c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan private static int mCustomAppIconSize = 32; 2742c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 2752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private long mStartMillis; 2762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private long mEndMillis; 2778b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan private boolean mAllDay; 2782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mHasAttendeeData; 28083efa2d50deca53c9937b19a379045c31b541cb7Michael Chan private String mEventOrganizerEmail; 28183efa2d50deca53c9937b19a379045c31b541cb7Michael Chan private String mEventOrganizerDisplayName = ""; 2822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mIsOrganizer; 283d845fbe558d5229102b58cce70a1b29fe6cb6967Erik private long mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE; 284352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private boolean mOwnerCanRespond; 28542896f76d81dbae873614340a3a78b29e7d463d2Sara Ting private String mSyncAccountName; 2862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private String mCalendarOwnerAccount; 2872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mCanModifyCalendar; 28865eeb79e62034d706503ce29d88c0e05ebd726feRoboErik private boolean mCanModifyEvent; 2892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mIsBusyFreeCalendar; 2902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private int mNumOfAttendees; 2912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private EditResponseHelper mEditResponseHelper; 292b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson private boolean mDeleteDialogVisible = false; 293b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson private DeleteEventHelper mDeleteHelper; 2942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private int mOriginalAttendeeResponse; 2966bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson private int mAttendeeResponseFromIntent = Attendees.ATTENDEE_STATUS_NONE; 2976bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson private int mUserSetResponse = Attendees.ATTENDEE_STATUS_NONE; 2982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mIsRepeating; 2991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private boolean mHasAlarm; 3001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private int mMaxReminders; 3011ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private String mCalendarAllowedReminders; 302b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson // Used to prevent saving changes in event if it is being deleted. 303b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson private boolean mEventDeletionStarted = false; 3042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 305259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mTitle; 30675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting private TextView mWhenDateTime; 307259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mWhere; 30899704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan private ExpandableTextView mDesc; 309c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private AttendeesView mLongAttendees; 3107ffa24cba2977925b737e6bd39be59ba39609611Sara Ting private Button emailAttendeesButton; 311d8353fb85ef59a88580125207be9c914a8586758RoboErik private Menu mMenu = null; 312fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson private View mHeadlines; 3131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ScrollView mScrollView; 3148f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson private View mLoadingMsgView; 3158f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson private ObjectAnimator mAnimateAlpha; 316263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson private long mLoadingMsgStartTime; 3178f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson private static final int FADE_IN_TIME = 300; // in milliseconds 318263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson private static final int LOADING_MSG_DELAY = 600; // in milliseconds 319263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson private static final int LOADING_MSG_MIN_DISPLAY_TIME = 600; 32080d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson private boolean mNoCrossFade = false; // Used to prevent repeated cross-fade 3218f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 322259b8f9a21fffd3858218581e9daaf689b6b888fErik 32373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden private static final Pattern mWildcardPattern = Pattern.compile("^.*$"); 3242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 3252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>(); 3262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>(); 3272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>(); 3282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mNoResponseAttendees = new ArrayList<Attendee>(); 329cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting ArrayList<String> mToEmails = new ArrayList<String>(); 330cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting ArrayList<String> mCcEmails = new ArrayList<String>(); 3312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private int mColor; 3322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 3331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 3341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private int mDefaultReminderMinutes; 335ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson private final ArrayList<LinearLayout> mReminderViews = new ArrayList<LinearLayout>(0); 3361ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public ArrayList<ReminderEntry> mReminders; 3377f078b716fa7f1d374af9af3dad05d2e249e18c8RoboErik public ArrayList<ReminderEntry> mOriginalReminders = new ArrayList<ReminderEntry>(); 3387f078b716fa7f1d374af9af3dad05d2e249e18c8RoboErik public ArrayList<ReminderEntry> mUnsupportedReminders = new ArrayList<ReminderEntry>(); 3398b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik private boolean mUserModifiedReminders = false; 3401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 3411ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 3421ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Contents of the "minutes" spinner. This has default values from the XML file, augmented 3431ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * with any additional values that were already associated with the event. 3441ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 3451ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<Integer> mReminderMinuteValues; 3461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<String> mReminderMinuteLabels; 3471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 3481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 3491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Contents of the "methods" spinner. The "values" list specifies the method constant 3501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * (e.g. {@link Reminders#METHOD_ALERT}) associated with the labels. Any methods that 3511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * aren't allowed by the Calendar will be removed. 3521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 3531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<Integer> mReminderMethodValues; 3541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<String> mReminderMethodLabels; 3551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 3562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private QueryHandler mHandler; 3572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 358b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 359ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson private final Runnable mTZUpdater = new Runnable() { 360cb81189e4868769ea016253eca104e46df2f033aErik @Override 361cb81189e4868769ea016253eca104e46df2f033aErik public void run() { 362cb81189e4868769ea016253eca104e46df2f033aErik updateEvent(mView); 363cb81189e4868769ea016253eca104e46df2f033aErik } 364cb81189e4868769ea016253eca104e46df2f033aErik }; 365cb81189e4868769ea016253eca104e46df2f033aErik 366ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson private final Runnable mLoadingMsgAlphaUpdater = new Runnable() { 367263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson @Override 368263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson public void run() { 369263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson // Since this is run after a delay, make sure to only show the message 370263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson // if the event's data is not shown yet. 371263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson if (!mAnimateAlpha.isRunning() && mScrollView.getAlpha() == 0) { 372263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson mLoadingMsgStartTime = System.currentTimeMillis(); 373263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson mLoadingMsgView.setAlpha(1); 374263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson } 375263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson } 376263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson }; 377263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson 3788b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik private OnItemSelectedListener mReminderChangeListener; 3798b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik 3807ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson private static int mDialogWidth = 500; 3817ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson private static int mDialogHeight = 600; 3820aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson private static int DIALOG_TOP_MARGIN = 8; 38371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private boolean mIsDialog = false; 3847c6236d5553dc9f3d004ebbed794249713a11d19RoboErik private boolean mIsPaused = true; 3857c6236d5553dc9f3d004ebbed794249713a11d19RoboErik private boolean mDismissOnResume = false; 38671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private int mX = -1; 38771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private int mY = -1; 3880aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson private int mMinTop; // Dialog cannot be above this location 38910b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson private boolean mIsTabletConfig; 39010b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson private Activity mActivity; 391be2a432034e96c9f2fbf333cd7fe6489312bbeaaMichael Chan private Context mContext; 39271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 3932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private class QueryHandler extends AsyncQueryService { 3942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public QueryHandler(Context context) { 3952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang super(context); 3962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 3972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 3982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 3992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 4004003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang // if the activity is finishing, then close the cursor and return 4014003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang final Activity activity = getActivity(); 4024003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (activity == null || activity.isFinishing()) { 40347f6cc6909665e4f6f8d85f29bfd588688463c66Isaac Katzenelson if (cursor != null) { 40447f6cc6909665e4f6f8d85f29bfd588688463c66Isaac Katzenelson cursor.close(); 40547f6cc6909665e4f6f8d85f29bfd588688463c66Isaac Katzenelson } 4064003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang return; 4074003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 4084003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 4092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang switch (token) { 4102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_EVENT: 4112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventCursor = Utils.matrixCursorFromCursor(cursor); 4122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (initEventCursor()) { 4132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // The cursor is empty. This can happen if the event was 4142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // deleted. 4152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // FRAG_TODO we should no longer rely on Activity.finish() 4161df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang activity.finish(); 4172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 4182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateEvent(mView); 420e35a032c939f357ce435711b2fd8de1887a05011RoboErik prepareReminders(); 4212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 4222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // start calendar query 4232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Uri uri = Calendars.CONTENT_URI; 4242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String[] args = new String[] { 4252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Long.toString(mEventCursor.getLong(EVENT_INDEX_CALENDAR_ID))}; 4262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang startQuery(TOKEN_QUERY_CALENDARS, null, uri, CALENDARS_PROJECTION, 4272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang CALENDARS_WHERE, args, null); 4282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 4292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_CALENDARS: 4302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarsCursor = Utils.matrixCursorFromCursor(cursor); 4312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateCalendar(mView); 4324003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang // FRAG_TODO fragments shouldn't set the title anymore 4332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateTitle(); 4342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 435352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (!mIsBusyFreeCalendar) { 436352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan args = new String[] { Long.toString(mEventId) }; 437352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 438352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // start attendees query 439352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan uri = Attendees.CONTENT_URI; 440352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan startQuery(TOKEN_QUERY_ATTENDEES, null, uri, ATTENDEES_PROJECTION, 441352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan ATTENDEES_WHERE, args, ATTENDEES_SORT_ORDER); 442259b8f9a21fffd3858218581e9daaf689b6b888fErik } else { 443259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEventIfQueryDone(TOKEN_QUERY_ATTENDEES); 4442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4451ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mHasAlarm) { 4461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // start reminders query 4471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson args = new String[] { Long.toString(mEventId) }; 4481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson uri = Reminders.CONTENT_URI; 4491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson startQuery(TOKEN_QUERY_REMINDERS, null, uri, 4501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson REMINDERS_PROJECTION, REMINDERS_WHERE, args, null); 4511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } else { 4521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson sendAccessibilityEventIfQueryDone(TOKEN_QUERY_REMINDERS); 4531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 4542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 4552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_ATTENDEES: 4562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeesCursor = Utils.matrixCursorFromCursor(cursor); 4572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang initAttendeesCursor(mView); 4582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateResponse(mView); 4592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 4601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson case TOKEN_QUERY_REMINDERS: 4611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mRemindersCursor = Utils.matrixCursorFromCursor(cursor); 4621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson initReminders(mView, mRemindersCursor); 4631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson break; 4646aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting case TOKEN_QUERY_VISIBLE_CALENDARS: 4656aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting if (cursor.getCount() > 1) { 4666aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting // Start duplicate calendars query to detect whether to add the calendar 4676aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting // email to the calendar owner display. 4686aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting String displayName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME); 4696aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting mHandler.startQuery(TOKEN_QUERY_DUPLICATE_CALENDARS, null, 4706aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting Calendars.CONTENT_URI, CALENDARS_PROJECTION, 4716aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting CALENDARS_DUPLICATE_NAME_WHERE, new String[] {displayName}, null); 4726aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting } else { 4736aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting // Don't need to display the calendar owner when there is only a single 4746aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting // calendar. Skip the duplicate calendars query. 4756aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting setVisibilityCommon(mView, R.id.calendar_container, View.GONE); 4766aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting mCurrentQuery |= TOKEN_QUERY_DUPLICATE_CALENDARS; 4776aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting } 4786aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting break; 4792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_DUPLICATE_CALENDARS: 48071b221ae5d0f514352584a955630f5494f686c51Michael Chan Resources res = activity.getResources(); 48171b221ae5d0f514352584a955630f5494f686c51Michael Chan SpannableStringBuilder sb = new SpannableStringBuilder(); 48271b221ae5d0f514352584a955630f5494f686c51Michael Chan 48371b221ae5d0f514352584a955630f5494f686c51Michael Chan // Calendar display name 4842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String calendarName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME); 48571b221ae5d0f514352584a955630f5494f686c51Michael Chan sb.append(calendarName); 48671b221ae5d0f514352584a955630f5494f686c51Michael Chan 48771b221ae5d0f514352584a955630f5494f686c51Michael Chan // Show email account if display name is not unique and 48871b221ae5d0f514352584a955630f5494f686c51Michael Chan // display name != email 48971b221ae5d0f514352584a955630f5494f686c51Michael Chan String email = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT); 4906aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting if (cursor.getCount() > 1 && !calendarName.equalsIgnoreCase(email) && 4916aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting Utils.isValidEmail(email)) { 49271b221ae5d0f514352584a955630f5494f686c51Michael Chan sb.append(" (").append(email).append(")"); 49371b221ae5d0f514352584a955630f5494f686c51Michael Chan } 49471b221ae5d0f514352584a955630f5494f686c51Michael Chan 4956aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting setVisibilityCommon(mView, R.id.calendar_container, View.VISIBLE); 4966aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting setTextCommon(mView, R.id.calendar_name, sb); 4972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 4982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang cursor.close(); 500259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEventIfQueryDone(token); 5016aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting 5026aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting // All queries are done, show the view. 503263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson if (mCurrentQuery == TOKEN_QUERY_ALL) { 504263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson if (mLoadingMsgView.getAlpha() == 1) { 505263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson // Loading message is showing, let it stay a bit more (to prevent 506263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson // flashing) by adding a start delay to the event animation 507263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson long timeDiff = LOADING_MSG_MIN_DISPLAY_TIME - (System.currentTimeMillis() - 508263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson mLoadingMsgStartTime); 509263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson if (timeDiff > 0) { 510263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson mAnimateAlpha.setStartDelay(timeDiff); 511263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson } 512263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson } 51380d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson if (!mAnimateAlpha.isRunning() &&!mAnimateAlpha.isStarted() && !mNoCrossFade) { 51480d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson mAnimateAlpha.start(); 51580d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson } else { 51680d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson mScrollView.setAlpha(1); 51780d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson mLoadingMsgView.setVisibility(View.GONE); 51880d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson } 519263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson } 5202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 523259b8f9a21fffd3858218581e9daaf689b6b888fErik private void sendAccessibilityEventIfQueryDone(int token) { 524259b8f9a21fffd3858218581e9daaf689b6b888fErik mCurrentQuery |= token; 525259b8f9a21fffd3858218581e9daaf689b6b888fErik if (mCurrentQuery == TOKEN_QUERY_ALL) { 526259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEvent(); 527259b8f9a21fffd3858218581e9daaf689b6b888fErik } 528259b8f9a21fffd3858218581e9daaf689b6b888fErik } 529259b8f9a21fffd3858218581e9daaf689b6b888fErik 5300a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan public EventInfoFragment(Context context, Uri uri, long startMillis, long endMillis, 5317ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson int attendeeResponse, boolean isDialog, int windowStyle) { 5327ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson 5332c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Resources r = context.getResources(); 5342c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (mScale == 0) { 5352c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan mScale = context.getResources().getDisplayMetrics().density; 5362c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (mScale != 1) { 5372c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan mCustomAppIconSize *= mScale; 5382c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (isDialog) { 5397ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson DIALOG_TOP_MARGIN *= mScale; 5407ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson } 5410a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan } 5420a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan } 543363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan if (isDialog) { 544363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan setDialogSize(r); 545363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan } 54660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mIsDialog = isDialog; 547c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson 5482fc6b79dfb06812baf2e6c547f3ffee83b5c3e9aMichael Chan setStyle(DialogFragment.STYLE_NO_TITLE, 0); 5492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mUri = uri; 5502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mStartMillis = startMillis; 5512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEndMillis = endMillis; 5522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeeResponseFromIntent = attendeeResponse; 5537ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson mWindowStyle = windowStyle; 5542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 556ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden // This is currently required by the fragment manager. 55760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson public EventInfoFragment() { 55860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 55960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 56060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 56160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 5620a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan public EventInfoFragment(Context context, long eventId, long startMillis, long endMillis, 5637ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson int attendeeResponse, boolean isDialog, int windowStyle) { 5640a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan this(context, ContentUris.withAppendedId(Events.CONTENT_URI, eventId), startMillis, 5657ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson endMillis, attendeeResponse, isDialog, windowStyle); 5664003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mEventId = eventId; 5674003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 5684003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 56971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan @Override 57071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan public void onActivityCreated(Bundle savedInstanceState) { 57171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan super.onActivityCreated(savedInstanceState); 57271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 5738b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderChangeListener = new OnItemSelectedListener() { 5748b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik @Override 5758b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 5768b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik Integer prevValue = (Integer) parent.getTag(); 5778b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik if (prevValue == null || prevValue != position) { 5788b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik parent.setTag(position); 5798b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mUserModifiedReminders = true; 5808b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik } 5818b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik } 5828b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik 5838b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik @Override 5848b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik public void onNothingSelected(AdapterView<?> parent) { 5858b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik // do nothing 5868b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik } 5878b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik 5888b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik }; 5898b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik 59071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan if (savedInstanceState != null) { 59171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false); 5927ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson mWindowStyle = savedInstanceState.getInt(BUNDLE_KEY_WINDOW_STYLE, 5937ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson DIALOG_WINDOW_STYLE); 59471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 59571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 59671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan if (mIsDialog) { 59771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan applyDialogParams(); 59871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 599825b8ca1ea39c0da4620f5aaaeeb1fa40e7e8efdMichael Chan mContext = getActivity(); 60071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 60171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 60271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private void applyDialogParams() { 60371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan Dialog dialog = getDialog(); 60471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan dialog.setCanceledOnTouchOutside(true); 60571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 60671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan Window window = dialog.getWindow(); 60771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); 60871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 60971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan WindowManager.LayoutParams a = window.getAttributes(); 61071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan a.dimAmount = .4f; 61171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 6127ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson a.width = mDialogWidth; 6137ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson a.height = mDialogHeight; 61471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 6150b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson 6160b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson // On tablets , do smart positioning of dialog 6170b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson // On phones , use the whole screen 6180b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson 61960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (mX != -1 || mY != -1) { 6207ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson a.x = mX - mDialogWidth / 2; 6217ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson a.y = mY - mDialogHeight / 2; 6220aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson if (a.y < mMinTop) { 6230aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson a.y = mMinTop + DIALOG_TOP_MARGIN; 6240a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan } 62560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson a.gravity = Gravity.LEFT | Gravity.TOP; 62671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 62771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan window.setAttributes(a); 62871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 62971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 6300aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson public void setDialogParams(int x, int y, int minTop) { 63171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan mX = x; 63271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan mY = y; 6330aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson mMinTop = minTop; 63471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 63571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 636f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan // Implements OnCheckedChangeListener 637f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan @Override 638f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan public void onCheckedChanged(RadioGroup group, int checkedId) { 6392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If this is not a repeating event, then don't display the dialog 6402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // asking which events to change. 6415afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik mUserSetResponse = getResponseFromButtonId(checkedId); 6422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!mIsRepeating) { 6432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 6442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If the selection is the same as the original, then don't display the 6472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // dialog asking which events to change. 648f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan if (checkedId == findButtonIdForResponse(mOriginalAttendeeResponse)) { 6492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 6502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // This is a repeating event. We need to ask the user if they mean to 6532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // change just this one instance or all instances. 6542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEditResponseHelper.showDialog(mEditResponseHelper.getWhichEvents()); 6552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void onNothingSelected(AdapterView<?> parent) { 6582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 6612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void onAttach(Activity activity) { 6622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang super.onAttach(activity); 66310b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson mActivity = activity; 6642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEditResponseHelper = new EditResponseHelper(activity); 66586550ce5323f7e3971977702fca259986c048bf6RoboErik 66686550ce5323f7e3971977702fca259986c048bf6RoboErik if (mAttendeeResponseFromIntent != Attendees.ATTENDEE_STATUS_NONE) { 66786550ce5323f7e3971977702fca259986c048bf6RoboErik mEditResponseHelper.setWhichEvents(UPDATE_ALL); 66886550ce5323f7e3971977702fca259986c048bf6RoboErik } 6692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler = new QueryHandler(activity); 67060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (!mIsDialog) { 67160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson setHasOptionsMenu(true); 67260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 6732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 6762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public View onCreateView(LayoutInflater inflater, ViewGroup container, 6772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Bundle savedInstanceState) { 678320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson 679320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson if (savedInstanceState != null) { 680320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false); 681320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson mWindowStyle = savedInstanceState.getInt(BUNDLE_KEY_WINDOW_STYLE, 682320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson DIALOG_WINDOW_STYLE); 683320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson mDeleteDialogVisible = 684320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson savedInstanceState.getBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE,false); 685320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson 686320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson } 687320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson 6887ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson if (mWindowStyle == DIALOG_WINDOW_STYLE) { 689cba7f1fd22e1d7ee9d8d0828f37bc08512bf6b75Michael Chan mView = inflater.inflate(R.layout.event_info_dialog, container, false); 6907ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson } else { 6917ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson mView = inflater.inflate(R.layout.event_info, container, false); 6927ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson } 6931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mScrollView = (ScrollView) mView.findViewById(R.id.event_info_scroll_view); 6948f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mLoadingMsgView = mView.findViewById(R.id.event_info_loading_msg); 695259b8f9a21fffd3858218581e9daaf689b6b888fErik mTitle = (TextView) mView.findViewById(R.id.title); 69675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting mWhenDateTime = (TextView) mView.findViewById(R.id.when_datetime); 697259b8f9a21fffd3858218581e9daaf689b6b888fErik mWhere = (TextView) mView.findViewById(R.id.where); 69899704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan mDesc = (ExpandableTextView) mView.findViewById(R.id.description); 699fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mHeadlines = mView.findViewById(R.id.event_info_headline); 700c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mLongAttendees = (AttendeesView)mView.findViewById(R.id.long_attendee_list); 70110b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson mIsTabletConfig = Utils.getConfigBool(mActivity, R.bool.tablet_config); 7022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 7034003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (mUri == null) { 7044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang // restore event ID from bundle 7054003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mEventId = savedInstanceState.getLong(BUNDLE_KEY_EVENT_ID); 7064003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mUri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 7074003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mStartMillis = savedInstanceState.getLong(BUNDLE_KEY_START_MILLIS); 7084003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mEndMillis = savedInstanceState.getLong(BUNDLE_KEY_END_MILLIS); 7094003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 7104003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 7118f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mAnimateAlpha = ObjectAnimator.ofFloat(mScrollView, "Alpha", 0, 1); 7128f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mAnimateAlpha.setDuration(FADE_IN_TIME); 7138f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mAnimateAlpha.addListener(new AnimatorListenerAdapter() { 7148f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson int defLayerType; 7158f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 7168f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson @Override 7178f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson public void onAnimationStart(Animator animation) { 7188f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson // Use hardware layer for better performance during animation 7198f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson defLayerType = mScrollView.getLayerType(); 7208f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mScrollView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 7218f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson // Ensure that the loading message is gone before showing the 7228f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson // event info 723263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson mLoadingMsgView.removeCallbacks(mLoadingMsgAlphaUpdater); 7248f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mLoadingMsgView.setVisibility(View.GONE); 7258f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson } 7268f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 7278f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson @Override 7288f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson public void onAnimationCancel(Animator animation) { 7298f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mScrollView.setLayerType(defLayerType, null); 7308f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson } 7318f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 7328f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson @Override 7338f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson public void onAnimationEnd(Animator animation) { 7348f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mScrollView.setLayerType(defLayerType, null); 73580d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson // Do not cross fade after the first time 73680d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson mNoCrossFade = true; 7378f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson } 7388f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson }); 7398f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 7408f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mLoadingMsgView.setAlpha(0); 7418f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson mScrollView.setAlpha(0); 742263b0291b701dc2b5df7ebab53f8e6808e7be9a8Isaac Katzenelson mLoadingMsgView.postDelayed(mLoadingMsgAlphaUpdater, LOADING_MSG_DELAY); 7438f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 7442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // start loading the data 7458f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson 7462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION, 7472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang null, null, null); 7482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 749d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson View b = mView.findViewById(R.id.delete); 7508ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan b.setOnClickListener(new OnClickListener() { 7518ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan @Override 7528ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan public void onClick(View v) { 75369be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik if (!mCanModifyCalendar) { 75469be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik return; 75569be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik } 756d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson mDeleteHelper = 757d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson new DeleteEventHelper(mContext, mActivity, !mIsDialog && !mIsTabletConfig /* exitWhenDone */); 758b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper.setDeleteNotificationListener(EventInfoFragment.this); 759b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener()); 760b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteDialogVisible = true; 761b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable); 762d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson } 763d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson }); 7648ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 76510b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // Hide Edit/Delete buttons if in full screen mode on a phone 7667ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson if (!mIsDialog && !mIsTabletConfig || mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) { 76760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mView.findViewById(R.id.event_info_buttons_container).setVisibility(View.GONE); 76860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 76960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 770cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting // Create a listener for the email guests button 7717ffa24cba2977925b737e6bd39be59ba39609611Sara Ting emailAttendeesButton = (Button) mView.findViewById(R.id.email_attendees_button); 772cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting if (emailAttendeesButton != null) { 773cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting emailAttendeesButton.setOnClickListener(new View.OnClickListener() { 774cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting @Override 775cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting public void onClick(View v) { 776cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting emailAttendees(); 777cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 778cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting }); 779cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 7801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 781cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting // Create a listener for the add reminder button 782b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan View reminderAddButton = mView.findViewById(R.id.reminder_add); 7831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson View.OnClickListener addReminderOnClickListener = new View.OnClickListener() { 7841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson @Override 7851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public void onClick(View v) { 7861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson addReminder(); 7878b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mUserModifiedReminders = true; 7881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 7891ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson }; 7901ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson reminderAddButton.setOnClickListener(addReminderOnClickListener); 7911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 7921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Set reminders variables 7931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 7941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity); 7951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson String defaultReminderString = prefs.getString( 7961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING); 7971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mDefaultReminderMinutes = Integer.parseInt(defaultReminderString); 7981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson prepareReminders(); 7991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 8002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return mView; 8012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 803ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson private final Runnable onDeleteRunnable = new Runnable() { 80489ad0822f104015625f4ca88bfdf5c1d522b6e74Erik @Override 80589ad0822f104015625f4ca88bfdf5c1d522b6e74Erik public void run() { 8067c6236d5553dc9f3d004ebbed794249713a11d19RoboErik if (EventInfoFragment.this.mIsPaused) { 8077c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mDismissOnResume = true; 8087c6236d5553dc9f3d004ebbed794249713a11d19RoboErik return; 8097c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 81089ad0822f104015625f4ca88bfdf5c1d522b6e74Erik if (EventInfoFragment.this.isVisible()) { 81189ad0822f104015625f4ca88bfdf5c1d522b6e74Erik EventInfoFragment.this.dismiss(); 81289ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 81389ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 81489ad0822f104015625f4ca88bfdf5c1d522b6e74Erik }; 81589ad0822f104015625f4ca88bfdf5c1d522b6e74Erik 8162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateTitle() { 8172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Resources res = getActivity().getResources(); 8182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mCanModifyCalendar && !mIsOrganizer) { 8192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang getActivity().setTitle(res.getString(R.string.event_info_title_invite)); 8202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 8212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang getActivity().setTitle(res.getString(R.string.event_info_title)); 8222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 8262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Initializes the event cursor, which is expected to point to the first 8272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * (and only) result from a query. 8282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * @return true if the cursor is empty. 8292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 8302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean initEventCursor() { 8312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if ((mEventCursor == null) || (mEventCursor.getCount() == 0)) { 8322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 8332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventCursor.moveToFirst(); 8352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventId = mEventCursor.getInt(EVENT_INDEX_ID); 8362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String rRule = mEventCursor.getString(EVENT_INDEX_RRULE); 83766b2067e0a389180f909eb0a528bea5f6becca23Michael Chan mIsRepeating = !TextUtils.isEmpty(rRule); 8381ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mHasAlarm = (mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) == 1)?true:false; 8391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mMaxReminders = mEventCursor.getInt(EVENT_INDEX_MAX_REMINDERS); 8401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mCalendarAllowedReminders = mEventCursor.getString(EVENT_INDEX_ALLOWED_REMINDERS); 8412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @SuppressWarnings("fallthrough") 8452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void initAttendeesCursor(View view) { 8466bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson mOriginalAttendeeResponse = Attendees.ATTENDEE_STATUS_NONE; 847d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE; 8482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mNumOfAttendees = 0; 8492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor != null) { 8502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mNumOfAttendees = mAttendeesCursor.getCount(); 8512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor.moveToFirst()) { 8522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAcceptedAttendees.clear(); 8532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mDeclinedAttendees.clear(); 8542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mTentativeAttendees.clear(); 8552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mNoResponseAttendees.clear(); 8562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang do { 8582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang int status = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS); 8592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String name = mAttendeesCursor.getString(ATTENDEES_INDEX_NAME); 8602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String email = mAttendeesCursor.getString(ATTENDEES_INDEX_EMAIL); 8612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 86283efa2d50deca53c9937b19a379045c31b541cb7Michael Chan if (mAttendeesCursor.getInt(ATTENDEES_INDEX_RELATIONSHIP) == 86383efa2d50deca53c9937b19a379045c31b541cb7Michael Chan Attendees.RELATIONSHIP_ORGANIZER) { 86483efa2d50deca53c9937b19a379045c31b541cb7Michael Chan 86583efa2d50deca53c9937b19a379045c31b541cb7Michael Chan // Overwrites the one from Event table if available 86683efa2d50deca53c9937b19a379045c31b541cb7Michael Chan if (!TextUtils.isEmpty(name)) { 86783efa2d50deca53c9937b19a379045c31b541cb7Michael Chan mEventOrganizerDisplayName = name; 86883efa2d50deca53c9937b19a379045c31b541cb7Michael Chan if (!mIsOrganizer) { 86983efa2d50deca53c9937b19a379045c31b541cb7Michael Chan setVisibilityCommon(view, R.id.organizer_container, View.VISIBLE); 87083efa2d50deca53c9937b19a379045c31b541cb7Michael Chan setTextCommon(view, R.id.organizer, mEventOrganizerDisplayName); 87183efa2d50deca53c9937b19a379045c31b541cb7Michael Chan } 87283efa2d50deca53c9937b19a379045c31b541cb7Michael Chan } 87383efa2d50deca53c9937b19a379045c31b541cb7Michael Chan } 87483efa2d50deca53c9937b19a379045c31b541cb7Michael Chan 875d845fbe558d5229102b58cce70a1b29fe6cb6967Erik if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE && 8762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAccount.equalsIgnoreCase(email)) { 8772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAttendeeId = mAttendeesCursor.getInt(ATTENDEES_INDEX_ID); 8782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mOriginalAttendeeResponse = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS); 8792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 880693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan String identity = null; 881693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan String idNamespace = null; 882693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan 883fac2d1594f7ecae8e50dc7790ce67de0c9b70d22Sara Ting if (Utils.isJellybeanOrLater()) { 884693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan identity = mAttendeesCursor.getString(ATTENDEES_INDEX_IDENTITY); 885693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan idNamespace = mAttendeesCursor.getString(ATTENDEES_INDEX_ID_NAMESPACE); 886693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 887ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting 8882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Don't show your own status in the list because: 8892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // 1) it doesn't make sense for event without other guests. 8902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // 2) there's a spinner for that for events with guests. 8912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang switch(status) { 8922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case Attendees.ATTENDEE_STATUS_ACCEPTED: 893fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mAcceptedAttendees.add(new Attendee(name, email, 894ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting Attendees.ATTENDEE_STATUS_ACCEPTED, identity, 895ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting idNamespace)); 8962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 8972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case Attendees.ATTENDEE_STATUS_DECLINED: 898fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mDeclinedAttendees.add(new Attendee(name, email, 899ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting Attendees.ATTENDEE_STATUS_DECLINED, identity, 900ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting idNamespace)); 9012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 9028ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan case Attendees.ATTENDEE_STATUS_TENTATIVE: 903fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mTentativeAttendees.add(new Attendee(name, email, 904ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting Attendees.ATTENDEE_STATUS_TENTATIVE, identity, 905ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting idNamespace)); 9068ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan break; 9078ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan default: 908fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mNoResponseAttendees.add(new Attendee(name, email, 909ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting Attendees.ATTENDEE_STATUS_NONE, identity, 910ddbc002f3471e224fc112d406116e396ee1c50aeSara Ting idNamespace)); 9112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } while (mAttendeesCursor.moveToNext()); 9142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeesCursor.moveToFirst(); 9152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateAttendees(view); 9172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 9224003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang public void onSaveInstanceState(Bundle outState) { 9234003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang super.onSaveInstanceState(outState); 9244003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang outState.putLong(BUNDLE_KEY_EVENT_ID, mEventId); 9254003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang outState.putLong(BUNDLE_KEY_START_MILLIS, mStartMillis); 9264003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang outState.putLong(BUNDLE_KEY_END_MILLIS, mEndMillis); 92771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan outState.putBoolean(BUNDLE_KEY_IS_DIALOG, mIsDialog); 9287ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson outState.putInt(BUNDLE_KEY_WINDOW_STYLE, mWindowStyle); 929b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson outState.putBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE, mDeleteDialogVisible); 93060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson outState.putInt(BUNDLE_KEY_ATTENDEE_RESPONSE, mAttendeeResponseFromIntent); 93160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 93260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 93360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 93460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson @Override 93560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 93660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson super.onCreateOptionsMenu(menu, inflater); 9377ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson // Show edit/delete buttons only in non-dialog configuration 9387ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson if (!mIsDialog && !mIsTabletConfig || mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) { 93960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson inflater.inflate(R.menu.event_info_title_bar, menu); 940d8353fb85ef59a88580125207be9c914a8586758RoboErik mMenu = menu; 941d8353fb85ef59a88580125207be9c914a8586758RoboErik updateMenu(); 94260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 9434003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 9444003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 945d8353fb85ef59a88580125207be9c914a8586758RoboErik @Override 946d8353fb85ef59a88580125207be9c914a8586758RoboErik public boolean onOptionsItemSelected(MenuItem item) { 947d8353fb85ef59a88580125207be9c914a8586758RoboErik 9487ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson // If we're a dialog we don't want to handle menu buttons 9497ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson if (mIsDialog) { 950d8353fb85ef59a88580125207be9c914a8586758RoboErik return false; 951d8353fb85ef59a88580125207be9c914a8586758RoboErik } 952d8353fb85ef59a88580125207be9c914a8586758RoboErik // Handles option menu selections: 953d8353fb85ef59a88580125207be9c914a8586758RoboErik // Home button - close event info activity and start the main calendar 954d8353fb85ef59a88580125207be9c914a8586758RoboErik // one 955d8353fb85ef59a88580125207be9c914a8586758RoboErik // Edit button - start the event edit activity and close the info 956d8353fb85ef59a88580125207be9c914a8586758RoboErik // activity 957d8353fb85ef59a88580125207be9c914a8586758RoboErik // Delete button - start a delete query that calls a runnable that close 958d8353fb85ef59a88580125207be9c914a8586758RoboErik // the info activity 959d8353fb85ef59a88580125207be9c914a8586758RoboErik 960bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan final int itemId = item.getItemId(); 961bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan if (itemId == android.R.id.home) { 962bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan Utils.returnToCalendarHome(mContext); 963bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mActivity.finish(); 964bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan return true; 965bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan } else if (itemId == R.id.info_action_edit) { 966bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 967bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan Intent intent = new Intent(Intent.ACTION_EDIT, uri); 968bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan intent.putExtra(EXTRA_EVENT_BEGIN_TIME, mStartMillis); 969bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan intent.putExtra(EXTRA_EVENT_END_TIME, mEndMillis); 970bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan intent.putExtra(EXTRA_EVENT_ALL_DAY, mAllDay); 971bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan intent.setClass(mActivity, EditEventActivity.class); 972bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan intent.putExtra(EVENT_EDIT_ON_LAUNCH, true); 973bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan startActivity(intent); 974bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mActivity.finish(); 975bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan } else if (itemId == R.id.info_action_delete) { 976bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mDeleteHelper = 977bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan new DeleteEventHelper(mActivity, mActivity, true /* exitWhenDone */); 978bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mDeleteHelper.setDeleteNotificationListener(EventInfoFragment.this); 979bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener()); 980bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mDeleteDialogVisible = true; 981bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable); 982d8353fb85ef59a88580125207be9c914a8586758RoboErik } 983d8353fb85ef59a88580125207be9c914a8586758RoboErik return super.onOptionsItemSelected(item); 984d8353fb85ef59a88580125207be9c914a8586758RoboErik } 9854003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 9864003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang @Override 9874003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang public void onDestroyView() { 988ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson 989b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson if (!mEventDeletionStarted) { 990ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson boolean responseSaved = saveResponse(); 991ac4350b25b794d1b2935266cf8c480e4fbf97b8fIsaac Katzenelson if (saveReminders() || responseSaved) { 992b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson Toast.makeText(getActivity(), R.string.saving_event, Toast.LENGTH_SHORT).show(); 993b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson } 9942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9954003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang super.onDestroyView(); 9962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 9992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void onDestroy() { 10002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mEventCursor != null) { 10012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventCursor.close(); 10022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mCalendarsCursor != null) { 10042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarsCursor.close(); 10052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor != null) { 10072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeesCursor.close(); 10082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 100971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan super.onDestroy(); 10102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 10132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Asynchronously saves the response to an invitation if the user changed 10142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * the response. Returns true if the database will be updated. 10152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 10162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * @return true if the database will be changed 10172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 10182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean saveResponse() { 10192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor == null || mEventCursor == null) { 10202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 10212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1022f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 1023f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan RadioGroup radioGroup = (RadioGroup) getView().findViewById(R.id.response_value); 1024f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int status = getResponseFromButtonId(radioGroup.getCheckedRadioButtonId()); 1025f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan if (status == Attendees.ATTENDEE_STATUS_NONE) { 10262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 10272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If the status has not changed, then don't update the database 10302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (status == mOriginalAttendeeResponse) { 10312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 10322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If we never got an owner attendee id we can't set the status 1035d845fbe558d5229102b58cce70a1b29fe6cb6967Erik if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE) { 10362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 10372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!mIsRepeating) { 10402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // This is a non-repeating event 10412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateResponse(mEventId, mCalendarOwnerAttendeeId, status); 10422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 10432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // This is a repeating event 10462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang int whichEvents = mEditResponseHelper.getWhichEvents(); 10472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang switch (whichEvents) { 10482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case -1: 10492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 10502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case UPDATE_SINGLE: 1051c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden createExceptionResponse(mEventId, status); 10522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 10532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case UPDATE_ALL: 10542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateResponse(mEventId, mCalendarOwnerAttendeeId, status); 10552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 10562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang default: 10572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Log.e(TAG, "Unexpected choice for updating invitation response"); 10582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 10592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 10612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateResponse(long eventId, long attendeeId, int status) { 10642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Update the attendee status in the attendees table. the provider 10652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // takes care of updating the self attendance status. 10662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ContentValues values = new ContentValues(); 10672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!TextUtils.isEmpty(mCalendarOwnerAccount)) { 10692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Attendees.ATTENDEE_EMAIL, mCalendarOwnerAccount); 10702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Attendees.ATTENDEE_STATUS, status); 10722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Attendees.EVENT_ID, eventId); 10732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Uri uri = ContentUris.withAppendedId(Attendees.CONTENT_URI, attendeeId); 10752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler.startUpdate(mHandler.getNextToken(), null, uri, values, 10772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang null, null, Utils.UNDO_DELAY); 10782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1080c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden /** 1081c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * Creates an exception to a recurring event. The only change we're making is to the 1082c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * "self attendee status" value. The provider will take care of updating the corresponding 1083c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * Attendees.attendeeStatus entry. 1084c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * 1085c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * @param eventId The recurring event. 1086c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * @param status The new value for selfAttendeeStatus. 1087c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden */ 1088c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden private void createExceptionResponse(long eventId, int status) { 10892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ContentValues values = new ContentValues(); 10902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis); 10912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Events.SELF_ATTENDEE_STATUS, status); 1092c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden values.put(Events.STATUS, Events.STATUS_CONFIRMED); 10932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1094364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erik ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 109579b2c8c946c29ea9107957fe72a9fa9f560da345Andy McFadden Uri exceptionUri = Uri.withAppendedPath(Events.CONTENT_EXCEPTION_URI, 1096c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden String.valueOf(eventId)); 1097c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden ops.add(ContentProviderOperation.newInsert(exceptionUri).withValues(values).build()); 1098364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erik 1099c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden mHandler.startBatch(mHandler.getNextToken(), null, CalendarContract.AUTHORITY, ops, 1100c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden Utils.UNDO_DELAY); 1101c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden } 11022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1103f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan public static int getResponseFromButtonId(int buttonId) { 1104f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int response; 1105bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan if (buttonId == R.id.response_yes) { 1106bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan response = Attendees.ATTENDEE_STATUS_ACCEPTED; 1107bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan } else if (buttonId == R.id.response_maybe) { 1108bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan response = Attendees.ATTENDEE_STATUS_TENTATIVE; 1109bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan } else if (buttonId == R.id.response_no) { 1110bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan response = Attendees.ATTENDEE_STATUS_DECLINED; 1111bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan } else { 1112bb6d9279d8c0f0fb746160ad428da4738ece175eMichael Chan response = Attendees.ATTENDEE_STATUS_NONE; 11132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1114f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan return response; 1115f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan } 1116f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 1117f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan public static int findButtonIdForResponse(int response) { 1118f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int buttonId; 1119f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan switch (response) { 1120f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case Attendees.ATTENDEE_STATUS_ACCEPTED: 1121f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = R.id.response_yes; 1122f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 1123f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case Attendees.ATTENDEE_STATUS_TENTATIVE: 1124f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = R.id.response_maybe; 1125f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 1126f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case Attendees.ATTENDEE_STATUS_DECLINED: 1127f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = R.id.response_no; 1128f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 1129f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan default: 1130f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = -1; 1131f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan } 1132f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan return buttonId; 11332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 11342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 11352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void doEdit() { 1136c41b99be504e395b8c7264a0d626906ccbff1c57Erik Context c = getActivity(); 1137c41b99be504e395b8c7264a0d626906ccbff1c57Erik // This ensures that we aren't in the process of closing and have been 1138c41b99be504e395b8c7264a0d626906ccbff1c57Erik // unattached already 1139c41b99be504e395b8c7264a0d626906ccbff1c57Erik if (c != null) { 1140c41b99be504e395b8c7264a0d626906ccbff1c57Erik CalendarController.getInstance(c).sendEventRelatedEvent( 114161bf59383cc3d38ef0447635ed65ab986796d7deMichael Chan this, EventType.EDIT_EVENT, mEventId, mStartMillis, mEndMillis, 0 114260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson , 0, -1); 1143c41b99be504e395b8c7264a0d626906ccbff1c57Erik } 11442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 11452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 11462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateEvent(View view) { 1147b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson if (mEventCursor == null || view == null) { 11482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 11492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 11502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 11515f5ef752bfd4640016c4dedef53be47c5b8842afMichael Chan Context context = view.getContext(); 11525f5ef752bfd4640016c4dedef53be47c5b8842afMichael Chan if (context == null) { 11535f5ef752bfd4640016c4dedef53be47c5b8842afMichael Chan return; 11545f5ef752bfd4640016c4dedef53be47c5b8842afMichael Chan } 11555f5ef752bfd4640016c4dedef53be47c5b8842afMichael Chan 11562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String eventName = mEventCursor.getString(EVENT_INDEX_TITLE); 11572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (eventName == null || eventName.length() == 0) { 11582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang eventName = getActivity().getString(R.string.no_title_label); 11592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 11602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 11618b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan mAllDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0; 11622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION); 11632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION); 11642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String rRule = mEventCursor.getString(EVENT_INDEX_RRULE); 1165f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE); 11662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 11674acb2fd087308dea146b8b10f5278c59df387680RoboErik mColor = Utils.getDisplayColorFromColor(mEventCursor.getInt(EVENT_INDEX_COLOR)); 1168fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mHeadlines.setBackgroundColor(mColor); 11692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 11704e92627c5eb10de50c49c57e116b080d48360c70Sara Ting // What 11714e92627c5eb10de50c49c57e116b080d48360c70Sara Ting if (eventName != null) { 11724e92627c5eb10de50c49c57e116b080d48360c70Sara Ting setTextCommon(view, R.id.title, eventName); 11734e92627c5eb10de50c49c57e116b080d48360c70Sara Ting } 11744e92627c5eb10de50c49c57e116b080d48360c70Sara Ting 11752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // When 1176fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson // Set the date and repeats (if any) 117775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting String localTimezone = Utils.getTimeZone(mActivity, mTZUpdater); 11785f5ef752bfd4640016c4dedef53be47c5b8842afMichael Chan 117923acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting Resources resources = context.getResources(); 118023acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting String displayedDatetime = Utils.getDisplayedDatetime(mStartMillis, mEndMillis, 118123acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting System.currentTimeMillis(), localTimezone, mAllDay, context); 1182e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan 1183e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan String displayedTimezone = null; 1184e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan if (!mAllDay) { 1185e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan displayedTimezone = Utils.getDisplayedTimezone(mStartMillis, localTimezone, 1186e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan eventTimezone); 118723acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting } 118823acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting // Display the datetime. Make the timezone (if any) transparent. 118923acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting if (displayedTimezone == null) { 119023acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting setTextCommon(view, R.id.when_datetime, displayedDatetime); 119123acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting } else { 1192e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan int timezoneIndex = displayedDatetime.length(); 1193e8e557260ec1f907d257dcbb08c49bc5d0926795Michael Chan displayedDatetime += " " + displayedTimezone; 119423acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting SpannableStringBuilder sb = new SpannableStringBuilder(displayedDatetime); 119523acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting ForegroundColorSpan transparentColorSpan = new ForegroundColorSpan( 119623acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting resources.getColor(R.color.event_info_headline_transparent_color)); 119723acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting sb.setSpan(transparentColorSpan, timezoneIndex, displayedDatetime.length(), 119823acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting Spannable.SPAN_INCLUSIVE_INCLUSIVE); 119923acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting setTextCommon(view, R.id.when_datetime, sb); 120023acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting } 1201fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson 120275f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting // Display the repeat string (if any) 1203fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson String repeatString = null; 1204fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (!TextUtils.isEmpty(rRule)) { 1205fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson EventRecurrence eventRecurrence = new EventRecurrence(); 1206fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson eventRecurrence.parse(rRule); 120775f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting Time date = new Time(localTimezone); 120875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting date.set(mStartMillis); 12098b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan if (mAllDay) { 1210fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson date.timezone = Time.TIMEZONE_UTC; 1211fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 1212fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson eventRecurrence.setStartDate(date); 121323acd2668d65c2282f7aa922b4e86a7713d9b2faSara Ting repeatString = EventRecurrenceFormatter.getRepeatString(resources, eventRecurrence); 1214fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 121575f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting if (repeatString == null) { 121675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting view.findViewById(R.id.when_repeat).setVisibility(View.GONE); 12172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 121875f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting setTextCommon(view, R.id.when_repeat, repeatString); 1219f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson } 1220f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson 12212e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson // Organizer view is setup in the updateCalendar method 12222e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson 12232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 12242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Where 1225ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan if (location == null || location.trim().length() == 0) { 12262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setVisibilityCommon(view, R.id.where, View.GONE); 12272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 1228259b8f9a21fffd3858218581e9daaf689b6b888fErik final TextView textView = mWhere; 12292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (textView != null) { 1230ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan textView.setAutoLinkMask(0); 1231ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan textView.setText(location.trim()); 1232af577fd49d334060f34d3e40e48c762ff5f0de4fAndy McFadden try { 1233af577fd49d334060f34d3e40e48c762ff5f0de4fAndy McFadden linkifyTextView(textView); 1234af577fd49d334060f34d3e40e48c762ff5f0de4fAndy McFadden } catch (Exception ex) { 1235af577fd49d334060f34d3e40e48c762ff5f0de4fAndy McFadden // unexpected 1236af577fd49d334060f34d3e40e48c762ff5f0de4fAndy McFadden Log.e(TAG, "Linkification failed", ex); 1237af577fd49d334060f34d3e40e48c762ff5f0de4fAndy McFadden } 123873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 1239ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan textView.setOnTouchListener(new OnTouchListener() { 1240c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden @Override 1241ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan public boolean onTouch(View v, MotionEvent event) { 1242ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan try { 1243ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan return v.onTouchEvent(event); 1244ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan } catch (ActivityNotFoundException e) { 1245ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan // ignore 1246ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan return true; 12472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1248ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan } 1249ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan }); 12502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 12512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 12522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 12532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Description 1254352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (description != null && description.length() != 0) { 125599704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan mDesc.setText(description); 12562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 12572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 12582c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan // Launch Custom App 1259fac2d1594f7ecae8e50dc7790ce67de0c9b70d22Sara Ting if (Utils.isJellybeanOrLater()) { 1260693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan updateCustomAppButton(); 1261693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 12622c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 12632c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12642c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan private void updateCustomAppButton() { 12652c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan buttonSetup: { 12662c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan final Button launchButton = (Button) mView.findViewById(R.id.launch_custom_app_button); 12672c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (launchButton == null) 12682c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 12692c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12702c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan final String customAppPackage = mEventCursor.getString(EVENT_INDEX_CUSTOM_APP_PACKAGE); 12712c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan final String customAppUri = mEventCursor.getString(EVENT_INDEX_CUSTOM_APP_URI); 12722c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12732c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (TextUtils.isEmpty(customAppPackage) || TextUtils.isEmpty(customAppUri)) 12742c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 12752c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12762c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan PackageManager pm = mContext.getPackageManager(); 12772c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (pm == null) 12782c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 12792c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12802c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan ApplicationInfo info; 12812c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan try { 12822c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan info = pm.getApplicationInfo(customAppPackage, 0); 12832c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (info == null) 12842c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 12852c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } catch (NameNotFoundException e) { 12862c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 12872c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 12882c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12892c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 12902c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan final Intent intent = new Intent(CalendarContract.ACTION_HANDLE_CUSTOM_EVENT, uri); 12912c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan intent.setPackage(customAppPackage); 12922c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan intent.putExtra(CalendarContract.EXTRA_CUSTOM_APP_URI, customAppUri); 12932c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan intent.putExtra(EXTRA_EVENT_BEGIN_TIME, mStartMillis); 12942c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12952c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan // See if we have a taker for our intent 12962c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (pm.resolveActivity(intent, 0) == null) 12972c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 12982c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 12992c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Drawable icon = pm.getApplicationIcon(info); 13002c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (icon != null) { 13012c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 13022c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan Drawable[] d = launchButton.getCompoundDrawables(); 13032c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan icon.setBounds(0, 0, mCustomAppIconSize, mCustomAppIconSize); 13042c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan launchButton.setCompoundDrawables(icon, d[1], d[2], d[3]); 13052c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 13062c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 13072c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan CharSequence label = pm.getApplicationLabel(info); 13082c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan if (label != null && label.length() != 0) { 13092c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan launchButton.setText(label); 13102c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } else if (icon == null) { 13112c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan // No icon && no label. Hide button? 13122c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan break buttonSetup; 13132c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 13142c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 13152c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan // Launch custom app 13162c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan launchButton.setOnClickListener(new View.OnClickListener() { 13172c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan @Override 13182c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan public void onClick(View v) { 13192c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan try { 13202c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan startActivityForResult(intent, 0); 13212c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } catch (ActivityNotFoundException e) { 13222c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan // Shouldn't happen as we checked it already 13232c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan setVisibilityCommon(mView, R.id.launch_custom_app_container, View.GONE); 13242c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 13252c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 13262c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan }); 13272c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 13282c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan setVisibilityCommon(mView, R.id.launch_custom_app_container, View.VISIBLE); 13292c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan return; 13302c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 13312c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan } 13322c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan 13332c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan setVisibilityCommon(mView, R.id.launch_custom_app_container, View.GONE); 13342c8485c84855545a0a8a0a7cb26d7c401a32cdd5Michael Chan return; 13358f4d969064ceeec166f709b81cc7b8427686154eIsaac Katzenelson } 133675f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting 133773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /** 1338fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * Finds North American Numbering Plan (NANP) phone numbers in the input text. 1339fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 1340fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * @param text The text to scan. 1341fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * @return A list of [start, end) pairs indicating the positions of phone numbers in the input. 1342fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden */ 1343fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // @VisibleForTesting 1344fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden static int[] findNanpPhoneNumbers(CharSequence text) { 1345fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden ArrayList<Integer> list = new ArrayList<Integer>(); 1346fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1347fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int startPos = 0; 1348fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int endPos = text.length() - NANP_MIN_DIGITS + 1; 1349fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (endPos < 0) { 1350fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden return new int[] {}; 1351fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1352fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1353fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden /* 1354fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * We can't just strip the whitespace out and crunch it down, because the whitespace 1355fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * is significant. March through, trying to figure out where numbers start and end. 1356fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden */ 1357fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden while (startPos < endPos) { 1358fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // skip whitespace 1359fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden while (Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) { 1360fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden startPos++; 1361fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1362fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (startPos == endPos) { 1363fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden break; 1364fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1365fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1366fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // check for a match at this position 1367fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int matchEnd = findNanpMatchEnd(text, startPos); 1368fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (matchEnd > startPos) { 1369fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden list.add(startPos); 1370fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden list.add(matchEnd); 1371fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden startPos = matchEnd; // skip past match 1372fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } else { 1373fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // skip to next whitespace char 1374fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden while (!Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) { 1375fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden startPos++; 1376fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1377fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1378fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1379fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1380fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int[] result = new int[list.size()]; 1381fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden for (int i = list.size() - 1; i >= 0; i--) { 1382fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden result[i] = list.get(i); 1383fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1384fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden return result; 1385fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1386fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1387fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden /** 1388fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * Checks to see if there is a valid phone number in the input, starting at the specified 1389fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * offset. If so, the index of the last character + 1 is returned. The input is assumed 1390fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * to begin with a non-whitespace character. 1391fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 1392fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * @return Exclusive end position, or -1 if not a match. 1393fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden */ 1394fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden private static int findNanpMatchEnd(CharSequence text, int startPos) { 1395fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden /* 1396fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * A few interesting cases: 1397fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 94043 # too short, ignore 1398fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 123456789012 # too long, ignore 1399fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * +1 (650) 555-1212 # 11 digits, spaces 1400c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein * (650) 555 5555 # Second space, only when first is present. 1401fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * (650) 555-1212, (650) 555-1213 # two numbers, return first 1402fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 1-650-555-1212 # 11 digits with leading '1' 1403fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * *#650.555.1212#*! # 10 digits, include #*, ignore trailing '!' 1404fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 555.1212 # 7 digits 1405fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 1406fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * For the most part we want to break on whitespace, but it's common to leave a space 1407fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * between the initial '1' and/or after the area code. 1408fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden */ 1409fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1410c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein // Check for "tel:" URI prefix. 1411c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein if (text.length() > startPos+4 1412c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein && text.subSequence(startPos, startPos+4).toString().equalsIgnoreCase("tel:")) { 1413c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein startPos += 4; 1414c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein } 1415c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein 1416fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int endPos = text.length(); 1417fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int curPos = startPos; 1418fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int foundDigits = 0; 1419fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden char firstDigit = 'x'; 1420c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein boolean foundWhiteSpaceAfterAreaCode = false; 1421fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1422fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden while (curPos <= endPos) { 1423fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden char ch; 1424fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (curPos < endPos) { 1425fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden ch = text.charAt(curPos); 1426fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } else { 1427fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden ch = 27; // fake invalid symbol at end to trigger loop break 1428fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1429fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1430fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (Character.isDigit(ch)) { 1431fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (foundDigits == 0) { 1432fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden firstDigit = ch; 1433fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1434fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden foundDigits++; 1435fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if (foundDigits > NANP_MAX_DIGITS) { 1436fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // too many digits, stop early 1437fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden return -1; 1438fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1439fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } else if (Character.isWhitespace(ch)) { 1440c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein if ( (firstDigit == '1' && foundDigits == 4) || 1441c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein (foundDigits == 3)) { 1442c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein foundWhiteSpaceAfterAreaCode = true; 1443c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein } else if (firstDigit == '1' && foundDigits == 1) { 1444c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein } else if (foundWhiteSpaceAfterAreaCode 1445c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein && ( (firstDigit == '1' && (foundDigits == 7)) || (foundDigits == 6))) { 1446c5cbf21580877c3ab4732f146bf81f6631464e6dSam Blitzstein } else { 1447fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden break; 1448fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1449fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } else if (NANP_ALLOWED_SYMBOLS.indexOf(ch) == -1) { 1450fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden break; 1451fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1452fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // else it's an allowed symbol 1453fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1454fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden curPos++; 1455fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1456fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1457fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden if ((firstDigit != '1' && (foundDigits == 7 || foundDigits == 10)) || 1458fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden (firstDigit == '1' && foundDigits == 11)) { 1459fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden // match 1460fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden return curPos; 1461fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1462fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 1463fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden return -1; 1464fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden } 1465fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden 146609e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting private static int indexFirstNonWhitespaceChar(CharSequence str) { 146709e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting for (int i = 0; i < str.length(); i++) { 146809e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting if (!Character.isWhitespace(str.charAt(i))) { 146909e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting return i; 147009e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 147109e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 147209e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting return -1; 147309e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 147409e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting 147509e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting private static int indexLastNonWhitespaceChar(CharSequence str) { 147609e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting for (int i = str.length() - 1; i >= 0; i--) { 147709e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting if (!Character.isWhitespace(str.charAt(i))) { 147809e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting return i; 147909e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 148009e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 148109e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting return -1; 148209e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 148309e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting 1484fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden /** 148573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Replaces stretches of text that look like addresses and phone numbers with clickable 148673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * links. 148773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * <p> 148873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * This is really just an enhanced version of Linkify.addLinks(). 148973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 149073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden private static void linkifyTextView(TextView textView) { 149173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 149273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * If the text includes a street address like "1600 Amphitheater Parkway, 94043", 149373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * the current Linkify code will identify "94043" as a phone number and invite 149409e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting * you to dial it (and not provide a map link for the address). For outside US, 149509e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting * use Linkify result iff it spans the entire text. Otherwise send the user to maps. 149609e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting */ 149709e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting String defaultPhoneRegion = System.getProperty("user.region", "US"); 149809e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting if (!defaultPhoneRegion.equals("US")) { 149909e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting CharSequence origText = textView.getText(); 150009e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting Linkify.addLinks(textView, Linkify.ALL); 150109e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting 150209e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting // If Linkify links the entire text, use that result. 150309e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting if (textView.getText() instanceof Spannable) { 150409e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting Spannable spanText = (Spannable) textView.getText(); 150509e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting URLSpan[] spans = spanText.getSpans(0, spanText.length(), URLSpan.class); 150609e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting if (spans.length == 1) { 150709e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting int linkStart = spanText.getSpanStart(spans[0]); 150809e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting int linkEnd = spanText.getSpanEnd(spans[0]); 150909e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting if (linkStart <= indexFirstNonWhitespaceChar(origText) && 151009e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting linkEnd >= indexLastNonWhitespaceChar(origText) + 1) { 151109e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting return; 151209e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 151309e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 151409e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 151509e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting 151609e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting // Otherwise default to geo. 151709e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting textView.setText(origText); 151809e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q="); 151909e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting return; 152009e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting } 152109e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting 152209e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting /* 152309e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting * For within US, we want to have better recognition of phone numbers without losing 152409e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting * any of the existing annotations. Ideally this would be addressed by improving Linkify. 152509e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting * For now we manage it as a second pass over the text. 152673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 152773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * URIs and e-mail addresses are pretty easy to pick out of text. Phone numbers 152873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * are a bit tricky because they have radically different formats in different 152973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * countries, in terms of both the digits and the way in which they are commonly 153073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * written or presented (e.g. the punctuation and spaces in "(650) 555-1212"). 153173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The expected format of a street address is defined in WebView.findAddress(). It's 153273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * pretty narrowly defined, so it won't often match. 153373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 153473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The RFC 3966 specification defines the format of a "tel:" URI. 153509e8b5ada4553fcf1214dd9163dac418c16fade0Sara Ting * 153673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Start by letting Linkify find anything that isn't a phone number. We have to let it 153773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * run first because every invocation removes all previous URLSpan annotations. 1538fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * 1539fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * Ideally we'd use the external/libphonenumber routines, but those aren't available 1540fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * to unbundled applications. 154173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 154273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden boolean linkifyFoundLinks = Linkify.addLinks(textView, 154373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Linkify.ALL & ~(Linkify.PHONE_NUMBERS)); 154473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 154573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 154673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Search for phone numbers. 154773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 1548fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * Some URIs contain strings of digits that look like phone numbers. If both the URI 1549fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * scanner and the phone number scanner find them, we want the URI link to win. Since 1550fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden * the URI scanner runs first, we just need to avoid creating overlapping spans. 155173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 155273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden CharSequence text = textView.getText(); 1553fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int[] phoneSequences = findNanpPhoneNumbers(text); 155473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 155573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 155673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * If the contents of the TextView are already Spannable (which will be the case if 155773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Linkify found stuff, but might not be otherwise), we can just add annotations 155873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * to what's there. If it's not, and we find phone numbers, we need to convert it to 155973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * a Spannable form. (This mimics the behavior of Linkable.addLinks().) 156073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 156173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Spannable spanText; 156273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (text instanceof SpannableString) { 156373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden spanText = (SpannableString) text; 156473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } else { 156573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden spanText = SpannableString.valueOf(text); 156673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 156773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 156873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 156973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Get a list of any spans created by Linkify, for the overlapping span check. 157073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 157173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class); 157273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 157373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 157473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Insert spans for the numbers we found. We generate "tel:" URIs. 157573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 157673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int phoneCount = 0; 1577fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden for (int match = 0; match < phoneSequences.length / 2; match++) { 1578fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int start = phoneSequences[match*2]; 1579fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden int end = phoneSequences[match*2 + 1]; 158073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 158173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (spanWillOverlap(spanText, existingSpans, start, end)) { 158273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (Log.isLoggable(TAG, Log.VERBOSE)) { 1583fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden CharSequence seq = text.subSequence(start, end); 1584fd8ce5e0d40a4a55e9425fe95e9c1ebdf6f9cee9Andy McFadden Log.v(TAG, "Not linkifying " + seq + " as phone number due to overlap"); 158573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 158673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden continue; 158773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 158873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 158973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 159073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The Linkify code takes the matching span and strips out everything that isn't a 159173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * digit or '+' sign. We do the same here. Extension numbers will get appended 159273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * without a separator, but the dialer wasn't doing anything useful with ";ext=" 159373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * anyway. 159473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 159573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 159673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden //String dialStr = phoneUtil.format(match.number(), 159773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // PhoneNumberUtil.PhoneNumberFormat.RFC3966); 159873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden StringBuilder dialBuilder = new StringBuilder(); 159973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden for (int i = start; i < end; i++) { 160073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden char ch = spanText.charAt(i); 160173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (ch == '+' || Character.isDigit(ch)) { 160273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden dialBuilder.append(ch); 160373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 160473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 160573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden URLSpan span = new URLSpan("tel:" + dialBuilder.toString()); 160673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 160773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 160873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden phoneCount++; 160973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 161073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 161173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (phoneCount != 0) { 161273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // If we had to "upgrade" to Spannable, store the object into the TextView. 161373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (spanText != text) { 161473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden textView.setText(spanText); 161573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 161673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 161773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // Linkify.addLinks() sets the TextView movement method if it finds any links. We 161873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // want to do the same here. (This is cloned from Linkify.addLinkMovementMethod().) 161973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden MovementMethod mm = textView.getMovementMethod(); 162073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 162173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if ((mm == null) || !(mm instanceof LinkMovementMethod)) { 162273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (textView.getLinksClickable()) { 162373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden textView.setMovementMethod(LinkMovementMethod.getInstance()); 162473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 162573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 162673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 162773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 162873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (!linkifyFoundLinks && phoneCount == 0) { 162973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (Log.isLoggable(TAG, Log.VERBOSE)) { 163073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Log.v(TAG, "No linkification matches, using geo default"); 163173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 163273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q="); 163373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 163473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 163573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 163673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /** 163773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Determines whether a new span at [start,end) will overlap with any existing span. 163873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 163973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden private static boolean spanWillOverlap(Spannable spanText, URLSpan[] spanList, int start, 164073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int end) { 164173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (start == end) { 164273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // empty span, ignore 164373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden return false; 164473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 164573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden for (URLSpan span : spanList) { 164673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int existingStart = spanText.getSpanStart(span); 164773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int existingEnd = spanText.getSpanEnd(span); 164873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if ((start >= existingStart && start < existingEnd) || 164973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden end > existingStart && end <= existingEnd) { 165073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden return true; 165173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 165273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 165373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 165473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden return false; 165573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 165673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 1657259b8f9a21fffd3858218581e9daaf689b6b888fErik private void sendAccessibilityEvent() { 1658ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden AccessibilityManager am = 1659ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden (AccessibilityManager) getActivity().getSystemService(Service.ACCESSIBILITY_SERVICE); 1660259b8f9a21fffd3858218581e9daaf689b6b888fErik if (!am.isEnabled()) { 1661259b8f9a21fffd3858218581e9daaf689b6b888fErik return; 1662259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1663259b8f9a21fffd3858218581e9daaf689b6b888fErik 1664259b8f9a21fffd3858218581e9daaf689b6b888fErik AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED); 1665259b8f9a21fffd3858218581e9daaf689b6b888fErik event.setClassName(getClass().getName()); 1666259b8f9a21fffd3858218581e9daaf689b6b888fErik event.setPackageName(getActivity().getPackageName()); 1667259b8f9a21fffd3858218581e9daaf689b6b888fErik List<CharSequence> text = event.getText(); 1668259b8f9a21fffd3858218581e9daaf689b6b888fErik 166999704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan addFieldToAccessibilityEvent(text, mTitle, null); 167075f53668f94c3ced9d3cc8583d7e45ce725ff9deSara Ting addFieldToAccessibilityEvent(text, mWhenDateTime, null); 167199704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan addFieldToAccessibilityEvent(text, mWhere, null); 167299704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan addFieldToAccessibilityEvent(text, null, mDesc); 1673259b8f9a21fffd3858218581e9daaf689b6b888fErik 1674259b8f9a21fffd3858218581e9daaf689b6b888fErik RadioGroup response = (RadioGroup) getView().findViewById(R.id.response_value); 1675259b8f9a21fffd3858218581e9daaf689b6b888fErik if (response.getVisibility() == View.VISIBLE) { 1676259b8f9a21fffd3858218581e9daaf689b6b888fErik int id = response.getCheckedRadioButtonId(); 1677259b8f9a21fffd3858218581e9daaf689b6b888fErik if (id != View.NO_ID) { 1678259b8f9a21fffd3858218581e9daaf689b6b888fErik text.add(((TextView) getView().findViewById(R.id.response_label)).getText()); 1679259b8f9a21fffd3858218581e9daaf689b6b888fErik text.add((((RadioButton) (response.findViewById(id))).getText() + PERIOD_SPACE)); 1680259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1681259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1682259b8f9a21fffd3858218581e9daaf689b6b888fErik 1683259b8f9a21fffd3858218581e9daaf689b6b888fErik am.sendAccessibilityEvent(event); 1684259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1685259b8f9a21fffd3858218581e9daaf689b6b888fErik 168699704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan private void addFieldToAccessibilityEvent(List<CharSequence> text, TextView tv, 168799704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan ExpandableTextView etv) { 16883389397186b93936747d4009a35f5bae605c246eMichael Chan CharSequence cs; 168999704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan if (tv != null) { 16903389397186b93936747d4009a35f5bae605c246eMichael Chan cs = tv.getText(); 169199704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan } else if (etv != null) { 16923389397186b93936747d4009a35f5bae605c246eMichael Chan cs = etv.getText(); 169399704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan } else { 16949ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson return; 16959ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson } 169699704a2787158bf670fa4a7b4e4f89ace10afa00Michael Chan 16973389397186b93936747d4009a35f5bae605c246eMichael Chan if (!TextUtils.isEmpty(cs)) { 16983389397186b93936747d4009a35f5bae605c246eMichael Chan cs = cs.toString().trim(); 16993389397186b93936747d4009a35f5bae605c246eMichael Chan if (cs.length() > 0) { 17003389397186b93936747d4009a35f5bae605c246eMichael Chan text.add(cs); 17013389397186b93936747d4009a35f5bae605c246eMichael Chan text.add(PERIOD_SPACE); 17023389397186b93936747d4009a35f5bae605c246eMichael Chan } 1703259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1704259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1705259b8f9a21fffd3858218581e9daaf689b6b888fErik 17062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateCalendar(View view) { 17072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAccount = ""; 17082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mCalendarsCursor != null && mEventCursor != null) { 17092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarsCursor.moveToFirst(); 17102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String tempAccount = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT); 17112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAccount = (tempAccount == null) ? "" : tempAccount; 1712352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOwnerCanRespond = mCalendarsCursor.getInt(CALENDARS_INDEX_OWNER_CAN_RESPOND) != 0; 171342896f76d81dbae873614340a3a78b29e7d463d2Sara Ting mSyncAccountName = mCalendarsCursor.getString(CALENDARS_INDEX_ACCOUNT_NAME); 17142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 17152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String displayName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME); 17162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 17176aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting // start visible calendars query 17186aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting mHandler.startQuery(TOKEN_QUERY_VISIBLE_CALENDARS, null, Calendars.CONTENT_URI, 17196aad0ffcbdda48fc895543e2780b1d1c9fef3942Sara Ting CALENDARS_PROJECTION, CALENDARS_VISIBLE_WHERE, new String[] {"1"}, null); 17202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 172183efa2d50deca53c9937b19a379045c31b541cb7Michael Chan mEventOrganizerEmail = mEventCursor.getString(EVENT_INDEX_ORGANIZER); 172283efa2d50deca53c9937b19a379045c31b541cb7Michael Chan mIsOrganizer = mCalendarOwnerAccount.equalsIgnoreCase(mEventOrganizerEmail); 172383efa2d50deca53c9937b19a379045c31b541cb7Michael Chan 17240c0da940484dc8966576634475daa126b4a6ede2Sara Ting if (!TextUtils.isEmpty(mEventOrganizerEmail) && 17250c0da940484dc8966576634475daa126b4a6ede2Sara Ting !mEventOrganizerEmail.endsWith(Utils.MACHINE_GENERATED_ADDRESS)) { 172683efa2d50deca53c9937b19a379045c31b541cb7Michael Chan mEventOrganizerDisplayName = mEventOrganizerEmail; 172783efa2d50deca53c9937b19a379045c31b541cb7Michael Chan } 172883efa2d50deca53c9937b19a379045c31b541cb7Michael Chan 172983efa2d50deca53c9937b19a379045c31b541cb7Michael Chan if (!mIsOrganizer && !TextUtils.isEmpty(mEventOrganizerDisplayName)) { 173083efa2d50deca53c9937b19a379045c31b541cb7Michael Chan setTextCommon(view, R.id.organizer, mEventOrganizerDisplayName); 1731b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson setVisibilityCommon(view, R.id.organizer_container, View.VISIBLE); 1732b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson } else { 1733b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson setVisibilityCommon(view, R.id.organizer_container, View.GONE); 1734b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson } 17352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHasAttendeeData = mEventCursor.getInt(EVENT_INDEX_HAS_ATTENDEE_DATA) != 0; 173665eeb79e62034d706503ce29d88c0e05ebd726feRoboErik mCanModifyCalendar = mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) 173765eeb79e62034d706503ce29d88c0e05ebd726feRoboErik >= Calendars.CAL_ACCESS_CONTRIBUTOR; 173865eeb79e62034d706503ce29d88c0e05ebd726feRoboErik // TODO add "|| guestCanModify" after b/1299071 is fixed 173965eeb79e62034d706503ce29d88c0e05ebd726feRoboErik mCanModifyEvent = mCanModifyCalendar && mIsOrganizer; 17402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mIsBusyFreeCalendar = 1741ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) == Calendars.CAL_ACCESS_FREEBUSY; 1742352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 1743352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (!mIsBusyFreeCalendar) { 1744d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson 1745d4e45fa96c8c377d91271fbb368db64dc1fd5b48Isaac Katzenelson View b = mView.findViewById(R.id.edit); 1746352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan b.setEnabled(true); 17478ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan b.setOnClickListener(new OnClickListener() { 17488ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan @Override 17498ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan public void onClick(View v) { 17508ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan doEdit(); 175110b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // For dialogs, just close the fragment 175210b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // For full screen, close activity on phone, leave it for tablet 175360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (mIsDialog) { 175460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson EventInfoFragment.this.dismiss(); 175560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 175610b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson else if (!mIsTabletConfig){ 175760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson getActivity().finish(); 175860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 1759352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 1760352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan }); 17618ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 1762dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira View button; 176342896f76d81dbae873614340a3a78b29e7d463d2Sara Ting if (mCanModifyCalendar) { 1764dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button = mView.findViewById(R.id.delete); 1765dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira if (button != null) { 176642896f76d81dbae873614340a3a78b29e7d463d2Sara Ting button.setEnabled(true); 176742896f76d81dbae873614340a3a78b29e7d463d2Sara Ting button.setVisibility(View.VISIBLE); 176865eeb79e62034d706503ce29d88c0e05ebd726feRoboErik } 1769dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira } 177042896f76d81dbae873614340a3a78b29e7d463d2Sara Ting if (mCanModifyEvent) { 1771dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button = mView.findViewById(R.id.edit); 1772dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira if (button != null) { 177342896f76d81dbae873614340a3a78b29e7d463d2Sara Ting button.setEnabled(true); 177442896f76d81dbae873614340a3a78b29e7d463d2Sara Ting button.setVisibility(View.VISIBLE); 177560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 1776d8353fb85ef59a88580125207be9c914a8586758RoboErik } 177742896f76d81dbae873614340a3a78b29e7d463d2Sara Ting 17787ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson if ((!mIsDialog && !mIsTabletConfig || 17797ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) && mMenu != null) { 1780d8353fb85ef59a88580125207be9c914a8586758RoboErik mActivity.invalidateOptionsMenu(); 178169be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik } 17822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 178371b221ae5d0f514352584a955630f5494f686c51Michael Chan setVisibilityCommon(view, R.id.calendar, View.GONE); 1784259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEventIfQueryDone(TOKEN_QUERY_DUPLICATE_CALENDARS); 17852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 17862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 17872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1788d8353fb85ef59a88580125207be9c914a8586758RoboErik /** 1789d8353fb85ef59a88580125207be9c914a8586758RoboErik * 1790d8353fb85ef59a88580125207be9c914a8586758RoboErik */ 1791d8353fb85ef59a88580125207be9c914a8586758RoboErik private void updateMenu() { 1792d8353fb85ef59a88580125207be9c914a8586758RoboErik if (mMenu == null) { 1793d8353fb85ef59a88580125207be9c914a8586758RoboErik return; 1794d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1795d8353fb85ef59a88580125207be9c914a8586758RoboErik MenuItem delete = mMenu.findItem(R.id.info_action_delete); 1796d8353fb85ef59a88580125207be9c914a8586758RoboErik MenuItem edit = mMenu.findItem(R.id.info_action_edit); 1797d8353fb85ef59a88580125207be9c914a8586758RoboErik if (delete != null) { 1798d8353fb85ef59a88580125207be9c914a8586758RoboErik delete.setVisible(mCanModifyCalendar); 1799d8353fb85ef59a88580125207be9c914a8586758RoboErik delete.setEnabled(mCanModifyCalendar); 1800d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1801d8353fb85ef59a88580125207be9c914a8586758RoboErik if (edit != null) { 180265eeb79e62034d706503ce29d88c0e05ebd726feRoboErik edit.setVisible(mCanModifyEvent); 180365eeb79e62034d706503ce29d88c0e05ebd726feRoboErik edit.setEnabled(mCanModifyEvent); 1804d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1805d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1806d8353fb85ef59a88580125207be9c914a8586758RoboErik 18072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateAttendees(View view) { 1808fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (mAcceptedAttendees.size() + mDeclinedAttendees.size() + 1809fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mTentativeAttendees.size() + mNoResponseAttendees.size() > 0) { 1810c7f3c3896f1bc4cad43aa7f0bca1dee603704613RoboErik mLongAttendees.clearAttendees(); 18114acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mAcceptedAttendees); 18124acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mDeclinedAttendees); 18134acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mTentativeAttendees); 18144acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mNoResponseAttendees); 1815fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mLongAttendees.setEnabled(false); 1816fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mLongAttendees.setVisibility(View.VISIBLE); 181760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } else { 1818fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mLongAttendees.setVisibility(View.GONE); 181971b221ae5d0f514352584a955630f5494f686c51Michael Chan } 1820cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting 18217ffa24cba2977925b737e6bd39be59ba39609611Sara Ting if (hasEmailableAttendees()) { 18227da27670d2a62e213e230989b250f047012a3bbdSara Ting setVisibilityCommon(mView, R.id.email_attendees_container, View.VISIBLE); 18237ffa24cba2977925b737e6bd39be59ba39609611Sara Ting if (emailAttendeesButton != null) { 18247ffa24cba2977925b737e6bd39be59ba39609611Sara Ting emailAttendeesButton.setText(R.string.email_guests_label); 18257ffa24cba2977925b737e6bd39be59ba39609611Sara Ting } 18267ffa24cba2977925b737e6bd39be59ba39609611Sara Ting } else if (hasEmailableOrganizer()) { 18277ffa24cba2977925b737e6bd39be59ba39609611Sara Ting setVisibilityCommon(mView, R.id.email_attendees_container, View.VISIBLE); 18287ffa24cba2977925b737e6bd39be59ba39609611Sara Ting if (emailAttendeesButton != null) { 18297ffa24cba2977925b737e6bd39be59ba39609611Sara Ting emailAttendeesButton.setText(R.string.email_organizer_label); 18307ffa24cba2977925b737e6bd39be59ba39609611Sara Ting } 18317da27670d2a62e213e230989b250f047012a3bbdSara Ting } else { 18327da27670d2a62e213e230989b250f047012a3bbdSara Ting setVisibilityCommon(mView, R.id.email_attendees_container, View.GONE); 18337da27670d2a62e213e230989b250f047012a3bbdSara Ting } 1834cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 1835cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting 1836cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting /** 18377da27670d2a62e213e230989b250f047012a3bbdSara Ting * Returns true if there is at least 1 attendee that is not the viewer. 1838cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting */ 18397ffa24cba2977925b737e6bd39be59ba39609611Sara Ting private boolean hasEmailableAttendees() { 1840cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting for (Attendee attendee : mAcceptedAttendees) { 18417da27670d2a62e213e230989b250f047012a3bbdSara Ting if (Utils.isEmailableFrom(attendee.mEmail, mSyncAccountName)) { 18427da27670d2a62e213e230989b250f047012a3bbdSara Ting return true; 18437da27670d2a62e213e230989b250f047012a3bbdSara Ting } 1844cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 1845cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting for (Attendee attendee : mTentativeAttendees) { 18467da27670d2a62e213e230989b250f047012a3bbdSara Ting if (Utils.isEmailableFrom(attendee.mEmail, mSyncAccountName)) { 18477da27670d2a62e213e230989b250f047012a3bbdSara Ting return true; 18487da27670d2a62e213e230989b250f047012a3bbdSara Ting } 1849cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 1850cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting for (Attendee attendee : mNoResponseAttendees) { 18517da27670d2a62e213e230989b250f047012a3bbdSara Ting if (Utils.isEmailableFrom(attendee.mEmail, mSyncAccountName)) { 18527da27670d2a62e213e230989b250f047012a3bbdSara Ting return true; 18537da27670d2a62e213e230989b250f047012a3bbdSara Ting } 1854cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 18557da27670d2a62e213e230989b250f047012a3bbdSara Ting for (Attendee attendee : mDeclinedAttendees) { 18567da27670d2a62e213e230989b250f047012a3bbdSara Ting if (Utils.isEmailableFrom(attendee.mEmail, mSyncAccountName)) { 18577da27670d2a62e213e230989b250f047012a3bbdSara Ting return true; 18587da27670d2a62e213e230989b250f047012a3bbdSara Ting } 1859cb5f5688a4080e6a20f4f7a52adef1ed971035cbSara Ting } 18607ffa24cba2977925b737e6bd39be59ba39609611Sara Ting return false; 18617ffa24cba2977925b737e6bd39be59ba39609611Sara Ting } 18627ffa24cba2977925b737e6bd39be59ba39609611Sara Ting 18637ffa24cba2977925b737e6bd39be59ba39609611Sara Ting private boolean hasEmailableOrganizer() { 18647da27670d2a62e213e230989b250f047012a3bbdSara Ting return mEventOrganizerEmail != null && 18657da27670d2a62e213e230989b250f047012a3bbdSara Ting Utils.isEmailableFrom(mEventOrganizerEmail, mSyncAccountName); 18668ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 18678ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 18681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public void initReminders(View view, Cursor cursor) { 18691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 18701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Add reminders 1871c7f3c3896f1bc4cad43aa7f0bca1dee603704613RoboErik mOriginalReminders.clear(); 1872c08957b48e755d34f1496d3937a24d60bdd24904RoboErik mUnsupportedReminders.clear(); 18731ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson while (cursor.moveToNext()) { 18741ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int minutes = cursor.getInt(EditEventHelper.REMINDERS_INDEX_MINUTES); 18751ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int method = cursor.getInt(EditEventHelper.REMINDERS_INDEX_METHOD); 1876e35a032c939f357ce435711b2fd8de1887a05011RoboErik 1877c08957b48e755d34f1496d3937a24d60bdd24904RoboErik if (method != Reminders.METHOD_DEFAULT && !mReminderMethodValues.contains(method)) { 1878e35a032c939f357ce435711b2fd8de1887a05011RoboErik // Stash unsupported reminder types separately so we don't alter 1879e35a032c939f357ce435711b2fd8de1887a05011RoboErik // them in the UI 1880e35a032c939f357ce435711b2fd8de1887a05011RoboErik mUnsupportedReminders.add(ReminderEntry.valueOf(minutes, method)); 1881e35a032c939f357ce435711b2fd8de1887a05011RoboErik } else { 1882e35a032c939f357ce435711b2fd8de1887a05011RoboErik mOriginalReminders.add(ReminderEntry.valueOf(minutes, method)); 1883e35a032c939f357ce435711b2fd8de1887a05011RoboErik } 18841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 18851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Sort appropriately for display (by time, then type) 18861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Collections.sort(mOriginalReminders); 18871ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 18888b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik if (mUserModifiedReminders) { 18898b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik // If the user has changed the list of reminders don't change what's 18908b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik // shown. 18918b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik return; 18928b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik } 18938b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik 18945d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik LinearLayout parent = (LinearLayout) mScrollView 18955d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik .findViewById(R.id.reminder_items_container); 18965d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik if (parent != null) { 18975d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik parent.removeAllViews(); 18985d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik } 1899c08957b48e755d34f1496d3937a24d60bdd24904RoboErik if (mReminderViews != null) { 1900c08957b48e755d34f1496d3937a24d60bdd24904RoboErik mReminderViews.clear(); 1901c08957b48e755d34f1496d3937a24d60bdd24904RoboErik } 19025d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik 19031ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mHasAlarm) { 19041ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<ReminderEntry> reminders = mOriginalReminders; 19051ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Insert any minute values that aren't represented in the minutes list. 19061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson for (ReminderEntry re : reminders) { 19071ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addMinutesToList( 19081ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mActivity, mReminderMinuteValues, mReminderMinuteLabels, re.getMinutes()); 19091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 19101ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Create a UI element for each reminder. We display all of the reminders we get 19111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // from the provider, even if the count exceeds the calendar maximum. (Also, for 19121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // a new event, we won't have a maxReminders value available.) 19131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson for (ReminderEntry re : reminders) { 1914e35a032c939f357ce435711b2fd8de1887a05011RoboErik EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, 1915e35a032c939f357ce435711b2fd8de1887a05011RoboErik mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues, 19168b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderMethodLabels, re, Integer.MAX_VALUE, mReminderChangeListener); 19171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 191806f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting EventViewUtils.updateAddReminderButton(mView, mReminderViews, mMaxReminders); 1919e35a032c939f357ce435711b2fd8de1887a05011RoboErik // TODO show unsupported reminder types in some fashion. 19201ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 19211ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 19221ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 19232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang void updateResponse(View view) { 19242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // we only let the user accept/reject/etc. a meeting if: 19252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // a) you can edit the event's containing calendar AND 19262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // b) you're not the organizer and only attendee AND 19272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // c) organizerCanRespond is enabled for the calendar 19282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // (if the attendee data has been hidden, the visible number of attendees 19292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // will be 1 -- the calendar owner's). 19302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // (there are more cases involved to be 100% accurate, such as 19312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // paying attention to whether or not an attendee status was 19322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // included in the feed, but we're currently omitting those corner cases 19332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // for simplicity). 1934352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 1935352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // TODO Switch to EditEventHelper.canRespond when this class uses CalendarEventModel. 1936d785cd533f6a3c23813c15315aed74efa9a116f5Michael Chan if (!mCanModifyCalendar || (mHasAttendeeData && mIsOrganizer && mNumOfAttendees <= 1) || 1937352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan (mIsOrganizer && !mOwnerCanRespond)) { 19382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setVisibilityCommon(view, R.id.response_container, View.GONE); 19392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 19402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 19412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 19422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setVisibilityCommon(view, R.id.response_container, View.VISIBLE); 19432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1944f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 1945f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int response; 19466bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson if (mUserSetResponse != Attendees.ATTENDEE_STATUS_NONE) { 19475afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik response = mUserSetResponse; 19486bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson } else if (mAttendeeResponseFromIntent != Attendees.ATTENDEE_STATUS_NONE) { 1949f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = mAttendeeResponseFromIntent; 19502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 1951f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = mOriginalAttendeeResponse; 19522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1953f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 1954f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int buttonToCheck = findButtonIdForResponse(response); 1955f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.response_value); 1956f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan radioGroup.check(buttonToCheck); // -1 clear all radio buttons 1957f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan radioGroup.setOnCheckedChangeListener(this); 19582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 19592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 19602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void setTextCommon(View view, int id, CharSequence text) { 19612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang TextView textView = (TextView) view.findViewById(id); 19622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (textView == null) 19632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 19642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang textView.setText(text); 19652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 19662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 19672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void setVisibilityCommon(View view, int id, int visibility) { 19682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang View v = view.findViewById(id); 19692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (v != null) { 19702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang v.setVisibility(visibility); 19712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 19722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 19732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 19742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 19752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 19762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Taken from com.google.android.gm.HtmlConversationActivity 19772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 19782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Send the intent that shows the Contact info corresponding to the email address. 19792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 19802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void showContactInfo(Attendee attendee, Rect rect) { 19812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // First perform lookup query to find existing contact 19822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final ContentResolver resolver = getActivity().getContentResolver(); 19832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final String address = attendee.mEmail; 19842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Uri dataUri = Uri.withAppendedPath(CommonDataKinds.Email.CONTENT_FILTER_URI, 19852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Uri.encode(address)); 19862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Uri lookupUri = ContactsContract.Data.getContactLookupUri(resolver, dataUri); 19872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 19882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (lookupUri != null) { 19892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Found matching contact, trigger QuickContact 19902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang QuickContact.showQuickContact(getActivity(), rect, lookupUri, 19912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang QuickContact.MODE_MEDIUM, null); 19922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 19932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // No matching contact, ask user to create one 19942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Uri mailUri = Uri.fromParts("mailto", address, null); 19952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, mailUri); 19962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 19972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Pass along full E-mail string for possible create dialog 19982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Rfc822Token sender = new Rfc822Token(attendee.mName, attendee.mEmail, null); 19992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang intent.putExtra(Intents.EXTRA_CREATE_DESCRIPTION, sender.toString()); 20002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 20012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Only provide personal name hint if we have one 20022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final String senderPersonal = attendee.mName; 20032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!TextUtils.isEmpty(senderPersonal)) { 20042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang intent.putExtra(Intents.Insert.NAME, senderPersonal); 20052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 20062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 20072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang startActivity(intent); 20082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 20092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 2010cb81189e4868769ea016253eca104e46df2f033aErik 2011cb81189e4868769ea016253eca104e46df2f033aErik @Override 20127c6236d5553dc9f3d004ebbed794249713a11d19RoboErik public void onPause() { 20137c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mIsPaused = true; 20147c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mHandler.removeCallbacks(onDeleteRunnable); 20157c6236d5553dc9f3d004ebbed794249713a11d19RoboErik super.onPause(); 2016b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson // Remove event deletion alert box since it is being rebuild in the OnResume 2017b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson // This is done to get the same behavior on OnResume since the AlertDialog is gone on 2018b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson // rotation but not if you press the HOME key 2019b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson if (mDeleteDialogVisible && mDeleteHelper != null) { 2020b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper.dismissAlertDialog(); 2021b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper = null; 2022b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 20237c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 20247c6236d5553dc9f3d004ebbed794249713a11d19RoboErik 20257c6236d5553dc9f3d004ebbed794249713a11d19RoboErik @Override 20267c6236d5553dc9f3d004ebbed794249713a11d19RoboErik public void onResume() { 20277c6236d5553dc9f3d004ebbed794249713a11d19RoboErik super.onResume(); 2028363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan if (mIsDialog) { 2029363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan setDialogSize(getActivity().getResources()); 2030363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan applyDialogParams(); 2031363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan } 20327c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mIsPaused = false; 20337c6236d5553dc9f3d004ebbed794249713a11d19RoboErik if (mDismissOnResume) { 20347c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mHandler.post(onDeleteRunnable); 20357c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 2036b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson // Display the "delete confirmation" dialog if needed 2037b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson if (mDeleteDialogVisible) { 2038b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper = new DeleteEventHelper( 2039b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mContext, mActivity, 2040b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson !mIsDialog && !mIsTabletConfig /* exitWhenDone */); 2041b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener()); 2042b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable); 2043b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 20447c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 20457c6236d5553dc9f3d004ebbed794249713a11d19RoboErik 20467c6236d5553dc9f3d004ebbed794249713a11d19RoboErik @Override 2047cb81189e4868769ea016253eca104e46df2f033aErik public void eventsChanged() { 2048cb81189e4868769ea016253eca104e46df2f033aErik } 2049cb81189e4868769ea016253eca104e46df2f033aErik 2050cb81189e4868769ea016253eca104e46df2f033aErik @Override 2051cb81189e4868769ea016253eca104e46df2f033aErik public long getSupportedEventTypes() { 2052cb81189e4868769ea016253eca104e46df2f033aErik return EventType.EVENTS_CHANGED; 2053cb81189e4868769ea016253eca104e46df2f033aErik } 2054cb81189e4868769ea016253eca104e46df2f033aErik 2055cb81189e4868769ea016253eca104e46df2f033aErik @Override 2056cb81189e4868769ea016253eca104e46df2f033aErik public void handleEvent(EventInfo event) { 2057f836d4af478310abc9b63f1afa6ab964e2478fedRoboErik if (event.eventType == EventType.EVENTS_CHANGED && mHandler != null) { 2058cb81189e4868769ea016253eca104e46df2f033aErik // reload the data 205980d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson reloadEvents(); 2060cb81189e4868769ea016253eca104e46df2f033aErik } 2061cb81189e4868769ea016253eca104e46df2f033aErik } 20621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 206380d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson public void reloadEvents() { 206480d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION, 206580d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson null, null, null); 206680d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson } 20671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 20681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson @Override 20691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public void onClick(View view) { 20701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 20711ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // This must be a click on one of the "remove reminder" buttons 20721ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson LinearLayout reminderItem = (LinearLayout) view.getParent(); 20731ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson LinearLayout parent = (LinearLayout) reminderItem.getParent(); 20741ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson parent.removeView(reminderItem); 20751ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderViews.remove(reminderItem); 20768b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mUserModifiedReminders = true; 207706f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting EventViewUtils.updateAddReminderButton(mView, mReminderViews, mMaxReminders); 20781ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 20791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 20801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 20811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 20821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Add a new reminder when the user hits the "add reminder" button. We use the default 20831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * reminder time and method. 20841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 20851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private void addReminder() { 20861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // TODO: when adding a new reminder, make it different from the 20871ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // last one in the list (if any). 20881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mDefaultReminderMinutes == GeneralPreferences.NO_REMINDER) { 20891ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, 20908b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues, 20918b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderMethodLabels, 20928b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik ReminderEntry.valueOf(GeneralPreferences.REMINDER_DEFAULT_TIME), mMaxReminders, 20938b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderChangeListener); 20941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } else { 20951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, 20968b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues, 20978b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mReminderMethodLabels, ReminderEntry.valueOf(mDefaultReminderMinutes), 20988b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik mMaxReminders, mReminderChangeListener); 20991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 210106f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting EventViewUtils.updateAddReminderButton(mView, mReminderViews, mMaxReminders); 210206f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting } 21031ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2104e35a032c939f357ce435711b2fd8de1887a05011RoboErik synchronized private void prepareReminders() { 2105e35a032c939f357ce435711b2fd8de1887a05011RoboErik // Nothing to do if we've already built these lists _and_ we aren't 2106e35a032c939f357ce435711b2fd8de1887a05011RoboErik // removing not allowed methods 2107e35a032c939f357ce435711b2fd8de1887a05011RoboErik if (mReminderMinuteValues != null && mReminderMinuteLabels != null 2108e35a032c939f357ce435711b2fd8de1887a05011RoboErik && mReminderMethodValues != null && mReminderMethodLabels != null 2109e35a032c939f357ce435711b2fd8de1887a05011RoboErik && mCalendarAllowedReminders == null) { 2110e35a032c939f357ce435711b2fd8de1887a05011RoboErik return; 2111e35a032c939f357ce435711b2fd8de1887a05011RoboErik } 2112e35a032c939f357ce435711b2fd8de1887a05011RoboErik // Load the labels and corresponding numeric values for the minutes and methods lists 2113e35a032c939f357ce435711b2fd8de1887a05011RoboErik // from the assets. If we're switching calendars, we need to clear and re-populate the 2114e35a032c939f357ce435711b2fd8de1887a05011RoboErik // lists (which may have elements added and removed based on calendar properties). This 2115e35a032c939f357ce435711b2fd8de1887a05011RoboErik // is mostly relevant for "methods", since we shouldn't have any "minutes" values in a 2116e35a032c939f357ce435711b2fd8de1887a05011RoboErik // new event that aren't in the default set. 21171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Resources r = mActivity.getResources(); 21181ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues = loadIntegerArray(r, R.array.reminder_minutes_values); 21191ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteLabels = loadStringArray(r, R.array.reminder_minutes_labels); 21201ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodValues = loadIntegerArray(r, R.array.reminder_methods_values); 21211ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodLabels = loadStringArray(r, R.array.reminder_methods_labels); 2122e35a032c939f357ce435711b2fd8de1887a05011RoboErik 2123e35a032c939f357ce435711b2fd8de1887a05011RoboErik // Remove any reminder methods that aren't allowed for this calendar. If this is 2124e35a032c939f357ce435711b2fd8de1887a05011RoboErik // a new event, mCalendarAllowedReminders may not be set the first time we're called. 2125e35a032c939f357ce435711b2fd8de1887a05011RoboErik if (mCalendarAllowedReminders != null) { 2126e35a032c939f357ce435711b2fd8de1887a05011RoboErik EventViewUtils.reduceMethodList(mReminderMethodValues, mReminderMethodLabels, 2127e35a032c939f357ce435711b2fd8de1887a05011RoboErik mCalendarAllowedReminders); 2128e35a032c939f357ce435711b2fd8de1887a05011RoboErik } 2129e35a032c939f357ce435711b2fd8de1887a05011RoboErik if (mView != null) { 2130e35a032c939f357ce435711b2fd8de1887a05011RoboErik mView.invalidate(); 2131e35a032c939f357ce435711b2fd8de1887a05011RoboErik } 21321ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21351ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private boolean saveReminders() { 21361ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(3); 21371ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21381ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Read reminders from UI 21391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminders = EventViewUtils.reminderItemsToReminders(mReminderViews, 21401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues, mReminderMethodValues); 2141e35a032c939f357ce435711b2fd8de1887a05011RoboErik mOriginalReminders.addAll(mUnsupportedReminders); 2142e35a032c939f357ce435711b2fd8de1887a05011RoboErik Collections.sort(mOriginalReminders); 2143e35a032c939f357ce435711b2fd8de1887a05011RoboErik mReminders.addAll(mUnsupportedReminders); 2144e35a032c939f357ce435711b2fd8de1887a05011RoboErik Collections.sort(mReminders); 21451ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Check if there are any changes in the reminder 21471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson boolean changed = EditEventHelper.saveReminders(ops, mEventId, mReminders, 21481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mOriginalReminders, false /* no force save */); 21491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (!changed) { 21511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return false; 21521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // save new reminders 21551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson AsyncQueryService service = new AsyncQueryService(getActivity()); 21561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson service.startBatch(0, null, Calendars.CONTENT_URI.getAuthority(), ops, 0); 21571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Update the "hasAlarm" field for the event 21581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 21591ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int len = mReminders.size(); 21601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson boolean hasAlarm = len > 0; 21611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (hasAlarm != mHasAlarm) { 21621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ContentValues values = new ContentValues(); 21631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson values.put(Events.HAS_ALARM, hasAlarm ? 1 : 0); 21641ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson service.startUpdate(0, null, uri, values, null, null, 0); 21651ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21661ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return true; 21671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 217042896f76d81dbae873614340a3a78b29e7d463d2Sara Ting * Email all the attendees of the event, except for the viewer (so as to not email 217142896f76d81dbae873614340a3a78b29e7d463d2Sara Ting * himself) and resources like conference rooms. 217242896f76d81dbae873614340a3a78b29e7d463d2Sara Ting */ 217342896f76d81dbae873614340a3a78b29e7d463d2Sara Ting private void emailAttendees() { 21747da27670d2a62e213e230989b250f047012a3bbdSara Ting Intent i = new Intent(getActivity(), QuickResponseActivity.class); 21757da27670d2a62e213e230989b250f047012a3bbdSara Ting i.putExtra(QuickResponseActivity.EXTRA_EVENT_ID, mEventId); 21767da27670d2a62e213e230989b250f047012a3bbdSara Ting i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 21777da27670d2a62e213e230989b250f047012a3bbdSara Ting startActivity(i); 217842896f76d81dbae873614340a3a78b29e7d463d2Sara Ting } 217942896f76d81dbae873614340a3a78b29e7d463d2Sara Ting 218042896f76d81dbae873614340a3a78b29e7d463d2Sara Ting /** 21811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Loads an integer array asset into a list. 21821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 21831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static ArrayList<Integer> loadIntegerArray(Resources r, int resNum) { 21841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int[] vals = r.getIntArray(resNum); 21851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int size = vals.length; 21861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<Integer> list = new ArrayList<Integer>(size); 21871ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson for (int i = 0; i < size; i++) { 21891ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson list.add(vals[i]); 21901ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 21921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return list; 21931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 21941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 21951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Loads a String array asset into a list. 21961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 21971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static ArrayList<String> loadStringArray(Resources r, int resNum) { 21981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson String[] labels = r.getStringArray(resNum); 21991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<String> list = new ArrayList<String>(Arrays.asList(labels)); 22001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return list; 22011ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 22021ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2203b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson public void onDeleteStarted() { 2204b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson mEventDeletionStarted = true; 2205b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson } 2206b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 2207b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson private Dialog.OnDismissListener createDeleteOnDismissListener() { 2208b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson return new Dialog.OnDismissListener() { 2209b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson @Override 2210b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson public void onDismiss(DialogInterface dialog) { 2211b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson // Since OnPause will force the dialog to dismiss , do 2212b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson // not change the dialog status 2213b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson if (!mIsPaused) { 2214b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDeleteDialogVisible = false; 2215b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 2216b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 2217b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson }; 2218b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 2219b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson 222080d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson public long getEventId() { 222180d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson return mEventId; 222280d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson } 222380d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson 222480d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson public long getStartMillis() { 222580d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson return mStartMillis; 222680d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson } 222780d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson public long getEndMillis() { 222880d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson return mEndMillis; 222980d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson } 2230363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan private void setDialogSize(Resources r) { 2231363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan mDialogWidth = (int)r.getDimension(R.dimen.event_info_dialog_width); 2232363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan mDialogHeight = (int)r.getDimension(R.dimen.event_info_dialog_height); 2233363aa9c237a33e9e1a40bdfd9039dcaaa855a5a0Michael Chan } 223480d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson 223580d640f3edc455d053a0e71a419f222a6f03385eIsaac Katzenelson 22362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang} 2237