EventInfoFragment.java revision c7f3c3896f1bc4cad43aa7f0bca1dee603704613
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 19d8353fb85ef59a88580125207be9c914a8586758RoboErikimport static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME; 20d8353fb85ef59a88580125207be9c914a8586758RoboErikimport static android.provider.CalendarContract.EXTRA_EVENT_END_TIME; 21d8353fb85ef59a88580125207be9c914a8586758RoboErikimport static com.android.calendar.CalendarController.EVENT_EDIT_ON_LAUNCH; 22d8353fb85ef59a88580125207be9c914a8586758RoboErik 23cb81189e4868769ea016253eca104e46df2f033aErikimport com.android.calendar.CalendarController.EventInfo; 242bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport com.android.calendar.CalendarController.EventType; 25667af28a8e9729e14831f3db456ff3edb2c4c29aIsaac Katzenelsonimport com.android.calendar.CalendarEventModel.Attendee; 261ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport com.android.calendar.CalendarEventModel.ReminderEntry; 27c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelsonimport com.android.calendar.event.AttendeesView; 28d8353fb85ef59a88580125207be9c914a8586758RoboErikimport com.android.calendar.event.EditEventActivity; 29fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.event.EditEventHelper; 308ed988fbac3e988f0408490a1d61101c4176686dAndy McFaddenimport com.android.calendarcommon.EventRecurrence; 311ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport com.android.calendar.event.EventViewUtils; 3273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport com.android.i18n.phonenumbers.PhoneNumberMatch; 3373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport com.android.i18n.phonenumbers.PhoneNumberUtil; 342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 352bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.app.Activity; 3671d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.app.Dialog; 3771d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.app.DialogFragment; 38ef31a98202852807f460af49ae3313d1ccf5e288Andy McFaddenimport android.app.Service; 392bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ActivityNotFoundException; 40364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erikimport android.content.ContentProviderOperation; 412bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentResolver; 422bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentUris; 432bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentValues; 442bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Context; 452bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Intent; 461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.content.SharedPreferences; 472bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.res.Resources; 482bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.database.Cursor; 492bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.graphics.Rect; 5071b221ae5d0f514352584a955630f5494f686c51Michael Chanimport android.graphics.Typeface; 512bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.net.Uri; 522bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.os.Bundle; 53a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract; 54a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees; 55a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars; 56a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events; 571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.provider.CalendarContract.Reminders; 58cb81189e4868769ea016253eca104e46df2f033aErikimport android.provider.ContactsContract; 592bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.CommonDataKinds; 602bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.Intents; 612bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.QuickContact; 628ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.Spannable; 6373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.SpannableString; 648ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.SpannableStringBuilder; 6573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.Spanned; 662bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.TextUtils; 672bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.DateFormat; 682bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.DateUtils; 692bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.Time; 7073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.method.LinkMovementMethod; 7173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.method.MovementMethod; 728ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.ForegroundColorSpan; 738ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.StrikethroughSpan; 7471b221ae5d0f514352584a955630f5494f686c51Michael Chanimport android.text.style.StyleSpan; 7573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.style.URLSpan; 762bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Linkify; 772bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Rfc822Token; 782bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.util.Log; 7971d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Gravity; 802bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.LayoutInflater; 8160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.Menu; 8260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.MenuInflater; 8360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.MenuItem; 842bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.MotionEvent; 852bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.View; 86cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnClickListener; 87cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnTouchListener; 882bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.ViewGroup; 8971d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Window; 9071d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.WindowManager; 91259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityEvent; 92259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityManager; 932bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.AdapterView; 948ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.widget.Button; 951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.widget.ImageButton; 961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.widget.LinearLayout; 97259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.widget.RadioButton; 98f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup; 991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.widget.ScrollView; 100f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup.OnCheckedChangeListener; 1012bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.TextView; 1022bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.Toast; 1032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1042bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport java.util.ArrayList; 1051ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport java.util.Arrays; 1061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport java.util.Collections; 10774c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelsonimport java.util.Formatter; 108259b8f9a21fffd3858218581e9daaf689b6b888fErikimport java.util.List; 10974c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelsonimport java.util.Locale; 1102bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport java.util.regex.Pattern; 111f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelsonimport java.util.TimeZone; 112f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson 1132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 114f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanpublic class EventInfoFragment extends DialogFragment implements OnCheckedChangeListener, 1151ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson CalendarController.EventHandler, OnClickListener { 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"; 12460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson protected static final String BUNDLE_KEY_ATTENDEE_RESPONSE = "key_attendee_response"; 12571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 126259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final String PERIOD_SPACE = ". "; 127259b8f9a21fffd3858218581e9daaf689b6b888fErik 1282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 1292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * These are the corresponding indices into the array of strings 1302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * "R.array.change_response_labels" in the resource file. 1312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 1322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int UPDATE_SINGLE = 0; 1332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int UPDATE_ALL = 1; 1342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Query tokens for QueryHandler 136259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_EVENT = 1 << 0; 137259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_CALENDARS = 1 << 1; 138259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_ATTENDEES = 1 << 2; 139259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_DUPLICATE_CALENDARS = 1 << 3; 1401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int TOKEN_QUERY_REMINDERS = 1 << 4; 141259b8f9a21fffd3858218581e9daaf689b6b888fErik private static final int TOKEN_QUERY_ALL = TOKEN_QUERY_DUPLICATE_CALENDARS 1421ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson | TOKEN_QUERY_ATTENDEES | TOKEN_QUERY_CALENDARS | TOKEN_QUERY_EVENT 1431ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson | TOKEN_QUERY_REMINDERS; 144259b8f9a21fffd3858218581e9daaf689b6b888fErik private int mCurrentQuery = 0; 1452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String[] EVENT_PROJECTION = new String[] { 1472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events._ID, // 0 do not remove; used in DeleteEventHelper 1482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.TITLE, // 1 do not remove; used in DeleteEventHelper 1492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.RRULE, // 2 do not remove; used in DeleteEventHelper 1502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.ALL_DAY, // 3 do not remove; used in DeleteEventHelper 1512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.CALENDAR_ID, // 4 do not remove; used in DeleteEventHelper 1522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.DTSTART, // 5 do not remove; used in DeleteEventHelper 1532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events._SYNC_ID, // 6 do not remove; used in DeleteEventHelper 1542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.EVENT_TIMEZONE, // 7 do not remove; used in DeleteEventHelper 1552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.DESCRIPTION, // 8 1562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Events.EVENT_LOCATION, // 9 157ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik Calendars.CALENDAR_ACCESS_LEVEL, // 10 1580e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik Calendars.CALENDAR_COLOR, // 11 15971b221ae5d0f514352584a955630f5494f686c51Michael Chan Events.HAS_ATTENDEE_DATA, // 12 16071b221ae5d0f514352584a955630f5494f686c51Michael Chan Events.ORGANIZER, // 13 1611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Events.HAS_ALARM, // 14 1621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Calendars.MAX_REMINDERS, //15 1631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Calendars.ALLOWED_REMINDERS, // 16 16465eeb79e62034d706503ce29d88c0e05ebd726feRoboErik Events.ORIGINAL_SYNC_ID, // 17 do not remove; used in DeleteEventHelper 1652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang }; 1662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_ID = 0; 1672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_TITLE = 1; 1682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_RRULE = 2; 1692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_ALL_DAY = 3; 1702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_CALENDAR_ID = 4; 1712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_SYNC_ID = 6; 1722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_EVENT_TIMEZONE = 7; 1732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_DESCRIPTION = 8; 1742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int EVENT_INDEX_EVENT_LOCATION = 9; 17571b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_ACCESS_LEVEL = 10; 17671b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_COLOR = 11; 17771b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_HAS_ATTENDEE_DATA = 12; 17871b221ae5d0f514352584a955630f5494f686c51Michael Chan private static final int EVENT_INDEX_ORGANIZER = 13; 1791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int EVENT_INDEX_HAS_ALARM = 14; 1801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int EVENT_INDEX_MAX_REMINDERS = 15; 1811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int EVENT_INDEX_ALLOWED_REMINDERS = 16; 1821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 1832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String[] ATTENDEES_PROJECTION = new String[] { 1852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees._ID, // 0 1862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_NAME, // 1 1872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_EMAIL, // 2 1882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_RELATIONSHIP, // 3 1892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Attendees.ATTENDEE_STATUS, // 4 1902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang }; 1912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_ID = 0; 1922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_NAME = 1; 1932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_EMAIL = 2; 1942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_RELATIONSHIP = 3; 1952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final int ATTENDEES_INDEX_STATUS = 4; 1962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=?"; 1982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private static final String ATTENDEES_SORT_ORDER = Attendees.ATTENDEE_NAME + " ASC, " 2002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang + Attendees.ATTENDEE_EMAIL + " ASC"; 2012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2021ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final String[] REMINDERS_PROJECTION = new String[] { 2031ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Reminders._ID, // 0 2041ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Reminders.MINUTES, // 1 2051ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Reminders.METHOD // 2 2061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson }; 2071ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int REMINDERS_INDEX_ID = 0; 2081ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int REMINDERS_MINUTES_ID = 1; 2091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final int REMINDERS_METHOD_ID = 2; 2101ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=?"; 2121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final String[] CALENDARS_PROJECTION = new String[] { 2142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Calendars._ID, // 0 215ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik Calendars.CALENDAR_DISPLAY_NAME, // 1 2162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Calendars.OWNER_ACCOUNT, // 2 217950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden Calendars.CAN_ORGANIZER_RESPOND // 3 2182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang }; 2192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int CALENDARS_INDEX_DISPLAY_NAME = 1; 2202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int CALENDARS_INDEX_OWNER_ACCOUNT = 2; 2212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final int CALENDARS_INDEX_OWNER_CAN_RESPOND = 3; 2222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang static final String CALENDARS_WHERE = Calendars._ID + "=?"; 224ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.CALENDAR_DISPLAY_NAME + "=?"; 2252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private View mView; 2272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Uri mUri; 2292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private long mEventId; 2302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Cursor mEventCursor; 2312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Cursor mAttendeesCursor; 2322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private Cursor mCalendarsCursor; 2331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private Cursor mRemindersCursor; 2341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2350a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan private static float mScale = 0; // Used for supporting different screen densities 2362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private long mStartMillis; 2382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private long mEndMillis; 2392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mHasAttendeeData; 2412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mIsOrganizer; 242d845fbe558d5229102b58cce70a1b29fe6cb6967Erik private long mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE; 243352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private boolean mOwnerCanRespond; 2442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private String mCalendarOwnerAccount; 2452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mCanModifyCalendar; 24665eeb79e62034d706503ce29d88c0e05ebd726feRoboErik private boolean mCanModifyEvent; 2472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mIsBusyFreeCalendar; 2482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private int mNumOfAttendees; 2492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private EditResponseHelper mEditResponseHelper; 2512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private int mOriginalAttendeeResponse; 253deced8999da73effe4133e2317c262fea7910090Michael Chan private int mAttendeeResponseFromIntent = CalendarController.ATTENDEE_NO_RESPONSE; 2542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean mIsRepeating; 2551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private boolean mHasAlarm; 2561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private int mMaxReminders; 2571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private String mCalendarAllowedReminders; 2582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 259259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mTitle; 260259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mWhen; 261259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mWhere; 262259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mWhat; 263259b8f9a21fffd3858218581e9daaf689b6b888fErik private TextView mAttendees; 264c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private AttendeesView mLongAttendees; 265d8353fb85ef59a88580125207be9c914a8586758RoboErik private Menu mMenu = null; 266fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson private View mHeadlines; 2671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ScrollView mScrollView; 268259b8f9a21fffd3858218581e9daaf689b6b888fErik 26973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden private static final Pattern mWildcardPattern = Pattern.compile("^.*$"); 2702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>(); 2722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>(); 2732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>(); 2742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ArrayList<Attendee> mNoResponseAttendees = new ArrayList<Attendee>(); 2752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private int mColor; 2762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 2771ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2781ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private int mDefaultReminderMinutes; 2791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<LinearLayout> mReminderViews = new ArrayList<LinearLayout>(0); 2801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public ArrayList<ReminderEntry> mReminders; 2811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public ArrayList<ReminderEntry> mOriginalReminders; 2821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 2841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Contents of the "minutes" spinner. This has default values from the XML file, augmented 2851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * with any additional values that were already associated with the event. 2861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 2871ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<Integer> mReminderMinuteValues; 2881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<String> mReminderMinuteLabels; 2891ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2901ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 2911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Contents of the "methods" spinner. The "values" list specifies the method constant 2921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * (e.g. {@link Reminders#METHOD_ALERT}) associated with the labels. Any methods that 2931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * aren't allowed by the Calendar will be removed. 2941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 2951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<Integer> mReminderMethodValues; 2961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private ArrayList<String> mReminderMethodLabels; 2971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 2991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 3002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private QueryHandler mHandler; 3012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 302cb81189e4868769ea016253eca104e46df2f033aErik private Runnable mTZUpdater = new Runnable() { 303cb81189e4868769ea016253eca104e46df2f033aErik @Override 304cb81189e4868769ea016253eca104e46df2f033aErik public void run() { 305cb81189e4868769ea016253eca104e46df2f033aErik updateEvent(mView); 306cb81189e4868769ea016253eca104e46df2f033aErik } 307cb81189e4868769ea016253eca104e46df2f033aErik }; 308cb81189e4868769ea016253eca104e46df2f033aErik 3092fc6b79dfb06812baf2e6c547f3ffee83b5c3e9aMichael Chan private static int DIALOG_WIDTH = 500; 3102fc6b79dfb06812baf2e6c547f3ffee83b5c3e9aMichael Chan private static int DIALOG_HEIGHT = 600; 31171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private boolean mIsDialog = false; 3127c6236d5553dc9f3d004ebbed794249713a11d19RoboErik private boolean mIsPaused = true; 3137c6236d5553dc9f3d004ebbed794249713a11d19RoboErik private boolean mDismissOnResume = false; 31471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private int mX = -1; 31571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private int mY = -1; 316c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private Button mDescButton; // Button to expand/collapse the description 317c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private String mMoreLabel; // Labels for the button 318c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private String mLessLabel; 319c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private boolean mShowMaxDescription; // Current status of button 320c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private int mDescLineNum; // The default number of lines in the description 32110b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson private boolean mIsTabletConfig; 32210b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson private Activity mActivity; 323be2a432034e96c9f2fbf333cd7fe6489312bbeaaMichael Chan private Context mContext; 32471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 3252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private class QueryHandler extends AsyncQueryService { 3262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public QueryHandler(Context context) { 3272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang super(context); 3282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 3292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 3302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 3312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 3324003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang // if the activity is finishing, then close the cursor and return 3334003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang final Activity activity = getActivity(); 3344003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (activity == null || activity.isFinishing()) { 3354003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang cursor.close(); 3364003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang return; 3374003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 3384003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 3392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang switch (token) { 3402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_EVENT: 3412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventCursor = Utils.matrixCursorFromCursor(cursor); 3422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (initEventCursor()) { 3432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // The cursor is empty. This can happen if the event was 3442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // deleted. 3452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // FRAG_TODO we should no longer rely on Activity.finish() 3461df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang activity.finish(); 3472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 3482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 3492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateEvent(mView); 3502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 3512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // start calendar query 3522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Uri uri = Calendars.CONTENT_URI; 3532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String[] args = new String[] { 3542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Long.toString(mEventCursor.getLong(EVENT_INDEX_CALENDAR_ID))}; 3552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang startQuery(TOKEN_QUERY_CALENDARS, null, uri, CALENDARS_PROJECTION, 3562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang CALENDARS_WHERE, args, null); 3572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 3582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_CALENDARS: 3592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarsCursor = Utils.matrixCursorFromCursor(cursor); 3602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateCalendar(mView); 3614003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang // FRAG_TODO fragments shouldn't set the title anymore 3622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateTitle(); 3632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 364352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (!mIsBusyFreeCalendar) { 365352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan args = new String[] { Long.toString(mEventId) }; 366352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 367352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // start attendees query 368352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan uri = Attendees.CONTENT_URI; 369352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan startQuery(TOKEN_QUERY_ATTENDEES, null, uri, ATTENDEES_PROJECTION, 370352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan ATTENDEES_WHERE, args, ATTENDEES_SORT_ORDER); 371259b8f9a21fffd3858218581e9daaf689b6b888fErik } else { 372259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEventIfQueryDone(TOKEN_QUERY_ATTENDEES); 3732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 3741ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mOriginalReminders = new ArrayList<ReminderEntry> (); 3751ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mHasAlarm) { 3761ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // start reminders query 3771ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson args = new String[] { Long.toString(mEventId) }; 3781ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson uri = Reminders.CONTENT_URI; 3791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson startQuery(TOKEN_QUERY_REMINDERS, null, uri, 3801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson REMINDERS_PROJECTION, REMINDERS_WHERE, args, null); 3811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } else { 3821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson sendAccessibilityEventIfQueryDone(TOKEN_QUERY_REMINDERS); 3831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 3842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 3852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_ATTENDEES: 3862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeesCursor = Utils.matrixCursorFromCursor(cursor); 3872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang initAttendeesCursor(mView); 3882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateResponse(mView); 3892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 3901ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson case TOKEN_QUERY_REMINDERS: 3911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mRemindersCursor = Utils.matrixCursorFromCursor(cursor); 3921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson initReminders(mView, mRemindersCursor); 3931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson break; 3942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case TOKEN_QUERY_DUPLICATE_CALENDARS: 39571b221ae5d0f514352584a955630f5494f686c51Michael Chan Resources res = activity.getResources(); 39671b221ae5d0f514352584a955630f5494f686c51Michael Chan SpannableStringBuilder sb = new SpannableStringBuilder(); 39771b221ae5d0f514352584a955630f5494f686c51Michael Chan 39871b221ae5d0f514352584a955630f5494f686c51Michael Chan // Label 39971b221ae5d0f514352584a955630f5494f686c51Michael Chan String label = res.getString(R.string.view_event_calendar_label); 40071b221ae5d0f514352584a955630f5494f686c51Michael Chan sb.append(label).append(" "); 40171b221ae5d0f514352584a955630f5494f686c51Michael Chan sb.setSpan(new StyleSpan(Typeface.BOLD), 0, label.length(), 40271b221ae5d0f514352584a955630f5494f686c51Michael Chan Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 40371b221ae5d0f514352584a955630f5494f686c51Michael Chan 40471b221ae5d0f514352584a955630f5494f686c51Michael Chan // Calendar display name 4052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String calendarName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME); 40671b221ae5d0f514352584a955630f5494f686c51Michael Chan sb.append(calendarName); 40771b221ae5d0f514352584a955630f5494f686c51Michael Chan 40871b221ae5d0f514352584a955630f5494f686c51Michael Chan // Show email account if display name is not unique and 40971b221ae5d0f514352584a955630f5494f686c51Michael Chan // display name != email 41071b221ae5d0f514352584a955630f5494f686c51Michael Chan String email = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT); 41171b221ae5d0f514352584a955630f5494f686c51Michael Chan if (cursor.getCount() > 1 && !calendarName.equalsIgnoreCase(email)) { 41271b221ae5d0f514352584a955630f5494f686c51Michael Chan sb.append(" (").append(email).append(")"); 41371b221ae5d0f514352584a955630f5494f686c51Michael Chan } 41471b221ae5d0f514352584a955630f5494f686c51Michael Chan 4152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 4162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang cursor.close(); 418259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEventIfQueryDone(token); 4192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 4212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 423259b8f9a21fffd3858218581e9daaf689b6b888fErik private void sendAccessibilityEventIfQueryDone(int token) { 424259b8f9a21fffd3858218581e9daaf689b6b888fErik mCurrentQuery |= token; 425259b8f9a21fffd3858218581e9daaf689b6b888fErik if (mCurrentQuery == TOKEN_QUERY_ALL) { 426259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEvent(); 427259b8f9a21fffd3858218581e9daaf689b6b888fErik } 428259b8f9a21fffd3858218581e9daaf689b6b888fErik } 429259b8f9a21fffd3858218581e9daaf689b6b888fErik 4300a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan public EventInfoFragment(Context context, Uri uri, long startMillis, long endMillis, 43160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson int attendeeResponse, boolean isDialog) { 432be2a432034e96c9f2fbf333cd7fe6489312bbeaaMichael Chan mContext = context; 4330b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson 4340a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan if (mScale == 0) { 4350a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan mScale = context.getResources().getDisplayMetrics().density; 4360a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan if (mScale != 1) { 4370a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan DIALOG_WIDTH *= mScale; 4380a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan DIALOG_HEIGHT *= mScale; 4390a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan } 4400a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan } 44160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mIsDialog = isDialog; 442c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson 4432fc6b79dfb06812baf2e6c547f3ffee83b5c3e9aMichael Chan setStyle(DialogFragment.STYLE_NO_TITLE, 0); 4442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mUri = uri; 4452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mStartMillis = startMillis; 4462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEndMillis = endMillis; 4472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeeResponseFromIntent = attendeeResponse; 4482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 4492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 450ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden // This is currently required by the fragment manager. 45160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson public EventInfoFragment() { 45260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 45360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 45460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 45560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 4560a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan public EventInfoFragment(Context context, long eventId, long startMillis, long endMillis, 45760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson int attendeeResponse, boolean isDialog) { 4580a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan this(context, ContentUris.withAppendedId(Events.CONTENT_URI, eventId), startMillis, 45960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson endMillis, attendeeResponse, isDialog); 4604003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mEventId = eventId; 4614003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 4624003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 46371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan @Override 46471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan public void onActivityCreated(Bundle savedInstanceState) { 46571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan super.onActivityCreated(savedInstanceState); 46671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 46771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan if (savedInstanceState != null) { 46871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false); 46971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 47071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 47171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan if (mIsDialog) { 47271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan applyDialogParams(); 47371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 47471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 47571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 47671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan private void applyDialogParams() { 47771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan Dialog dialog = getDialog(); 47871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan dialog.setCanceledOnTouchOutside(true); 47971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 48071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan Window window = dialog.getWindow(); 48171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); 48271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 48371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan WindowManager.LayoutParams a = window.getAttributes(); 48471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan a.dimAmount = .4f; 48571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 48671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan a.width = DIALOG_WIDTH; 487352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan a.height = DIALOG_HEIGHT; 48871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 4890b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson 4900b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson // On tablets , do smart positioning of dialog 4910b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson // On phones , use the whole screen 4920b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson 49360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (mX != -1 || mY != -1) { 49460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson a.x = mX - a.width - 64; 49560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (a.x < 0) { 49660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson a.x = mX + 64; 4970a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan } 49860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson a.y = mY - 64; 49960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson a.gravity = Gravity.LEFT | Gravity.TOP; 50071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 50171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan window.setAttributes(a); 50271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 50371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 50460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson public void setDialogParams(int x, int y) { 50571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan mX = x; 50671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan mY = y; 50771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan } 50871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan 509f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan // Implements OnCheckedChangeListener 510f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan @Override 511f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan public void onCheckedChanged(RadioGroup group, int checkedId) { 5122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If this is not a repeating event, then don't display the dialog 5132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // asking which events to change. 5142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!mIsRepeating) { 5152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 5162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 5182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If the selection is the same as the original, then don't display the 5192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // dialog asking which events to change. 520f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan if (checkedId == findButtonIdForResponse(mOriginalAttendeeResponse)) { 5212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 5222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 5242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // This is a repeating event. We need to ask the user if they mean to 5252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // change just this one instance or all instances. 5262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEditResponseHelper.showDialog(mEditResponseHelper.getWhichEvents()); 5272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 5292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void onNothingSelected(AdapterView<?> parent) { 5302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 5322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 5332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void onAttach(Activity activity) { 5342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang super.onAttach(activity); 53510b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson mActivity = activity; 5362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEditResponseHelper = new EditResponseHelper(activity); 53786550ce5323f7e3971977702fca259986c048bf6RoboErik 53886550ce5323f7e3971977702fca259986c048bf6RoboErik if (mAttendeeResponseFromIntent != Attendees.ATTENDEE_STATUS_NONE) { 53986550ce5323f7e3971977702fca259986c048bf6RoboErik mEditResponseHelper.setWhichEvents(UPDATE_ALL); 54086550ce5323f7e3971977702fca259986c048bf6RoboErik } 5412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler = new QueryHandler(activity); 54260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mDescLineNum = activity.getResources().getInteger((R.integer.event_info_desc_line_num)); 54360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mMoreLabel = activity.getResources().getString((R.string.event_info_desc_more)); 54460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mLessLabel = activity.getResources().getString((R.string.event_info_desc_less)); 54560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (!mIsDialog) { 54660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson setHasOptionsMenu(true); 54760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 5482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 5492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 5502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 5512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public View onCreateView(LayoutInflater inflater, ViewGroup container, 5522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Bundle savedInstanceState) { 5538b71d11235e7ebc02f62435d2c6583edb43c26a2Michael Chan mView = inflater.inflate(R.layout.event_info, container, false); 5541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mScrollView = (ScrollView) mView.findViewById(R.id.event_info_scroll_view); 555259b8f9a21fffd3858218581e9daaf689b6b888fErik mTitle = (TextView) mView.findViewById(R.id.title); 556259b8f9a21fffd3858218581e9daaf689b6b888fErik mWhen = (TextView) mView.findViewById(R.id.when); 557259b8f9a21fffd3858218581e9daaf689b6b888fErik mWhere = (TextView) mView.findViewById(R.id.where); 558259b8f9a21fffd3858218581e9daaf689b6b888fErik mWhat = (TextView) mView.findViewById(R.id.description); 559259b8f9a21fffd3858218581e9daaf689b6b888fErik mAttendees = (TextView) mView.findViewById(R.id.attendee_list); 560fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mHeadlines = mView.findViewById(R.id.event_info_headline); 561c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mLongAttendees = (AttendeesView)mView.findViewById(R.id.long_attendee_list); 562c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mDescButton = (Button)mView.findViewById(R.id.desc_expand); 563c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mDescButton.setOnClickListener(new View.OnClickListener() { 564ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden @Override 565c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson public void onClick(View v) { 566c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mShowMaxDescription = !mShowMaxDescription; 567c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson updateDescription(); 568c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson } 569c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson }); 570c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mShowMaxDescription = false; // Show short version of description as default. 57110b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson mIsTabletConfig = Utils.getConfigBool(mActivity, R.bool.tablet_config); 5722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 5734003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (mUri == null) { 5744003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang // restore event ID from bundle 5754003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mEventId = savedInstanceState.getLong(BUNDLE_KEY_EVENT_ID); 5764003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mUri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 5774003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mStartMillis = savedInstanceState.getLong(BUNDLE_KEY_START_MILLIS); 5784003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mEndMillis = savedInstanceState.getLong(BUNDLE_KEY_END_MILLIS); 5794003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 5804003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 5812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // start loading the data 5822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION, 5832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang null, null, null); 5842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 58589ad0822f104015625f4ca88bfdf5c1d522b6e74Erik Button b = (Button) mView.findViewById(R.id.delete); 5868ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan b.setOnClickListener(new OnClickListener() { 5878ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan @Override 5888ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan public void onClick(View v) { 58969be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik if (!mCanModifyCalendar) { 59069be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik return; 59169be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik } 59289ad0822f104015625f4ca88bfdf5c1d522b6e74Erik DeleteEventHelper deleteHelper = new DeleteEventHelper( 593be2a432034e96c9f2fbf333cd7fe6489312bbeaaMichael Chan mContext, mActivity, 5941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson !mIsDialog && !mIsTabletConfig /* exitWhenDone */); 59589ad0822f104015625f4ca88bfdf5c1d522b6e74Erik deleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable); 5968ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan }}); 5978ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 59810b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // Hide Edit/Delete buttons if in full screen mode on a phone 599fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (savedInstanceState != null) { 600fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false); 601fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 60210b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson if (!mIsDialog && !mIsTabletConfig) { 60360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson mView.findViewById(R.id.event_info_buttons_container).setVisibility(View.GONE); 60460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 60560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 6061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Create a listener for the add reminder button 6071ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 6081ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ImageButton reminderAddButton = (ImageButton) mView.findViewById(R.id.reminder_add); 6091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson View.OnClickListener addReminderOnClickListener = new View.OnClickListener() { 6101ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson @Override 6111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public void onClick(View v) { 6121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson addReminder(); 6131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 6141ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson }; 6151ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson reminderAddButton.setOnClickListener(addReminderOnClickListener); 6161ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 6171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Set reminders variables 6181ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 6191ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity); 6201ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson String defaultReminderString = prefs.getString( 6211ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING); 6221ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mDefaultReminderMinutes = Integer.parseInt(defaultReminderString); 6231ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson prepareReminders(); 6241ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 6252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return mView; 6262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 62889ad0822f104015625f4ca88bfdf5c1d522b6e74Erik private Runnable onDeleteRunnable = new Runnable() { 62989ad0822f104015625f4ca88bfdf5c1d522b6e74Erik @Override 63089ad0822f104015625f4ca88bfdf5c1d522b6e74Erik public void run() { 6317c6236d5553dc9f3d004ebbed794249713a11d19RoboErik if (EventInfoFragment.this.mIsPaused) { 6327c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mDismissOnResume = true; 6337c6236d5553dc9f3d004ebbed794249713a11d19RoboErik return; 6347c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 63589ad0822f104015625f4ca88bfdf5c1d522b6e74Erik if (EventInfoFragment.this.isVisible()) { 63689ad0822f104015625f4ca88bfdf5c1d522b6e74Erik EventInfoFragment.this.dismiss(); 63789ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 63889ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 63989ad0822f104015625f4ca88bfdf5c1d522b6e74Erik }; 64089ad0822f104015625f4ca88bfdf5c1d522b6e74Erik 641c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson // Sets the description: 642c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson // Set the expand/collapse button 643c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson // Expand/collapse the description according the the current status 644c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson private void updateDescription() { 645c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson // Description is short, hide button 646c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson if (mWhat.getLineCount() <= mDescLineNum) { 647c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mDescButton.setVisibility(View.GONE); 648c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson return; 649c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson } 650c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson // Show button and set label according to the expand/collapse status 651c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mDescButton.setVisibility(View.VISIBLE); 652c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson if (mShowMaxDescription) { 653c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mDescButton.setText(mLessLabel); 654c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mWhat.setLines(mWhat.getLineCount()); 655c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson } else { 656c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mDescButton.setText(mMoreLabel); 657c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson mWhat.setLines(mDescLineNum); 658c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson } 659c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson } 660c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson 6612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateTitle() { 6622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Resources res = getActivity().getResources(); 6632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mCanModifyCalendar && !mIsOrganizer) { 6642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang getActivity().setTitle(res.getString(R.string.event_info_title_invite)); 6652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 6662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang getActivity().setTitle(res.getString(R.string.event_info_title)); 6672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 6712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Initializes the event cursor, which is expected to point to the first 6722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * (and only) result from a query. 6732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * @return true if the cursor is empty. 6742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 6752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean initEventCursor() { 6762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if ((mEventCursor == null) || (mEventCursor.getCount() == 0)) { 6772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 6782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventCursor.moveToFirst(); 6802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventId = mEventCursor.getInt(EVENT_INDEX_ID); 6812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String rRule = mEventCursor.getString(EVENT_INDEX_RRULE); 68266b2067e0a389180f909eb0a528bea5f6becca23Michael Chan mIsRepeating = !TextUtils.isEmpty(rRule); 6831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mHasAlarm = (mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) == 1)?true:false; 6841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mMaxReminders = mEventCursor.getInt(EVENT_INDEX_MAX_REMINDERS); 6851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mCalendarAllowedReminders = mEventCursor.getString(EVENT_INDEX_ALLOWED_REMINDERS); 6862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 6872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 6882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 6892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @SuppressWarnings("fallthrough") 6902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void initAttendeesCursor(View view) { 691deced8999da73effe4133e2317c262fea7910090Michael Chan mOriginalAttendeeResponse = CalendarController.ATTENDEE_NO_RESPONSE; 692d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE; 6932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mNumOfAttendees = 0; 6942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor != null) { 6952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mNumOfAttendees = mAttendeesCursor.getCount(); 6962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor.moveToFirst()) { 6972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAcceptedAttendees.clear(); 6982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mDeclinedAttendees.clear(); 6992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mTentativeAttendees.clear(); 7002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mNoResponseAttendees.clear(); 7012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 7022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang do { 7032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang int status = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS); 7042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String name = mAttendeesCursor.getString(ATTENDEES_INDEX_NAME); 7052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String email = mAttendeesCursor.getString(ATTENDEES_INDEX_EMAIL); 7062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 707d845fbe558d5229102b58cce70a1b29fe6cb6967Erik if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE && 7082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAccount.equalsIgnoreCase(email)) { 7092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAttendeeId = mAttendeesCursor.getInt(ATTENDEES_INDEX_ID); 7102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mOriginalAttendeeResponse = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS); 7112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 7122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Don't show your own status in the list because: 7132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // 1) it doesn't make sense for event without other guests. 7142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // 2) there's a spinner for that for events with guests. 7152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang switch(status) { 7162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case Attendees.ATTENDEE_STATUS_ACCEPTED: 717fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mAcceptedAttendees.add(new Attendee(name, email, 718fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson Attendees.ATTENDEE_STATUS_ACCEPTED)); 7192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 7202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case Attendees.ATTENDEE_STATUS_DECLINED: 721fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mDeclinedAttendees.add(new Attendee(name, email, 722fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson Attendees.ATTENDEE_STATUS_DECLINED)); 7232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 7248ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan case Attendees.ATTENDEE_STATUS_TENTATIVE: 725fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mTentativeAttendees.add(new Attendee(name, email, 726fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson Attendees.ATTENDEE_STATUS_TENTATIVE)); 7278ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan break; 7288ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan default: 729fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson mNoResponseAttendees.add(new Attendee(name, email, 730fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson Attendees.ATTENDEE_STATUS_NONE)); 7312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 7322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 7332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } while (mAttendeesCursor.moveToNext()); 7342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeesCursor.moveToFirst(); 7352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 7362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateAttendees(view); 7372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 7382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 7392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 7402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 7412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 7424003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang public void onSaveInstanceState(Bundle outState) { 7434003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang super.onSaveInstanceState(outState); 7444003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang outState.putLong(BUNDLE_KEY_EVENT_ID, mEventId); 7454003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang outState.putLong(BUNDLE_KEY_START_MILLIS, mStartMillis); 7464003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang outState.putLong(BUNDLE_KEY_END_MILLIS, mEndMillis); 74771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan outState.putBoolean(BUNDLE_KEY_IS_DIALOG, mIsDialog); 74860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson outState.putInt(BUNDLE_KEY_ATTENDEE_RESPONSE, mAttendeeResponseFromIntent); 74960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 75060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 75160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson 75260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson @Override 75360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 75460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson super.onCreateOptionsMenu(menu, inflater); 75510b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // Show edit/delete buttons only in non-dialog configuration on a phone 75610b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson if (!mIsDialog && !mIsTabletConfig) { 75760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson inflater.inflate(R.menu.event_info_title_bar, menu); 758d8353fb85ef59a88580125207be9c914a8586758RoboErik mMenu = menu; 759d8353fb85ef59a88580125207be9c914a8586758RoboErik updateMenu(); 76060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 7614003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 7624003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 763d8353fb85ef59a88580125207be9c914a8586758RoboErik @Override 764d8353fb85ef59a88580125207be9c914a8586758RoboErik public boolean onOptionsItemSelected(MenuItem item) { 765d8353fb85ef59a88580125207be9c914a8586758RoboErik 766d8353fb85ef59a88580125207be9c914a8586758RoboErik // If we're a dialog or part of a tablet display we don't want to handle 767d8353fb85ef59a88580125207be9c914a8586758RoboErik // menu buttons 768d8353fb85ef59a88580125207be9c914a8586758RoboErik if (mIsDialog || mIsTabletConfig) { 769d8353fb85ef59a88580125207be9c914a8586758RoboErik return false; 770d8353fb85ef59a88580125207be9c914a8586758RoboErik } 771d8353fb85ef59a88580125207be9c914a8586758RoboErik // Handles option menu selections: 772d8353fb85ef59a88580125207be9c914a8586758RoboErik // Home button - close event info activity and start the main calendar 773d8353fb85ef59a88580125207be9c914a8586758RoboErik // one 774d8353fb85ef59a88580125207be9c914a8586758RoboErik // Edit button - start the event edit activity and close the info 775d8353fb85ef59a88580125207be9c914a8586758RoboErik // activity 776d8353fb85ef59a88580125207be9c914a8586758RoboErik // Delete button - start a delete query that calls a runnable that close 777d8353fb85ef59a88580125207be9c914a8586758RoboErik // the info activity 778d8353fb85ef59a88580125207be9c914a8586758RoboErik 779d8353fb85ef59a88580125207be9c914a8586758RoboErik switch (item.getItemId()) { 780d8353fb85ef59a88580125207be9c914a8586758RoboErik case android.R.id.home: 781d8353fb85ef59a88580125207be9c914a8586758RoboErik Intent launchIntent = new Intent(); 782d8353fb85ef59a88580125207be9c914a8586758RoboErik launchIntent.setAction(Intent.ACTION_VIEW); 783d8353fb85ef59a88580125207be9c914a8586758RoboErik launchIntent.setData(Uri.parse(CalendarContract.CONTENT_URI + "/time")); 784d8353fb85ef59a88580125207be9c914a8586758RoboErik launchIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 785d8353fb85ef59a88580125207be9c914a8586758RoboErik | Intent.FLAG_ACTIVITY_CLEAR_TOP); 786d8353fb85ef59a88580125207be9c914a8586758RoboErik launchIntent.setClass(mActivity, AllInOneActivity.class); 787d8353fb85ef59a88580125207be9c914a8586758RoboErik startActivity(launchIntent); 788d8353fb85ef59a88580125207be9c914a8586758RoboErik mActivity.finish(); 789d8353fb85ef59a88580125207be9c914a8586758RoboErik return true; 790d8353fb85ef59a88580125207be9c914a8586758RoboErik case R.id.info_action_edit: 791d8353fb85ef59a88580125207be9c914a8586758RoboErik Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 792d8353fb85ef59a88580125207be9c914a8586758RoboErik Intent intent = new Intent(Intent.ACTION_EDIT, uri); 793d8353fb85ef59a88580125207be9c914a8586758RoboErik intent.putExtra(EXTRA_EVENT_BEGIN_TIME, mStartMillis); 794d8353fb85ef59a88580125207be9c914a8586758RoboErik intent.putExtra(EXTRA_EVENT_END_TIME, mEndMillis); 795d8353fb85ef59a88580125207be9c914a8586758RoboErik intent.setClass(mActivity, EditEventActivity.class); 796d8353fb85ef59a88580125207be9c914a8586758RoboErik intent.putExtra(EVENT_EDIT_ON_LAUNCH, true); 797d8353fb85ef59a88580125207be9c914a8586758RoboErik startActivity(intent); 798d8353fb85ef59a88580125207be9c914a8586758RoboErik mActivity.finish(); 799d8353fb85ef59a88580125207be9c914a8586758RoboErik break; 800d8353fb85ef59a88580125207be9c914a8586758RoboErik case R.id.info_action_delete: 801d8353fb85ef59a88580125207be9c914a8586758RoboErik DeleteEventHelper deleteHelper = 802d8353fb85ef59a88580125207be9c914a8586758RoboErik new DeleteEventHelper(mActivity, mActivity, true /* exitWhenDone */); 803d8353fb85ef59a88580125207be9c914a8586758RoboErik deleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable); 804d8353fb85ef59a88580125207be9c914a8586758RoboErik break; 805d8353fb85ef59a88580125207be9c914a8586758RoboErik default: 806d8353fb85ef59a88580125207be9c914a8586758RoboErik break; 807d8353fb85ef59a88580125207be9c914a8586758RoboErik } 808d8353fb85ef59a88580125207be9c914a8586758RoboErik return super.onOptionsItemSelected(item); 809d8353fb85ef59a88580125207be9c914a8586758RoboErik } 8104003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 8114003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang @Override 8124003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang public void onDestroyView() { 8131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (saveResponse() || saveReminders()) { 8142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Toast.makeText(getActivity(), R.string.saving_event, Toast.LENGTH_SHORT).show(); 8152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8164003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang super.onDestroyView(); 8172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang @Override 8202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void onDestroy() { 8212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mEventCursor != null) { 8222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mEventCursor.close(); 8232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mCalendarsCursor != null) { 8252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarsCursor.close(); 8262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor != null) { 8282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mAttendeesCursor.close(); 8292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 83071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan super.onDestroy(); 8312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 8342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Asynchronously saves the response to an invitation if the user changed 8352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * the response. Returns true if the database will be updated. 8362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 8372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * @return true if the database will be changed 8382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 8392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private boolean saveResponse() { 8402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mAttendeesCursor == null || mEventCursor == null) { 8412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 843f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 844f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan RadioGroup radioGroup = (RadioGroup) getView().findViewById(R.id.response_value); 845f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int status = getResponseFromButtonId(radioGroup.getCheckedRadioButtonId()); 846f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan if (status == Attendees.ATTENDEE_STATUS_NONE) { 8472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If the status has not changed, then don't update the database 8512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (status == mOriginalAttendeeResponse) { 8522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // If we never got an owner attendee id we can't set the status 856d845fbe558d5229102b58cce70a1b29fe6cb6967Erik if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE) { 8572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!mIsRepeating) { 8612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // This is a non-repeating event 8622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateResponse(mEventId, mCalendarOwnerAttendeeId, status); 8632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 8642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // This is a repeating event 8672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang int whichEvents = mEditResponseHelper.getWhichEvents(); 8682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang switch (whichEvents) { 8692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case -1: 8702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case UPDATE_SINGLE: 872c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden createExceptionResponse(mEventId, status); 8732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 8742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang case UPDATE_ALL: 8752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang updateResponse(mEventId, mCalendarOwnerAttendeeId, status); 8762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return true; 8772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang default: 8782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Log.e(TAG, "Unexpected choice for updating invitation response"); 8792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang break; 8802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return false; 8822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateResponse(long eventId, long attendeeId, int status) { 8852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Update the attendee status in the attendees table. the provider 8862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // takes care of updating the self attendance status. 8872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ContentValues values = new ContentValues(); 8882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!TextUtils.isEmpty(mCalendarOwnerAccount)) { 8902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Attendees.ATTENDEE_EMAIL, mCalendarOwnerAccount); 8912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 8922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Attendees.ATTENDEE_STATUS, status); 8932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Attendees.EVENT_ID, eventId); 8942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Uri uri = ContentUris.withAppendedId(Attendees.CONTENT_URI, attendeeId); 8962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 8972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler.startUpdate(mHandler.getNextToken(), null, uri, values, 8982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang null, null, Utils.UNDO_DELAY); 8992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 901c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden /** 902c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * Creates an exception to a recurring event. The only change we're making is to the 903c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * "self attendee status" value. The provider will take care of updating the corresponding 904c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * Attendees.attendeeStatus entry. 905c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * 906c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * @param eventId The recurring event. 907c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden * @param status The new value for selfAttendeeStatus. 908c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden */ 909c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden private void createExceptionResponse(long eventId, int status) { 9102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang ContentValues values = new ContentValues(); 9112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis); 9122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang values.put(Events.SELF_ATTENDEE_STATUS, status); 913c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden values.put(Events.STATUS, Events.STATUS_CONFIRMED); 9142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 915364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erik ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 91679b2c8c946c29ea9107957fe72a9fa9f560da345Andy McFadden Uri exceptionUri = Uri.withAppendedPath(Events.CONTENT_EXCEPTION_URI, 917c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden String.valueOf(eventId)); 918c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden ops.add(ContentProviderOperation.newInsert(exceptionUri).withValues(values).build()); 919364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erik 920c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden mHandler.startBatch(mHandler.getNextToken(), null, CalendarContract.AUTHORITY, ops, 921c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden Utils.UNDO_DELAY); 922c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden } 9232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 924f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan public static int getResponseFromButtonId(int buttonId) { 925f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int response; 926f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan switch (buttonId) { 927f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case R.id.response_yes: 928f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = Attendees.ATTENDEE_STATUS_ACCEPTED; 929f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 930f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case R.id.response_maybe: 931f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = Attendees.ATTENDEE_STATUS_TENTATIVE; 932f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 933f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case R.id.response_no: 934f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = Attendees.ATTENDEE_STATUS_DECLINED; 935f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 936f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan default: 937f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = Attendees.ATTENDEE_STATUS_NONE; 9382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 939f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan return response; 940f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan } 941f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 942f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan public static int findButtonIdForResponse(int response) { 943f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int buttonId; 944f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan switch (response) { 945f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case Attendees.ATTENDEE_STATUS_ACCEPTED: 946f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = R.id.response_yes; 947f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 948f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case Attendees.ATTENDEE_STATUS_TENTATIVE: 949f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = R.id.response_maybe; 950f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 951f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan case Attendees.ATTENDEE_STATUS_DECLINED: 952f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = R.id.response_no; 953f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan break; 954f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan default: 955f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan buttonId = -1; 956f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan } 957f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan return buttonId; 9582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void doEdit() { 961c41b99be504e395b8c7264a0d626906ccbff1c57Erik Context c = getActivity(); 962c41b99be504e395b8c7264a0d626906ccbff1c57Erik // This ensures that we aren't in the process of closing and have been 963c41b99be504e395b8c7264a0d626906ccbff1c57Erik // unattached already 964c41b99be504e395b8c7264a0d626906ccbff1c57Erik if (c != null) { 965c41b99be504e395b8c7264a0d626906ccbff1c57Erik CalendarController.getInstance(c).sendEventRelatedEvent( 96661bf59383cc3d38ef0447635ed65ab986796d7deMichael Chan this, EventType.EDIT_EVENT, mEventId, mStartMillis, mEndMillis, 0 96760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson , 0, -1); 968c41b99be504e395b8c7264a0d626906ccbff1c57Erik } 9692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateEvent(View view) { 972b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson if (mEventCursor == null || view == null) { 9732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 9742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String eventName = mEventCursor.getString(EVENT_INDEX_TITLE); 9772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (eventName == null || eventName.length() == 0) { 9782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang eventName = getActivity().getString(R.string.no_title_label); 9792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0; 9822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION); 9832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION); 9842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String rRule = mEventCursor.getString(EVENT_INDEX_RRULE); 985f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE); 986f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson String organizer = mEventCursor.getString(EVENT_INDEX_ORGANIZER); 9872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9884acb2fd087308dea146b8b10f5278c59df387680RoboErik mColor = Utils.getDisplayColorFromColor(mEventCursor.getInt(EVENT_INDEX_COLOR)); 989fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mHeadlines.setBackgroundColor(mColor); 9902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // What 9922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (eventName != null) { 9932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setTextCommon(view, R.id.title, eventName); 9942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 9952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 9962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // When 997fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson // Set the date and repeats (if any) 99874c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson String whenDate; 99974c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson int flagsTime = DateUtils.FORMAT_SHOW_TIME; 100074c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson int flagsDate = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY | 100174c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson DateUtils.FORMAT_SHOW_YEAR; 100274c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson 100374c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson if (DateFormat.is24HourFormat(getActivity())) { 100474c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson flagsTime |= DateUtils.FORMAT_24HOUR; 100574c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson } 1006fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson 1007fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson // Put repeat after the date (if any) 1008fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson String repeatString = null; 1009fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (!TextUtils.isEmpty(rRule)) { 1010fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson EventRecurrence eventRecurrence = new EventRecurrence(); 1011fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson eventRecurrence.parse(rRule); 1012fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson Time date = new Time(Utils.getTimeZone(getActivity(), mTZUpdater)); 1013fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (allDay) { 1014fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson date.timezone = Time.TIMEZONE_UTC; 1015fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 1016fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson date.set(mStartMillis); 1017fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson eventRecurrence.setStartDate(date); 1018fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson repeatString = EventRecurrenceFormatter.getRepeatString( 1019fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson getActivity().getResources(), eventRecurrence); 1020fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 1021fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson // If an all day event , show the date without the time 10222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (allDay) { 102374c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson Formatter f = new Formatter(new StringBuilder(50), Locale.getDefault()); 102474c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson whenDate = DateUtils.formatDateRange(getActivity(), f, mStartMillis, mStartMillis, 102574c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson flagsDate, Time.TIMEZONE_UTC).toString(); 1026fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (repeatString != null) { 1027fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson setTextCommon(view, R.id.when_date, whenDate + " (" + repeatString + ")"); 1028fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } else { 1029fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson setTextCommon(view, R.id.when_date, whenDate); 1030fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 103174c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson view.findViewById(R.id.when_time).setVisibility(View.GONE); 103274c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson 10332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 1034fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson // Show date for none all-day events 103574c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson whenDate = Utils.formatDateRange(getActivity(), mStartMillis, mEndMillis, flagsDate); 103674c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson String whenTime = Utils.formatDateRange(getActivity(), mStartMillis, mEndMillis, 103774c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson flagsTime); 1038fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (repeatString != null) { 1039fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson setTextCommon(view, R.id.when_date, whenDate + " (" + repeatString + ")"); 1040f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson } else { 1041fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson setTextCommon(view, R.id.when_date, whenDate); 1042f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson } 1043f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson 1044fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson // Show the event timezone if it is different from the local timezone after the time 10451121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik String localTimezone = Utils.getTimeZone(mActivity, mTZUpdater); 10461121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik if (!TextUtils.equals(localTimezone, eventTimezone)) { 1047fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson String displayName; 10481121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik // Figure out if this is in DST 10491121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik Time date = new Time(Utils.getTimeZone(getActivity(), mTZUpdater)); 10501121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik if (allDay) { 10511121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik date.timezone = Time.TIMEZONE_UTC; 10521121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik } 10531121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik date.set(mStartMillis); 10541121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik 10551121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik TimeZone tz = TimeZone.getTimeZone(localTimezone); 1056fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (tz == null || tz.getID().equals("GMT")) { 1057fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson displayName = localTimezone; 1058fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } else { 10591121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik displayName = tz.getDisplayName(date.isDst != 0, TimeZone.LONG); 1060fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 1061fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson setTextCommon(view, R.id.when_time, whenTime + " (" + displayName + ")"); 1062fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 1063fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson else { 1064fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson setTextCommon(view, R.id.when_time, whenTime); 1065fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson } 1066f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson } 1067f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson 1068fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson 10692e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson // Organizer view is setup in the updateCalendar method 10702e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson 10712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Where 1073ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan if (location == null || location.trim().length() == 0) { 10742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setVisibilityCommon(view, R.id.where, View.GONE); 10752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 1076259b8f9a21fffd3858218581e9daaf689b6b888fErik final TextView textView = mWhere; 10772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (textView != null) { 1078ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan textView.setAutoLinkMask(0); 1079ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan textView.setText(location.trim()); 108073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden linkifyTextView(textView); 108173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 1082ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan textView.setOnTouchListener(new OnTouchListener() { 1083c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden @Override 1084ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan public boolean onTouch(View v, MotionEvent event) { 1085ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan try { 1086ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan return v.onTouchEvent(event); 1087ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan } catch (ActivityNotFoundException e) { 1088ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan // ignore 1089ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan return true; 10902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1091ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan } 1092ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan }); 10932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 10952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 10962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Description 1097352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (description != null && description.length() != 0) { 10982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setTextCommon(view, R.id.description, description); 10992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1100c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson updateDescription (); // Expand or collapse full description 11012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 11022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 110373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /** 110473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Replaces stretches of text that look like addresses and phone numbers with clickable 110573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * links. 110673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * <p> 110773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * This is really just an enhanced version of Linkify.addLinks(). 110873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 110973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden private static void linkifyTextView(TextView textView) { 111073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 111173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * If the text includes a street address like "1600 Amphitheater Parkway, 94043", 111273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * the current Linkify code will identify "94043" as a phone number and invite 111373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * you to dial it (and not provide a map link for the address). We want to 111473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * have better recognition of phone numbers without losing any of the existing 111573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * annotations. 111673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 111773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Ideally this would be addressed by improving Linkify. For now we manage it as 111873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * a second pass over the text. 111973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 112073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * URIs and e-mail addresses are pretty easy to pick out of text. Phone numbers 112173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * are a bit tricky because they have radically different formats in different 112273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * countries, in terms of both the digits and the way in which they are commonly 112373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * written or presented (e.g. the punctuation and spaces in "(650) 555-1212"). 112473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The expected format of a street address is defined in WebView.findAddress(). It's 112573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * pretty narrowly defined, so it won't often match. 112673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 112773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The RFC 3966 specification defines the format of a "tel:" URI. 112873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 112973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 113073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 113173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Start by letting Linkify find anything that isn't a phone number. We have to let it 113273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * run first because every invocation removes all previous URLSpan annotations. 113373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 113473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden boolean linkifyFoundLinks = Linkify.addLinks(textView, 113573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Linkify.ALL & ~(Linkify.PHONE_NUMBERS)); 113673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 113773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 113873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Search for phone numbers. 113973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 114073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The "leniency" value can be VALID or POSSIBLE. With VALID we won't match NANP numbers 114173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * shorter than 10 digits, which is inconvenient. With POSSIBLE we get NANP 7-digit 114273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * numbers, and possibly strings of digits inside URIs, but happily we don't flag 114373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * five-digit zip codes like Linkify does. 114473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 114573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Phone links inside URIs will be annotated by the earlier URI linkification, so we just 114673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * need to avoid creating overlapping spans. 114773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 114873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden String defaultPhoneRegion = System.getProperty("user.region", "US"); 114973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); 115073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden CharSequence text = textView.getText(); 115173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Iterable<PhoneNumberMatch> phoneIterable = phoneUtil.findNumbers(text, defaultPhoneRegion, 115273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden PhoneNumberUtil.Leniency.POSSIBLE, Long.MAX_VALUE); 115373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 115473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 115573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * If the contents of the TextView are already Spannable (which will be the case if 115673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Linkify found stuff, but might not be otherwise), we can just add annotations 115773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * to what's there. If it's not, and we find phone numbers, we need to convert it to 115873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * a Spannable form. (This mimics the behavior of Linkable.addLinks().) 115973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 116073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Spannable spanText; 116173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (text instanceof SpannableString) { 116273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden spanText = (SpannableString) text; 116373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } else { 116473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden spanText = SpannableString.valueOf(text); 116573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 116673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 116773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 116873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Get a list of any spans created by Linkify, for the overlapping span check. 116973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 117073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class); 117173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 117273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 117373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Insert spans for the numbers we found. We generate "tel:" URIs. 117473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 117573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int phoneCount = 0; 117673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden for (PhoneNumberMatch match : phoneIterable) { 117773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int start = match.start(); 117873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int end = match.end(); 117973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 118073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (spanWillOverlap(spanText, existingSpans, start, end)) { 118173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (Log.isLoggable(TAG, Log.VERBOSE)) { 118273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Log.v(TAG, "Not linkifying " + match.number().getNationalNumber() + 118373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden " as phone number due to overlap"); 118473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 118573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden continue; 118673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 118773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 118873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /* 118973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * A quick comparison of PhoneNumberUtil number parsing & formatting, with 119073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * defaultRegion="US": 119173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 119273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Input string RFC3966 NATIONAL 119373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 5551212 +1-5551212 555-1212 119473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 6505551212 +1-650-555-1212 (650) 555-1212 119573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 6505551212x123 +1-650-555-1212;ext=123 (650) 555-1212 ext. 123 119673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * +41446681800 +41-44-668-18-00 044 668 18 00 119773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 119873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The conversion of NANP 7-digit numbers to RFC3966 is not compatible with our dialer 119973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * (which tries to dial 8 digits, and fails). So that won't work. 120073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 120173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The conversion of the Swiss number to NATIONAL format loses the country code, 120273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * so that won't work. 120373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * 120473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * The Linkify code takes the matching span and strips out everything that isn't a 120573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * digit or '+' sign. We do the same here. Extension numbers will get appended 120673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * without a separator, but the dialer wasn't doing anything useful with ";ext=" 120773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * anyway. 120873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 120973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 121073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden //String dialStr = phoneUtil.format(match.number(), 121173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // PhoneNumberUtil.PhoneNumberFormat.RFC3966); 121273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden StringBuilder dialBuilder = new StringBuilder(); 121373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden for (int i = start; i < end; i++) { 121473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden char ch = spanText.charAt(i); 121573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (ch == '+' || Character.isDigit(ch)) { 121673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden dialBuilder.append(ch); 121773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 121873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 121973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden URLSpan span = new URLSpan("tel:" + dialBuilder.toString()); 122073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 122173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 122273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden phoneCount++; 122373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 122473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 122573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (phoneCount != 0) { 122673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // If we had to "upgrade" to Spannable, store the object into the TextView. 122773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (spanText != text) { 122873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden textView.setText(spanText); 122973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 123073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 123173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // Linkify.addLinks() sets the TextView movement method if it finds any links. We 123273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // want to do the same here. (This is cloned from Linkify.addLinkMovementMethod().) 123373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden MovementMethod mm = textView.getMovementMethod(); 123473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 123573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if ((mm == null) || !(mm instanceof LinkMovementMethod)) { 123673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (textView.getLinksClickable()) { 123773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden textView.setMovementMethod(LinkMovementMethod.getInstance()); 123873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 123973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 124073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 124173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 124273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (!linkifyFoundLinks && phoneCount == 0) { 124373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (Log.isLoggable(TAG, Log.VERBOSE)) { 124473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Log.v(TAG, "No linkification matches, using geo default"); 124573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 124673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q="); 124773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 124873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 124973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 125073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden /** 125173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden * Determines whether a new span at [start,end) will overlap with any existing span. 125273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden */ 125373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden private static boolean spanWillOverlap(Spannable spanText, URLSpan[] spanList, int start, 125473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int end) { 125573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if (start == end) { 125673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden // empty span, ignore 125773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden return false; 125873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 125973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden for (URLSpan span : spanList) { 126073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int existingStart = spanText.getSpanStart(span); 126173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden int existingEnd = spanText.getSpanEnd(span); 126273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden if ((start >= existingStart && start < existingEnd) || 126373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden end > existingStart && end <= existingEnd) { 126473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden return true; 126573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 126673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 126773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 126873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden return false; 126973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden } 127073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden 1271259b8f9a21fffd3858218581e9daaf689b6b888fErik private void sendAccessibilityEvent() { 1272ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden AccessibilityManager am = 1273ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden (AccessibilityManager) getActivity().getSystemService(Service.ACCESSIBILITY_SERVICE); 1274259b8f9a21fffd3858218581e9daaf689b6b888fErik if (!am.isEnabled()) { 1275259b8f9a21fffd3858218581e9daaf689b6b888fErik return; 1276259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1277259b8f9a21fffd3858218581e9daaf689b6b888fErik 1278259b8f9a21fffd3858218581e9daaf689b6b888fErik AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED); 1279259b8f9a21fffd3858218581e9daaf689b6b888fErik event.setClassName(getClass().getName()); 1280259b8f9a21fffd3858218581e9daaf689b6b888fErik event.setPackageName(getActivity().getPackageName()); 1281259b8f9a21fffd3858218581e9daaf689b6b888fErik List<CharSequence> text = event.getText(); 1282259b8f9a21fffd3858218581e9daaf689b6b888fErik 1283259b8f9a21fffd3858218581e9daaf689b6b888fErik addFieldToAccessibilityEvent(text, mTitle); 1284259b8f9a21fffd3858218581e9daaf689b6b888fErik addFieldToAccessibilityEvent(text, mWhen); 1285259b8f9a21fffd3858218581e9daaf689b6b888fErik addFieldToAccessibilityEvent(text, mWhere); 1286259b8f9a21fffd3858218581e9daaf689b6b888fErik addFieldToAccessibilityEvent(text, mWhat); 1287259b8f9a21fffd3858218581e9daaf689b6b888fErik addFieldToAccessibilityEvent(text, mAttendees); 1288259b8f9a21fffd3858218581e9daaf689b6b888fErik 1289259b8f9a21fffd3858218581e9daaf689b6b888fErik RadioGroup response = (RadioGroup) getView().findViewById(R.id.response_value); 1290259b8f9a21fffd3858218581e9daaf689b6b888fErik if (response.getVisibility() == View.VISIBLE) { 1291259b8f9a21fffd3858218581e9daaf689b6b888fErik int id = response.getCheckedRadioButtonId(); 1292259b8f9a21fffd3858218581e9daaf689b6b888fErik if (id != View.NO_ID) { 1293259b8f9a21fffd3858218581e9daaf689b6b888fErik text.add(((TextView) getView().findViewById(R.id.response_label)).getText()); 1294259b8f9a21fffd3858218581e9daaf689b6b888fErik text.add((((RadioButton) (response.findViewById(id))).getText() + PERIOD_SPACE)); 1295259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1296259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1297259b8f9a21fffd3858218581e9daaf689b6b888fErik 1298259b8f9a21fffd3858218581e9daaf689b6b888fErik am.sendAccessibilityEvent(event); 1299259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1300259b8f9a21fffd3858218581e9daaf689b6b888fErik 1301259b8f9a21fffd3858218581e9daaf689b6b888fErik /** 1302259b8f9a21fffd3858218581e9daaf689b6b888fErik * @param text 1303259b8f9a21fffd3858218581e9daaf689b6b888fErik */ 1304259b8f9a21fffd3858218581e9daaf689b6b888fErik private void addFieldToAccessibilityEvent(List<CharSequence> text, TextView view) { 13059ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson if (view == null) { 13069ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson return; 13079ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson } 1308b4c0150b7d6460bf44fca60aa38d355ab669adaaRoboErik String str = view.getText().toString().trim(); 1309259b8f9a21fffd3858218581e9daaf689b6b888fErik if (!TextUtils.isEmpty(str)) { 1310b4c0150b7d6460bf44fca60aa38d355ab669adaaRoboErik text.add(str); 1311259b8f9a21fffd3858218581e9daaf689b6b888fErik text.add(PERIOD_SPACE); 1312259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1313259b8f9a21fffd3858218581e9daaf689b6b888fErik } 1314259b8f9a21fffd3858218581e9daaf689b6b888fErik 13152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateCalendar(View view) { 13162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAccount = ""; 13172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (mCalendarsCursor != null && mEventCursor != null) { 13182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarsCursor.moveToFirst(); 13192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String tempAccount = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT); 13202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mCalendarOwnerAccount = (tempAccount == null) ? "" : tempAccount; 1321352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOwnerCanRespond = mCalendarsCursor.getInt(CALENDARS_INDEX_OWNER_CAN_RESPOND) != 0; 13222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 13232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String displayName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME); 13242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 13252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // start duplicate calendars query 13262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHandler.startQuery(TOKEN_QUERY_DUPLICATE_CALENDARS, null, Calendars.CONTENT_URI, 13272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang CALENDARS_PROJECTION, CALENDARS_DUPLICATE_NAME_WHERE, 13282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang new String[] {displayName}, null); 13292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 13302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang String eventOrganizer = mEventCursor.getString(EVENT_INDEX_ORGANIZER); 13312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mIsOrganizer = mCalendarOwnerAccount.equalsIgnoreCase(eventOrganizer); 13322e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson setTextCommon(view, R.id.organizer, eventOrganizer); 1333b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson if (!mIsOrganizer) { 1334b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson setVisibilityCommon(view, R.id.organizer_container, View.VISIBLE); 1335b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson } else { 1336b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson setVisibilityCommon(view, R.id.organizer_container, View.GONE); 1337b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson } 13382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mHasAttendeeData = mEventCursor.getInt(EVENT_INDEX_HAS_ATTENDEE_DATA) != 0; 133965eeb79e62034d706503ce29d88c0e05ebd726feRoboErik mCanModifyCalendar = mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) 134065eeb79e62034d706503ce29d88c0e05ebd726feRoboErik >= Calendars.CAL_ACCESS_CONTRIBUTOR; 134165eeb79e62034d706503ce29d88c0e05ebd726feRoboErik // TODO add "|| guestCanModify" after b/1299071 is fixed 134265eeb79e62034d706503ce29d88c0e05ebd726feRoboErik mCanModifyEvent = mCanModifyCalendar && mIsOrganizer; 13432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang mIsBusyFreeCalendar = 1344ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) == Calendars.CAL_ACCESS_FREEBUSY; 1345352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 1346352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (!mIsBusyFreeCalendar) { 13478ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan Button b = (Button) mView.findViewById(R.id.edit); 1348352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan b.setEnabled(true); 13498ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan b.setOnClickListener(new OnClickListener() { 13508ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan @Override 13518ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan public void onClick(View v) { 13528ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan doEdit(); 135310b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // For dialogs, just close the fragment 135410b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson // For full screen, close activity on phone, leave it for tablet 135560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson if (mIsDialog) { 135660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson EventInfoFragment.this.dismiss(); 135760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 135810b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson else if (!mIsTabletConfig){ 135960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson getActivity().finish(); 136060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 1361352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 1362352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan }); 13638ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 1364dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira View button; 1365dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira if (!mCanModifyCalendar) { 1366dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button = mView.findViewById(R.id.delete); 1367dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira if (button != null) { 1368dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button.setEnabled(false); 1369dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button.setVisibility(View.GONE); 137065eeb79e62034d706503ce29d88c0e05ebd726feRoboErik } 1371dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira } 1372dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira if (!mCanModifyEvent) { 1373dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button = mView.findViewById(R.id.edit); 1374dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira if (button != null) { 1375dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button.setEnabled(false); 1376dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira button.setVisibility(View.GONE); 137760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } 1378d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1379d8353fb85ef59a88580125207be9c914a8586758RoboErik if (mMenu != null) { 1380d8353fb85ef59a88580125207be9c914a8586758RoboErik mActivity.invalidateOptionsMenu(); 138169be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik } 13822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 138371b221ae5d0f514352584a955630f5494f686c51Michael Chan setVisibilityCommon(view, R.id.calendar, View.GONE); 1384259b8f9a21fffd3858218581e9daaf689b6b888fErik sendAccessibilityEventIfQueryDone(TOKEN_QUERY_DUPLICATE_CALENDARS); 13852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 13862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 13872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1388d8353fb85ef59a88580125207be9c914a8586758RoboErik /** 1389d8353fb85ef59a88580125207be9c914a8586758RoboErik * 1390d8353fb85ef59a88580125207be9c914a8586758RoboErik */ 1391d8353fb85ef59a88580125207be9c914a8586758RoboErik private void updateMenu() { 1392d8353fb85ef59a88580125207be9c914a8586758RoboErik if (mMenu == null) { 1393d8353fb85ef59a88580125207be9c914a8586758RoboErik return; 1394d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1395d8353fb85ef59a88580125207be9c914a8586758RoboErik MenuItem delete = mMenu.findItem(R.id.info_action_delete); 1396d8353fb85ef59a88580125207be9c914a8586758RoboErik MenuItem edit = mMenu.findItem(R.id.info_action_edit); 1397d8353fb85ef59a88580125207be9c914a8586758RoboErik if (delete != null) { 1398d8353fb85ef59a88580125207be9c914a8586758RoboErik delete.setVisible(mCanModifyCalendar); 1399d8353fb85ef59a88580125207be9c914a8586758RoboErik delete.setEnabled(mCanModifyCalendar); 1400d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1401d8353fb85ef59a88580125207be9c914a8586758RoboErik if (edit != null) { 140265eeb79e62034d706503ce29d88c0e05ebd726feRoboErik edit.setVisible(mCanModifyEvent); 140365eeb79e62034d706503ce29d88c0e05ebd726feRoboErik edit.setEnabled(mCanModifyEvent); 1404d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1405d8353fb85ef59a88580125207be9c914a8586758RoboErik } 1406d8353fb85ef59a88580125207be9c914a8586758RoboErik 14072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void updateAttendees(View view) { 1408fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson if (mAcceptedAttendees.size() + mDeclinedAttendees.size() + 1409fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mTentativeAttendees.size() + mNoResponseAttendees.size() > 0) { 1410c7f3c3896f1bc4cad43aa7f0bca1dee603704613RoboErik mLongAttendees.clearAttendees(); 14114acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mAcceptedAttendees); 14124acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mDeclinedAttendees); 14134acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mTentativeAttendees); 14144acb2fd087308dea146b8b10f5278c59df387680RoboErik (mLongAttendees).addAttendees(mNoResponseAttendees); 1415fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mLongAttendees.setEnabled(false); 1416fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mLongAttendees.setVisibility(View.VISIBLE); 141760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson } else { 1418fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson mLongAttendees.setVisibility(View.GONE); 141971b221ae5d0f514352584a955630f5494f686c51Michael Chan } 14208ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 14218ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 14221ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public void initReminders(View view, Cursor cursor) { 14231ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 14241ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Add reminders 1425c7f3c3896f1bc4cad43aa7f0bca1dee603704613RoboErik mOriginalReminders.clear(); 14261ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson while (cursor.moveToNext()) { 14271ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int minutes = cursor.getInt(EditEventHelper.REMINDERS_INDEX_MINUTES); 14281ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int method = cursor.getInt(EditEventHelper.REMINDERS_INDEX_METHOD); 14291ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mOriginalReminders.add(ReminderEntry.valueOf(minutes, method)); 14301ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 14311ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Sort appropriately for display (by time, then type) 14321ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Collections.sort(mOriginalReminders); 14331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 14341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Load the labels and corresponding numeric values for the minutes and methods lists 14351ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // from the assets. If we're switching calendars, we need to clear and re-populate the 14361ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // lists (which may have elements added and removed based on calendar properties). This 14371ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // is mostly relevant for "methods", since we shouldn't have any "minutes" values in a 14381ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // new event that aren't in the default set. 14391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Resources r = mActivity.getResources(); 14401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues = loadIntegerArray(r, R.array.reminder_minutes_values); 14411ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteLabels = loadStringArray(r, R.array.reminder_minutes_labels); 14421ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodValues = loadIntegerArray(r, R.array.reminder_methods_values); 14431ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodLabels = loadStringArray(r, R.array.reminder_methods_labels); 14441ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 14451ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Remove any reminder methods that aren't allowed for this calendar. If this is 14461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // a new event, mCalendarAllowedReminders may not be set the first time we're called. 14471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mCalendarAllowedReminders != null) { 14481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.reduceMethodList(mReminderMethodValues, mReminderMethodLabels, 14491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mCalendarAllowedReminders); 14501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 14511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 14521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mHasAlarm) { 14531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<ReminderEntry> reminders = mOriginalReminders; 14541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Insert any minute values that aren't represented in the minutes list. 14551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson for (ReminderEntry re : reminders) { 14561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addMinutesToList( 14571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mActivity, mReminderMinuteValues, mReminderMinuteLabels, re.getMinutes()); 14581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 14591ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Create a UI element for each reminder. We display all of the reminders we get 14601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // from the provider, even if the count exceeds the calendar maximum. (Also, for 14611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // a new event, we won't have a maxReminders value available.) 14621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson for (ReminderEntry re : reminders) { 14631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, 14641ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues, mReminderMinuteLabels, 14651ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodValues, mReminderMethodLabels, 14661ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson re, Integer.MAX_VALUE); 14671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 14681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 14691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 14701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 14718ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan private void formatAttendees(ArrayList<Attendee> attendees, SpannableStringBuilder sb, int type) { 14728ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan if (attendees.size() <= 0) { 14738ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan return; 14748ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 14758ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 14768ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan int begin = sb.length(); 14778ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan boolean firstTime = sb.length() == 0; 14788ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 14798ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan if (firstTime == false) { 14808ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan begin += 2; // skip over the ", " for formatting. 14818ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 14828ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 14838ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan for (Attendee attendee : attendees) { 14848ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan if (firstTime) { 14858ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan firstTime = false; 14868ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } else { 14878ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan sb.append(", "); 14888ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 14898ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 14908ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan String name = attendee.getDisplayName(); 14918ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan sb.append(name); 14928ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan } 14938ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan 14948ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan switch (type) { 14958ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan case Attendees.ATTENDEE_STATUS_ACCEPTED: 14968ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan break; 14978ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan case Attendees.ATTENDEE_STATUS_DECLINED: 14988ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan sb.setSpan(new StrikethroughSpan(), begin, sb.length(), 14998ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 15008ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan // fall through 15018ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan default: 15028ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan // The last INCLUSIVE causes the foreground color to be applied 15038ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan // to the rest of the span. If not, the comma at the end of the 15048ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan // declined or tentative may be black. 15050a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan sb.setSpan(new ForegroundColorSpan(0xFF999999), begin, sb.length(), 15068ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan Spannable.SPAN_EXCLUSIVE_INCLUSIVE); 15078ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan break; 15082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang void updateResponse(View view) { 15122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // we only let the user accept/reject/etc. a meeting if: 15132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // a) you can edit the event's containing calendar AND 15142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // b) you're not the organizer and only attendee AND 15152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // c) organizerCanRespond is enabled for the calendar 15162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // (if the attendee data has been hidden, the visible number of attendees 15172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // will be 1 -- the calendar owner's). 15182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // (there are more cases involved to be 100% accurate, such as 15192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // paying attention to whether or not an attendee status was 15202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // included in the feed, but we're currently omitting those corner cases 15212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // for simplicity). 1522352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 1523352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // TODO Switch to EditEventHelper.canRespond when this class uses CalendarEventModel. 1524d785cd533f6a3c23813c15315aed74efa9a116f5Michael Chan if (!mCanModifyCalendar || (mHasAttendeeData && mIsOrganizer && mNumOfAttendees <= 1) || 1525352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan (mIsOrganizer && !mOwnerCanRespond)) { 15262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setVisibilityCommon(view, R.id.response_container, View.GONE); 15272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 15282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang setVisibilityCommon(view, R.id.response_container, View.VISIBLE); 15312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 1532f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 1533f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int response; 1534deced8999da73effe4133e2317c262fea7910090Michael Chan if (mAttendeeResponseFromIntent != CalendarController.ATTENDEE_NO_RESPONSE) { 1535f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = mAttendeeResponseFromIntent; 15362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 1537f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan response = mOriginalAttendeeResponse; 15382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1539f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan 1540f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan int buttonToCheck = findButtonIdForResponse(response); 1541f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.response_value); 1542f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan radioGroup.check(buttonToCheck); // -1 clear all radio buttons 1543f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan radioGroup.setOnCheckedChangeListener(this); 15442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void setTextCommon(View view, int id, CharSequence text) { 15472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang TextView textView = (TextView) view.findViewById(id); 15482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (textView == null) 15492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 15502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang textView.setText(text); 15512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang private void setVisibilityCommon(View view, int id, int visibility) { 15542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang View v = view.findViewById(id); 15552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (v != null) { 15562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang v.setVisibility(visibility); 15572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang return; 15592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang /** 15622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Taken from com.google.android.gm.HtmlConversationActivity 15632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * 15642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Send the intent that shows the Contact info corresponding to the email address. 15652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */ 15662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang public void showContactInfo(Attendee attendee, Rect rect) { 15672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // First perform lookup query to find existing contact 15682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final ContentResolver resolver = getActivity().getContentResolver(); 15692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final String address = attendee.mEmail; 15702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Uri dataUri = Uri.withAppendedPath(CommonDataKinds.Email.CONTENT_FILTER_URI, 15712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Uri.encode(address)); 15722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Uri lookupUri = ContactsContract.Data.getContactLookupUri(resolver, dataUri); 15732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (lookupUri != null) { 15752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Found matching contact, trigger QuickContact 15762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang QuickContact.showQuickContact(getActivity(), rect, lookupUri, 15772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang QuickContact.MODE_MEDIUM, null); 15782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } else { 15792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // No matching contact, ask user to create one 15802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Uri mailUri = Uri.fromParts("mailto", address, null); 15812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, mailUri); 15822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Pass along full E-mail string for possible create dialog 15842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang Rfc822Token sender = new Rfc822Token(attendee.mName, attendee.mEmail, null); 15852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang intent.putExtra(Intents.EXTRA_CREATE_DESCRIPTION, sender.toString()); 15862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang // Only provide personal name hint if we have one 15882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang final String senderPersonal = attendee.mName; 15892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang if (!TextUtils.isEmpty(senderPersonal)) { 15902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang intent.putExtra(Intents.Insert.NAME, senderPersonal); 15912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang 15932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang startActivity(intent); 15942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 15952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang } 1596cb81189e4868769ea016253eca104e46df2f033aErik 1597cb81189e4868769ea016253eca104e46df2f033aErik @Override 15987c6236d5553dc9f3d004ebbed794249713a11d19RoboErik public void onPause() { 15997c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mIsPaused = true; 16007c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mHandler.removeCallbacks(onDeleteRunnable); 16017c6236d5553dc9f3d004ebbed794249713a11d19RoboErik super.onPause(); 16027c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 16037c6236d5553dc9f3d004ebbed794249713a11d19RoboErik 16047c6236d5553dc9f3d004ebbed794249713a11d19RoboErik @Override 16057c6236d5553dc9f3d004ebbed794249713a11d19RoboErik public void onResume() { 16067c6236d5553dc9f3d004ebbed794249713a11d19RoboErik super.onResume(); 16077c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mIsPaused = false; 16087c6236d5553dc9f3d004ebbed794249713a11d19RoboErik if (mDismissOnResume) { 16097c6236d5553dc9f3d004ebbed794249713a11d19RoboErik mHandler.post(onDeleteRunnable); 16107c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 16117c6236d5553dc9f3d004ebbed794249713a11d19RoboErik } 16127c6236d5553dc9f3d004ebbed794249713a11d19RoboErik 16137c6236d5553dc9f3d004ebbed794249713a11d19RoboErik @Override 1614cb81189e4868769ea016253eca104e46df2f033aErik public void eventsChanged() { 1615cb81189e4868769ea016253eca104e46df2f033aErik } 1616cb81189e4868769ea016253eca104e46df2f033aErik 1617cb81189e4868769ea016253eca104e46df2f033aErik @Override 1618cb81189e4868769ea016253eca104e46df2f033aErik public long getSupportedEventTypes() { 1619cb81189e4868769ea016253eca104e46df2f033aErik return EventType.EVENTS_CHANGED; 1620cb81189e4868769ea016253eca104e46df2f033aErik } 1621cb81189e4868769ea016253eca104e46df2f033aErik 1622cb81189e4868769ea016253eca104e46df2f033aErik @Override 1623cb81189e4868769ea016253eca104e46df2f033aErik public void handleEvent(EventInfo event) { 1624f836d4af478310abc9b63f1afa6ab964e2478fedRoboErik if (event.eventType == EventType.EVENTS_CHANGED && mHandler != null) { 1625cb81189e4868769ea016253eca104e46df2f033aErik // reload the data 1626cb81189e4868769ea016253eca104e46df2f033aErik mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION, 1627cb81189e4868769ea016253eca104e46df2f033aErik null, null, null); 1628cb81189e4868769ea016253eca104e46df2f033aErik } 1629cb81189e4868769ea016253eca104e46df2f033aErik 1630cb81189e4868769ea016253eca104e46df2f033aErik } 16311ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16321ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson @Override 16341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson public void onClick(View view) { 16351ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16361ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // This must be a click on one of the "remove reminder" buttons 16371ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson LinearLayout reminderItem = (LinearLayout) view.getParent(); 16381ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson LinearLayout parent = (LinearLayout) reminderItem.getParent(); 16391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson parent.removeView(reminderItem); 16401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderViews.remove(reminderItem); 16411ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 16421ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16431ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16441ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 16451ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Add a new reminder when the user hits the "add reminder" button. We use the default 16461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * reminder time and method. 16471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 16481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private void addReminder() { 16491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // TODO: when adding a new reminder, make it different from the 16501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // last one in the list (if any). 16511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (mDefaultReminderMinutes == GeneralPreferences.NO_REMINDER) { 16521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, 16531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues, mReminderMinuteLabels, 16541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodValues, mReminderMethodLabels, 16551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ReminderEntry.valueOf(GeneralPreferences.REMINDER_DEFAULT_TIME), 16561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mMaxReminders); 16571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } else { 16581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, 16591ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues, mReminderMinuteLabels, 16601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodValues, mReminderMethodLabels, 16611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ReminderEntry.valueOf(mDefaultReminderMinutes), 16621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mMaxReminders); 16631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 16641ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 16651ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16661ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private void prepareReminders() { 16681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Resources r = mActivity.getResources(); 16691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues = loadIntegerArray(r, R.array.reminder_minutes_values); 16701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteLabels = loadStringArray(r, R.array.reminder_minutes_labels); 16711ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodValues = loadIntegerArray(r, R.array.reminder_methods_values); 16721ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMethodLabels = loadStringArray(r, R.array.reminder_methods_labels); 16731ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 16741ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16751ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16761ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private boolean saveReminders() { 16771ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(3); 16781ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Read reminders from UI 16801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminders = EventViewUtils.reminderItemsToReminders(mReminderViews, 16811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mReminderMinuteValues, mReminderMethodValues); 16821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Check if there are any changes in the reminder 16841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson boolean changed = EditEventHelper.saveReminders(ops, mEventId, mReminders, 16851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson mOriginalReminders, false /* no force save */); 16861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16871ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (!changed) { 16881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return false; 16891ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 16901ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 16911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // save new reminders 16921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson AsyncQueryService service = new AsyncQueryService(getActivity()); 16931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson service.startBatch(0, null, Calendars.CONTENT_URI.getAuthority(), ops, 0); 16941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson // Update the "hasAlarm" field for the event 16951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); 16961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int len = mReminders.size(); 16971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson boolean hasAlarm = len > 0; 16981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson if (hasAlarm != mHasAlarm) { 16991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ContentValues values = new ContentValues(); 17001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson values.put(Events.HAS_ALARM, hasAlarm ? 1 : 0); 17011ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson service.startUpdate(0, null, uri, values, null, null, 0); 17021ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 17031ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return true; 17041ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 17051ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 17061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 17071ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Loads an integer array asset into a list. 17081ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 17091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static ArrayList<Integer> loadIntegerArray(Resources r, int resNum) { 17101ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int[] vals = r.getIntArray(resNum); 17111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson int size = vals.length; 17121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<Integer> list = new ArrayList<Integer>(size); 17131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 17141ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson for (int i = 0; i < size; i++) { 17151ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson list.add(vals[i]); 17161ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 17171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 17181ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return list; 17191ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 17201ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson /** 17211ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson * Loads a String array asset into a list. 17221ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson */ 17231ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson private static ArrayList<String> loadStringArray(Resources r, int resNum) { 17241ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson String[] labels = r.getStringArray(resNum); 17251ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson ArrayList<String> list = new ArrayList<String>(Arrays.asList(labels)); 17261ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson return list; 17271ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson } 17281ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson 17292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang} 1730