EventInfoFragment.java revision cba7f1fd22e1d7ee9d8d0828f37bc08512bf6b75
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;
301ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport com.android.calendar.event.EventViewUtils;
318b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport com.android.calendarcommon.EventRecurrence;
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;
4586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelsonimport android.content.DialogInterface;
462bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Intent;
471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.content.SharedPreferences;
482bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.res.Resources;
492bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.database.Cursor;
502bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.graphics.Rect;
5171b221ae5d0f514352584a955630f5494f686c51Michael Chanimport android.graphics.Typeface;
522bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.net.Uri;
532bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.os.Bundle;
54a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract;
55a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees;
56a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars;
57a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events;
581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.provider.CalendarContract.Reminders;
59cb81189e4868769ea016253eca104e46df2f033aErikimport android.provider.ContactsContract;
602bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.CommonDataKinds;
612bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.Intents;
622bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.QuickContact;
638ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.Spannable;
6473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.SpannableString;
658ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.SpannableStringBuilder;
6673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.Spanned;
672bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.TextUtils;
682bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.DateFormat;
692bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.DateUtils;
702bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.Time;
7173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.method.LinkMovementMethod;
7273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.method.MovementMethod;
738ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.ForegroundColorSpan;
748ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.StrikethroughSpan;
7571b221ae5d0f514352584a955630f5494f686c51Michael Chanimport android.text.style.StyleSpan;
7673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFaddenimport android.text.style.URLSpan;
772bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Linkify;
782bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Rfc822Token;
792bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.util.Log;
8071d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Gravity;
812bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.LayoutInflater;
8260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.Menu;
8360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.MenuInflater;
8460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelsonimport android.view.MenuItem;
852bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.MotionEvent;
862bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.View;
87cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnClickListener;
88cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnTouchListener;
892bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.ViewGroup;
9071d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Window;
9171d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.WindowManager;
92259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityEvent;
93259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityManager;
942bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.AdapterView;
958b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport android.widget.AdapterView.OnItemSelectedListener;
968ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.widget.Button;
971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport android.widget.LinearLayout;
98259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.widget.RadioButton;
99f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup;
100f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup.OnCheckedChangeListener;
1018b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport android.widget.ScrollView;
1022bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.TextView;
1032bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.Toast;
1042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1052bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport java.util.ArrayList;
1061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport java.util.Arrays;
1071ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelsonimport java.util.Collections;
10874c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelsonimport java.util.Formatter;
109259b8f9a21fffd3858218581e9daaf689b6b888fErikimport java.util.List;
11074c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelsonimport java.util.Locale;
111f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelsonimport java.util.TimeZone;
1128b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErikimport java.util.regex.Pattern;
113f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson
1142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
115f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanpublic class EventInfoFragment extends DialogFragment implements OnCheckedChangeListener,
116b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson        CalendarController.EventHandler, OnClickListener, DeleteEventHelper.DeleteNotifyListener {
117d845fbe558d5229102b58cce70a1b29fe6cb6967Erik    public static final boolean DEBUG = false;
1182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1192c7c851a4e40afa83a741ec39d44425b705a712eMichael Chan    public static final String TAG = "EventInfoFragment";
1202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
12160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    protected static final String BUNDLE_KEY_EVENT_ID = "key_event_id";
12260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    protected static final String BUNDLE_KEY_START_MILLIS = "key_start_millis";
12360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    protected static final String BUNDLE_KEY_END_MILLIS = "key_end_millis";
12460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    protected static final String BUNDLE_KEY_IS_DIALOG = "key_fragment_is_dialog";
12586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson    protected static final String BUNDLE_KEY_DELETE_DIALOG_VISIBLE = "key_delete_dialog_visible";
1267ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    protected static final String BUNDLE_KEY_WINDOW_STYLE = "key_window_style";
12760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    protected static final String BUNDLE_KEY_ATTENDEE_RESPONSE = "key_attendee_response";
12871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
129259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final String PERIOD_SPACE = ". ";
130259b8f9a21fffd3858218581e9daaf689b6b888fErik
1312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
1322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * These are the corresponding indices into the array of strings
1332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * "R.array.change_response_labels" in the resource file.
1342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
1352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int UPDATE_SINGLE = 0;
1362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int UPDATE_ALL = 1;
1372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1387ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    // Style of view
1397ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    public static final int FULL_WINDOW_STYLE = 0;
1407ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    public static final int DIALOG_WINDOW_STYLE = 1;
1417ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson
1427ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    private int mWindowStyle = DIALOG_WINDOW_STYLE;
1437ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson
1442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    // Query tokens for QueryHandler
145259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final int TOKEN_QUERY_EVENT = 1 << 0;
146259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final int TOKEN_QUERY_CALENDARS = 1 << 1;
147259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final int TOKEN_QUERY_ATTENDEES = 1 << 2;
148259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final int TOKEN_QUERY_DUPLICATE_CALENDARS = 1 << 3;
1491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int TOKEN_QUERY_REMINDERS = 1 << 4;
150259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final int TOKEN_QUERY_ALL = TOKEN_QUERY_DUPLICATE_CALENDARS
1511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            | TOKEN_QUERY_ATTENDEES | TOKEN_QUERY_CALENDARS | TOKEN_QUERY_EVENT
1521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            | TOKEN_QUERY_REMINDERS;
153259b8f9a21fffd3858218581e9daaf689b6b888fErik    private int mCurrentQuery = 0;
1542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String[] EVENT_PROJECTION = new String[] {
1562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events._ID,                  // 0  do not remove; used in DeleteEventHelper
1572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.TITLE,                // 1  do not remove; used in DeleteEventHelper
1582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.RRULE,                // 2  do not remove; used in DeleteEventHelper
1592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.ALL_DAY,              // 3  do not remove; used in DeleteEventHelper
1602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.CALENDAR_ID,          // 4  do not remove; used in DeleteEventHelper
1612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.DTSTART,              // 5  do not remove; used in DeleteEventHelper
1622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events._SYNC_ID,             // 6  do not remove; used in DeleteEventHelper
1632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.EVENT_TIMEZONE,       // 7  do not remove; used in DeleteEventHelper
1642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.DESCRIPTION,          // 8
1652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.EVENT_LOCATION,       // 9
166ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik        Calendars.CALENDAR_ACCESS_LEVEL,      // 10
1670e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik        Calendars.CALENDAR_COLOR,             // 11
16871b221ae5d0f514352584a955630f5494f686c51Michael Chan        Events.HAS_ATTENDEE_DATA,    // 12
16971b221ae5d0f514352584a955630f5494f686c51Michael Chan        Events.ORGANIZER,            // 13
1701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Events.HAS_ALARM,            // 14
1711ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Calendars.MAX_REMINDERS,     //15
1721ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Calendars.ALLOWED_REMINDERS, // 16
17365eeb79e62034d706503ce29d88c0e05ebd726feRoboErik        Events.ORIGINAL_SYNC_ID,     // 17 do not remove; used in DeleteEventHelper
1742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    };
1752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_ID = 0;
1762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_TITLE = 1;
1772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_RRULE = 2;
1782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_ALL_DAY = 3;
1792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_CALENDAR_ID = 4;
1802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_SYNC_ID = 6;
1812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_EVENT_TIMEZONE = 7;
1822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_DESCRIPTION = 8;
1832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_EVENT_LOCATION = 9;
18471b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_ACCESS_LEVEL = 10;
18571b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_COLOR = 11;
18671b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_HAS_ATTENDEE_DATA = 12;
18771b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_ORGANIZER = 13;
1881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int EVENT_INDEX_HAS_ALARM = 14;
1891ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int EVENT_INDEX_MAX_REMINDERS = 15;
1901ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int EVENT_INDEX_ALLOWED_REMINDERS = 16;
1911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
1922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String[] ATTENDEES_PROJECTION = new String[] {
1942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees._ID,                      // 0
1952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_NAME,            // 1
1962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_EMAIL,           // 2
1972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_RELATIONSHIP,    // 3
1982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_STATUS,          // 4
1992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    };
2002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_ID = 0;
2012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_NAME = 1;
2022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_EMAIL = 2;
2032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_RELATIONSHIP = 3;
2042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_STATUS = 4;
2052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=?";
2072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String ATTENDEES_SORT_ORDER = Attendees.ATTENDEE_NAME + " ASC, "
2092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            + Attendees.ATTENDEE_EMAIL + " ASC";
2102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final String[] REMINDERS_PROJECTION = new String[] {
2121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Reminders._ID,                      // 0
2131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Reminders.MINUTES,            // 1
2141ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Reminders.METHOD           // 2
2151ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    };
2161ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int REMINDERS_INDEX_ID = 0;
2171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int REMINDERS_MINUTES_ID = 1;
2181ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final int REMINDERS_METHOD_ID = 2;
2191ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
2201ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=?";
2211ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
2222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final String[] CALENDARS_PROJECTION = new String[] {
2232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Calendars._ID,           // 0
224ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik        Calendars.CALENDAR_DISPLAY_NAME,  // 1
2252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Calendars.OWNER_ACCOUNT, // 2
226950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden        Calendars.CAN_ORGANIZER_RESPOND // 3
2272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    };
2282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int CALENDARS_INDEX_DISPLAY_NAME = 1;
2292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int CALENDARS_INDEX_OWNER_ACCOUNT = 2;
2302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int CALENDARS_INDEX_OWNER_CAN_RESPOND = 3;
2312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final String CALENDARS_WHERE = Calendars._ID + "=?";
233ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik    static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.CALENDAR_DISPLAY_NAME + "=?";
2342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private View mView;
2362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Uri mUri;
2382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private long mEventId;
2392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Cursor mEventCursor;
2402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Cursor mAttendeesCursor;
2412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Cursor mCalendarsCursor;
2421ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private Cursor mRemindersCursor;
2431ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
2440a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan    private static float mScale = 0; // Used for supporting different screen densities
2452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private long mStartMillis;
2472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private long mEndMillis;
2482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mHasAttendeeData;
2502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mIsOrganizer;
251d845fbe558d5229102b58cce70a1b29fe6cb6967Erik    private long mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE;
252352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan    private boolean mOwnerCanRespond;
2532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private String mCalendarOwnerAccount;
2542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mCanModifyCalendar;
25565eeb79e62034d706503ce29d88c0e05ebd726feRoboErik    private boolean mCanModifyEvent;
2562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mIsBusyFreeCalendar;
2572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mNumOfAttendees;
2582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private EditResponseHelper mEditResponseHelper;
26086ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson    private boolean mDeleteDialogVisible = false;
26186ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson    private DeleteEventHelper mDeleteHelper;
2622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mOriginalAttendeeResponse;
264deced8999da73effe4133e2317c262fea7910090Michael Chan    private int mAttendeeResponseFromIntent = CalendarController.ATTENDEE_NO_RESPONSE;
2655afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik    private int mUserSetResponse = CalendarController.ATTENDEE_NO_RESPONSE;
2662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mIsRepeating;
2671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private boolean mHasAlarm;
2681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private int mMaxReminders;
2691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private String mCalendarAllowedReminders;
270b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson    // Used to prevent saving changes in event if it is being deleted.
271b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson    private boolean mEventDeletionStarted = false;
2722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
273259b8f9a21fffd3858218581e9daaf689b6b888fErik    private TextView mTitle;
274aeae98bf8f8c5c544f65f5b6b7f29cfd31366ad5Michael Chan    private TextView mWhenDate;
275aeae98bf8f8c5c544f65f5b6b7f29cfd31366ad5Michael Chan    private TextView mWhenTime;
276259b8f9a21fffd3858218581e9daaf689b6b888fErik    private TextView mWhere;
2772d2cc0a9604dfd803729a8f2be211e6800e9b410Michael Chan    private TextView mDesc;
278c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private AttendeesView mLongAttendees;
279d8353fb85ef59a88580125207be9c914a8586758RoboErik    private Menu mMenu = null;
280fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson    private View mHeadlines;
2811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private ScrollView mScrollView;
282259b8f9a21fffd3858218581e9daaf689b6b888fErik
28373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    private static final Pattern mWildcardPattern = Pattern.compile("^.*$");
2842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>();
2862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>();
2872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>();
2882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mNoResponseAttendees = new ArrayList<Attendee>();
2892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mColor;
2902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2911ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
2921ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private int mDefaultReminderMinutes;
2931ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private ArrayList<LinearLayout> mReminderViews = new ArrayList<LinearLayout>(0);
2941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    public ArrayList<ReminderEntry> mReminders;
2957f078b716fa7f1d374af9af3dad05d2e249e18c8RoboErik    public ArrayList<ReminderEntry> mOriginalReminders = new ArrayList<ReminderEntry>();
2967f078b716fa7f1d374af9af3dad05d2e249e18c8RoboErik    public ArrayList<ReminderEntry> mUnsupportedReminders = new ArrayList<ReminderEntry>();
2978b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik    private boolean mUserModifiedReminders = false;
2981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
2991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    /**
3001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * Contents of the "minutes" spinner.  This has default values from the XML file, augmented
3011ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * with any additional values that were already associated with the event.
3021ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     */
3031ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private ArrayList<Integer> mReminderMinuteValues;
3041ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private ArrayList<String> mReminderMinuteLabels;
3051ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
3061ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    /**
3071ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * Contents of the "methods" spinner.  The "values" list specifies the method constant
3081ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * (e.g. {@link Reminders#METHOD_ALERT}) associated with the labels.  Any methods that
3091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * aren't allowed by the Calendar will be removed.
3101ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     */
3111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private ArrayList<Integer> mReminderMethodValues;
3121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private ArrayList<String> mReminderMethodLabels;
3131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
3142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private QueryHandler mHandler;
3152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
316b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson
317cb81189e4868769ea016253eca104e46df2f033aErik    private Runnable mTZUpdater = new Runnable() {
318cb81189e4868769ea016253eca104e46df2f033aErik        @Override
319cb81189e4868769ea016253eca104e46df2f033aErik        public void run() {
320cb81189e4868769ea016253eca104e46df2f033aErik            updateEvent(mView);
321cb81189e4868769ea016253eca104e46df2f033aErik        }
322cb81189e4868769ea016253eca104e46df2f033aErik    };
323cb81189e4868769ea016253eca104e46df2f033aErik
3248b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik    private OnItemSelectedListener mReminderChangeListener;
3258b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik
3267ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    private static int mDialogWidth = 500;
3277ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson    private static int mDialogHeight = 600;
3280aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson    private static int DIALOG_TOP_MARGIN = 8;
32971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private boolean mIsDialog = false;
3307c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    private boolean mIsPaused = true;
3317c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    private boolean mDismissOnResume = false;
33271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private int mX = -1;
33371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private int mY = -1;
3340aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson    private int mMinTop;         // Dialog cannot be above this location
335c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private Button mDescButton;  // Button to expand/collapse the description
336c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private String mMoreLabel;   // Labels for the button
337c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private String mLessLabel;
338c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private boolean mShowMaxDescription;  // Current status of button
339c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private int mDescLineNum;             // The default number of lines in the description
34010b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson    private boolean mIsTabletConfig;
34110b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson    private Activity mActivity;
342be2a432034e96c9f2fbf333cd7fe6489312bbeaaMichael Chan    private Context mContext;
34371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
3442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private class QueryHandler extends AsyncQueryService {
3452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        public QueryHandler(Context context) {
3462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            super(context);
3472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
3482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        @Override
3502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
3514003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            // if the activity is finishing, then close the cursor and return
3524003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            final Activity activity = getActivity();
3534003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            if (activity == null || activity.isFinishing()) {
3544003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                cursor.close();
3554003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
3564003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            }
3574003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
3582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            switch (token) {
3592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_EVENT:
3602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mEventCursor = Utils.matrixCursorFromCursor(cursor);
3612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                if (initEventCursor()) {
3622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    // The cursor is empty. This can happen if the event was
3632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    // deleted.
3642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    // FRAG_TODO we should no longer rely on Activity.finish()
3651df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang                    activity.finish();
3662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    return;
3672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                }
3682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateEvent(mView);
369e35a032c939f357ce435711b2fd8de1887a05011RoboErik                prepareReminders();
3702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                // start calendar query
3722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Uri uri = Calendars.CONTENT_URI;
3732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                String[] args = new String[] {
3742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        Long.toString(mEventCursor.getLong(EVENT_INDEX_CALENDAR_ID))};
3752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                startQuery(TOKEN_QUERY_CALENDARS, null, uri, CALENDARS_PROJECTION,
3762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        CALENDARS_WHERE, args, null);
3772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
3782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_CALENDARS:
3792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mCalendarsCursor = Utils.matrixCursorFromCursor(cursor);
3802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateCalendar(mView);
3814003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                // FRAG_TODO fragments shouldn't set the title anymore
3822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateTitle();
3832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
384352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                if (!mIsBusyFreeCalendar) {
385352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    args = new String[] { Long.toString(mEventId) };
386352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
387352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    // start attendees query
388352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    uri = Attendees.CONTENT_URI;
389352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    startQuery(TOKEN_QUERY_ATTENDEES, null, uri, ATTENDEES_PROJECTION,
390352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                            ATTENDEES_WHERE, args, ATTENDEES_SORT_ORDER);
391259b8f9a21fffd3858218581e9daaf689b6b888fErik                } else {
392259b8f9a21fffd3858218581e9daaf689b6b888fErik                    sendAccessibilityEventIfQueryDone(TOKEN_QUERY_ATTENDEES);
3932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                }
3941ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                if (mHasAlarm) {
3951ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                    // start reminders query
3961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                    args = new String[] { Long.toString(mEventId) };
3971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                    uri = Reminders.CONTENT_URI;
3981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                    startQuery(TOKEN_QUERY_REMINDERS, null, uri,
3991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                            REMINDERS_PROJECTION, REMINDERS_WHERE, args, null);
4001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                } else {
4011ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                    sendAccessibilityEventIfQueryDone(TOKEN_QUERY_REMINDERS);
4021ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                }
4032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
4042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_ATTENDEES:
4052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mAttendeesCursor = Utils.matrixCursorFromCursor(cursor);
4062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                initAttendeesCursor(mView);
4072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateResponse(mView);
4082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
4091ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            case TOKEN_QUERY_REMINDERS:
4101ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                mRemindersCursor = Utils.matrixCursorFromCursor(cursor);
4111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                initReminders(mView, mRemindersCursor);
4121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                break;
4132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_DUPLICATE_CALENDARS:
41471b221ae5d0f514352584a955630f5494f686c51Michael Chan                Resources res = activity.getResources();
41571b221ae5d0f514352584a955630f5494f686c51Michael Chan                SpannableStringBuilder sb = new SpannableStringBuilder();
41671b221ae5d0f514352584a955630f5494f686c51Michael Chan
41771b221ae5d0f514352584a955630f5494f686c51Michael Chan                // Label
41871b221ae5d0f514352584a955630f5494f686c51Michael Chan                String label = res.getString(R.string.view_event_calendar_label);
41971b221ae5d0f514352584a955630f5494f686c51Michael Chan                sb.append(label).append(" ");
42071b221ae5d0f514352584a955630f5494f686c51Michael Chan                sb.setSpan(new StyleSpan(Typeface.BOLD), 0, label.length(),
42171b221ae5d0f514352584a955630f5494f686c51Michael Chan                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
42271b221ae5d0f514352584a955630f5494f686c51Michael Chan
42371b221ae5d0f514352584a955630f5494f686c51Michael Chan                // Calendar display name
4242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                String calendarName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
42571b221ae5d0f514352584a955630f5494f686c51Michael Chan                sb.append(calendarName);
42671b221ae5d0f514352584a955630f5494f686c51Michael Chan
42771b221ae5d0f514352584a955630f5494f686c51Michael Chan                // Show email account if display name is not unique and
42871b221ae5d0f514352584a955630f5494f686c51Michael Chan                // display name != email
42971b221ae5d0f514352584a955630f5494f686c51Michael Chan                String email = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT);
43071b221ae5d0f514352584a955630f5494f686c51Michael Chan                if (cursor.getCount() > 1 && !calendarName.equalsIgnoreCase(email)) {
43171b221ae5d0f514352584a955630f5494f686c51Michael Chan                    sb.append(" (").append(email).append(")");
43271b221ae5d0f514352584a955630f5494f686c51Michael Chan                }
43371b221ae5d0f514352584a955630f5494f686c51Michael Chan
4342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
4352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
4362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            cursor.close();
437259b8f9a21fffd3858218581e9daaf689b6b888fErik            sendAccessibilityEventIfQueryDone(token);
4382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
4392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
4412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
442259b8f9a21fffd3858218581e9daaf689b6b888fErik    private void sendAccessibilityEventIfQueryDone(int token) {
443259b8f9a21fffd3858218581e9daaf689b6b888fErik        mCurrentQuery |= token;
444259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (mCurrentQuery == TOKEN_QUERY_ALL) {
445259b8f9a21fffd3858218581e9daaf689b6b888fErik            sendAccessibilityEvent();
446259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
447259b8f9a21fffd3858218581e9daaf689b6b888fErik    }
448259b8f9a21fffd3858218581e9daaf689b6b888fErik
4490a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan    public EventInfoFragment(Context context, Uri uri, long startMillis, long endMillis,
4507ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            int attendeeResponse, boolean isDialog, int windowStyle) {
4517ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson
4527ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        if (isDialog) {
4537ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            Resources r = context.getResources();
4547ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson
4557ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            mDialogWidth = r.getInteger(R.integer.event_info_dialog_width);
4567ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            mDialogHeight = r.getInteger(R.integer.event_info_dialog_height);
4577ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson
4587ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            if (mScale == 0) {
4597ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                mScale = context.getResources().getDisplayMetrics().density;
4607ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                if (mScale != 1) {
4617ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                    mDialogWidth *= mScale;
4627ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                    mDialogHeight *= mScale;
4637ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                    DIALOG_TOP_MARGIN *= mScale;
4647ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                }
4650a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan            }
4660a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan        }
46760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        mIsDialog = isDialog;
468c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson
4692fc6b79dfb06812baf2e6c547f3ffee83b5c3e9aMichael Chan        setStyle(DialogFragment.STYLE_NO_TITLE, 0);
4702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mUri = uri;
4712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mStartMillis = startMillis;
4722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEndMillis = endMillis;
4732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mAttendeeResponseFromIntent = attendeeResponse;
4747ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        mWindowStyle = windowStyle;
4752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
4762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
477ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden    // This is currently required by the fragment manager.
47860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    public EventInfoFragment() {
47960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    }
48060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson
48160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson
48260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson
4830a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan    public EventInfoFragment(Context context, long eventId, long startMillis, long endMillis,
4847ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            int attendeeResponse, boolean isDialog, int windowStyle) {
4850a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan        this(context, ContentUris.withAppendedId(Events.CONTENT_URI, eventId), startMillis,
4867ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                endMillis, attendeeResponse, isDialog, windowStyle);
4874003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mEventId = eventId;
4884003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
4894003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
49071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    @Override
49171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    public void onActivityCreated(Bundle savedInstanceState) {
49271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        super.onActivityCreated(savedInstanceState);
49371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
4948b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik        mReminderChangeListener = new OnItemSelectedListener() {
4958b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            @Override
4968b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
4978b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                Integer prevValue = (Integer) parent.getTag();
4988b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                if (prevValue == null || prevValue != position) {
4998b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    parent.setTag(position);
5008b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mUserModifiedReminders = true;
5018b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                }
5028b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            }
5038b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik
5048b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            @Override
5058b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            public void onNothingSelected(AdapterView<?> parent) {
5068b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                // do nothing
5078b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            }
5088b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik
5098b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik        };
5108b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik
51171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        if (savedInstanceState != null) {
51271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan            mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false);
5137ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            mWindowStyle = savedInstanceState.getInt(BUNDLE_KEY_WINDOW_STYLE,
5147ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                    DIALOG_WINDOW_STYLE);
51571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        }
51671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
51771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        if (mIsDialog) {
51871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan            applyDialogParams();
51971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        }
520825b8ca1ea39c0da4620f5aaaeeb1fa40e7e8efdMichael Chan        mContext = getActivity();
52171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    }
52271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
52371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private void applyDialogParams() {
52471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        Dialog dialog = getDialog();
52571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        dialog.setCanceledOnTouchOutside(true);
52671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
52771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        Window window = dialog.getWindow();
52871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
52971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
53071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        WindowManager.LayoutParams a = window.getAttributes();
53171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        a.dimAmount = .4f;
53271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
5337ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        a.width = mDialogWidth;
5347ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        a.height = mDialogHeight;
53571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
5360b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson
5370b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson        // On tablets , do smart positioning of dialog
5380b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson        // On phones , use the whole screen
5390b1bd10dbf90e55821a555c68a8a444854e31252Isaac Katzenelson
54060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        if (mX != -1 || mY != -1) {
5417ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            a.x = mX - mDialogWidth / 2;
5427ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            a.y = mY - mDialogHeight / 2;
5430aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson            if (a.y < mMinTop) {
5440aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson                a.y = mMinTop + DIALOG_TOP_MARGIN;
5450a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan            }
54660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson            a.gravity = Gravity.LEFT | Gravity.TOP;
54771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        }
54871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        window.setAttributes(a);
54971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    }
55071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
5510aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson    public void setDialogParams(int x, int y, int minTop) {
55271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        mX = x;
55371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        mY = y;
5540aa0c61fcd2464f034d15f33db265b6d080f4af9Isaac Katzenelson        mMinTop = minTop;
55571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    }
55671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
557f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    // Implements OnCheckedChangeListener
558f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    @Override
559f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    public void onCheckedChanged(RadioGroup group, int checkedId) {
5602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If this is not a repeating event, then don't display the dialog
5612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // asking which events to change.
5625afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik        mUserSetResponse = getResponseFromButtonId(checkedId);
5632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (!mIsRepeating) {
5642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
5652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If the selection is the same as the original, then don't display the
5682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // dialog asking which events to change.
569f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        if (checkedId == findButtonIdForResponse(mOriginalAttendeeResponse)) {
5702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
5712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // This is a repeating event. We need to ask the user if they mean to
5742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // change just this one instance or all instances.
5752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEditResponseHelper.showDialog(mEditResponseHelper.getWhichEvents());
5762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onNothingSelected(AdapterView<?> parent) {
5792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
5822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onAttach(Activity activity) {
5832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        super.onAttach(activity);
58410b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson        mActivity = activity;
5852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEditResponseHelper = new EditResponseHelper(activity);
58686550ce5323f7e3971977702fca259986c048bf6RoboErik
58786550ce5323f7e3971977702fca259986c048bf6RoboErik        if (mAttendeeResponseFromIntent != Attendees.ATTENDEE_STATUS_NONE) {
58886550ce5323f7e3971977702fca259986c048bf6RoboErik            mEditResponseHelper.setWhichEvents(UPDATE_ALL);
58986550ce5323f7e3971977702fca259986c048bf6RoboErik        }
5902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler = new QueryHandler(activity);
59160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        mDescLineNum = activity.getResources().getInteger((R.integer.event_info_desc_line_num));
59260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        mMoreLabel = activity.getResources().getString((R.string.event_info_desc_more));
59360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        mLessLabel = activity.getResources().getString((R.string.event_info_desc_less));
59460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        if (!mIsDialog) {
59560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson            setHasOptionsMenu(true);
59660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        }
5972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
6002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public View onCreateView(LayoutInflater inflater, ViewGroup container,
6012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            Bundle savedInstanceState) {
602320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson
603320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson        if (savedInstanceState != null) {
604320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson            mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false);
605320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson            mWindowStyle = savedInstanceState.getInt(BUNDLE_KEY_WINDOW_STYLE,
606320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson                    DIALOG_WINDOW_STYLE);
607320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson            mDeleteDialogVisible =
608320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson                savedInstanceState.getBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE,false);
609320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson
610320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson        }
611320c1b11a8238ef299a401655d1ae06ffad45a47Isaac Katzenelson
6127ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        if (mWindowStyle == DIALOG_WINDOW_STYLE) {
613cba7f1fd22e1d7ee9d8d0828f37bc08512bf6b75Michael Chan            mView = inflater.inflate(R.layout.event_info_dialog, container, false);
6147ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        } else {
6157ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            mView = inflater.inflate(R.layout.event_info, container, false);
6167ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        }
6171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mScrollView = (ScrollView) mView.findViewById(R.id.event_info_scroll_view);
618259b8f9a21fffd3858218581e9daaf689b6b888fErik        mTitle = (TextView) mView.findViewById(R.id.title);
619aeae98bf8f8c5c544f65f5b6b7f29cfd31366ad5Michael Chan        mWhenDate = (TextView) mView.findViewById(R.id.when_date);
620aeae98bf8f8c5c544f65f5b6b7f29cfd31366ad5Michael Chan        mWhenTime = (TextView) mView.findViewById(R.id.when_time);
621259b8f9a21fffd3858218581e9daaf689b6b888fErik        mWhere = (TextView) mView.findViewById(R.id.where);
6222d2cc0a9604dfd803729a8f2be211e6800e9b410Michael Chan        mDesc = (TextView) mView.findViewById(R.id.description);
623fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        mHeadlines = mView.findViewById(R.id.event_info_headline);
624c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        mLongAttendees = (AttendeesView)mView.findViewById(R.id.long_attendee_list);
625c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        mDescButton = (Button)mView.findViewById(R.id.desc_expand);
626c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        mDescButton.setOnClickListener(new View.OnClickListener() {
627ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden            @Override
628c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson            public void onClick(View v) {
629c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson                mShowMaxDescription = !mShowMaxDescription;
630c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson                updateDescription();
631c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson            }
632c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        });
633c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        mShowMaxDescription = false; // Show short version of description as default.
63410b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson        mIsTabletConfig = Utils.getConfigBool(mActivity, R.bool.tablet_config);
6352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6364003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        if (mUri == null) {
6374003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            // restore event ID from bundle
6384003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mEventId = savedInstanceState.getLong(BUNDLE_KEY_EVENT_ID);
6394003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mUri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
6404003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mStartMillis = savedInstanceState.getLong(BUNDLE_KEY_START_MILLIS);
6414003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mEndMillis = savedInstanceState.getLong(BUNDLE_KEY_END_MILLIS);
6424003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
6434003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
6442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // start loading the data
6452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION,
6462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                null, null, null);
6472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
64889ad0822f104015625f4ca88bfdf5c1d522b6e74Erik        Button b = (Button) mView.findViewById(R.id.delete);
6498ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        b.setOnClickListener(new OnClickListener() {
6508ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            @Override
6518ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            public void onClick(View v) {
65269be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik                if (!mCanModifyCalendar) {
65369be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik                    return;
65469be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik                }
65586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper = new DeleteEventHelper(
656be2a432034e96c9f2fbf333cd7fe6489312bbeaaMichael Chan                        mContext, mActivity,
6571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                        !mIsDialog && !mIsTabletConfig /* exitWhenDone */);
65886ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper.setDeleteNotificationListener(EventInfoFragment.this);
65986ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener());
66086ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteDialogVisible = true;
66186ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable);
6628ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }});
6638ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
66410b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson        // Hide Edit/Delete buttons if in full screen mode on a phone
6657ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        if (!mIsDialog && !mIsTabletConfig || mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) {
66660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson            mView.findViewById(R.id.event_info_buttons_container).setVisibility(View.GONE);
66760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        }
66860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson
6691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Create a listener for the add reminder button
6701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
671b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan        View reminderAddButton = mView.findViewById(R.id.reminder_add);
6721ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        View.OnClickListener addReminderOnClickListener = new View.OnClickListener() {
6731ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            @Override
6741ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            public void onClick(View v) {
6751ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                addReminder();
6768b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                mUserModifiedReminders = true;
6771ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            }
6781ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        };
6791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        reminderAddButton.setOnClickListener(addReminderOnClickListener);
6801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
6811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Set reminders variables
6821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
6831ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity);
6841ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        String defaultReminderString = prefs.getString(
6851ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING);
6861ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mDefaultReminderMinutes = Integer.parseInt(defaultReminderString);
6871ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        prepareReminders();
6881ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
6892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return mView;
6902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
6912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
69289ad0822f104015625f4ca88bfdf5c1d522b6e74Erik    private Runnable onDeleteRunnable = new Runnable() {
69389ad0822f104015625f4ca88bfdf5c1d522b6e74Erik        @Override
69489ad0822f104015625f4ca88bfdf5c1d522b6e74Erik        public void run() {
6957c6236d5553dc9f3d004ebbed794249713a11d19RoboErik            if (EventInfoFragment.this.mIsPaused) {
6967c6236d5553dc9f3d004ebbed794249713a11d19RoboErik                mDismissOnResume = true;
6977c6236d5553dc9f3d004ebbed794249713a11d19RoboErik                return;
6987c6236d5553dc9f3d004ebbed794249713a11d19RoboErik            }
69989ad0822f104015625f4ca88bfdf5c1d522b6e74Erik            if (EventInfoFragment.this.isVisible()) {
70089ad0822f104015625f4ca88bfdf5c1d522b6e74Erik                EventInfoFragment.this.dismiss();
70189ad0822f104015625f4ca88bfdf5c1d522b6e74Erik            }
70289ad0822f104015625f4ca88bfdf5c1d522b6e74Erik        }
70389ad0822f104015625f4ca88bfdf5c1d522b6e74Erik    };
70489ad0822f104015625f4ca88bfdf5c1d522b6e74Erik
705c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    // Sets the description:
706c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    // Set the expand/collapse button
707c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    // Expand/collapse the description according the the current status
708c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    private void updateDescription() {
709d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        // If there is no description, hide the description field
710d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        // and desc button.
711d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        String text = mDesc.getText().toString();
712d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        if (TextUtils.isEmpty(text) || TextUtils.isEmpty(text.trim())) {
713d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira            mDesc.setVisibility(View.GONE);
714d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira            mDescButton.setVisibility(View.GONE);
715d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira            return;
716d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        }
7174ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan        // getLineCount() returns at most maxLines worth of text. If we have
7184ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan        // less than mDescLineNum lines, we know for sure we don't need the
719d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        // more/less button and we don't need to recalculate the number of
720d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        // lines.
721d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira
722d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira        mDesc.setVisibility(View.VISIBLE);
723d5e0803e1e21447577ba80fe4d396ee27b331daaMindy Pereira
724da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        if (mDesc.getLineCount() < mDescLineNum) {
725da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan            mDescButton.setVisibility(View.GONE);
726da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan            return;
727da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        }
728da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan
7294ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan        // getLineCount() returns at most maxLines worth of text. To
7304ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan        // recalculate, set to MAX_VALUE.
731da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        mDesc.setMaxLines(Integer.MAX_VALUE);
7324ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan
7334ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan        // Trick to get textview to recalculate line count
734da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        mDesc.setText(mDesc.getText());
735da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan
7364ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan        // Description is exactly mDescLineNum lines (or less).
7372d2cc0a9604dfd803729a8f2be211e6800e9b410Michael Chan        if (mDesc.getLineCount() <= mDescLineNum) {
738c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson            mDescButton.setVisibility(View.GONE);
739c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson            return;
740c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        }
7414ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan
742c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        // Show button and set label according to the expand/collapse status
743c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        mDescButton.setVisibility(View.VISIBLE);
744da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        String moreLessLabel;
745c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        if (mShowMaxDescription) {
746da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan            moreLessLabel = mLessLabel;
747c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        } else {
748da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan            moreLessLabel = mMoreLabel;
7494ee6b8082bf9eeb1d12ee74bd8565ff7eae79d2cMichael Chan            mDesc.setMaxLines(mDescLineNum);
750c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson        }
751da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan
752da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        mDescButton.setText(moreLessLabel);
753c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson    }
754c0624ee90e59386b06a01b3415d0bb4e38f40db7Isaac Katzenelson
7552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateTitle() {
7562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Resources res = getActivity().getResources();
7572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mCanModifyCalendar && !mIsOrganizer) {
7582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            getActivity().setTitle(res.getString(R.string.event_info_title_invite));
7592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
7602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            getActivity().setTitle(res.getString(R.string.event_info_title));
7612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
7622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
7632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
7652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Initializes the event cursor, which is expected to point to the first
7662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * (and only) result from a query.
7672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * @return true if the cursor is empty.
7682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
7692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean initEventCursor() {
7702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if ((mEventCursor == null) || (mEventCursor.getCount() == 0)) {
7712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return true;
7722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
7732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEventCursor.moveToFirst();
7742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEventId = mEventCursor.getInt(EVENT_INDEX_ID);
7752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
77666b2067e0a389180f909eb0a528bea5f6becca23Michael Chan        mIsRepeating = !TextUtils.isEmpty(rRule);
7771ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mHasAlarm = (mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) == 1)?true:false;
7781ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mMaxReminders = mEventCursor.getInt(EVENT_INDEX_MAX_REMINDERS);
7791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mCalendarAllowedReminders =  mEventCursor.getString(EVENT_INDEX_ALLOWED_REMINDERS);
7802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return false;
7812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
7822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @SuppressWarnings("fallthrough")
7842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void initAttendeesCursor(View view) {
785deced8999da73effe4133e2317c262fea7910090Michael Chan        mOriginalAttendeeResponse = CalendarController.ATTENDEE_NO_RESPONSE;
786d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE;
7872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mNumOfAttendees = 0;
7882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mAttendeesCursor != null) {
7892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mNumOfAttendees = mAttendeesCursor.getCount();
7902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (mAttendeesCursor.moveToFirst()) {
7912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mAcceptedAttendees.clear();
7922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mDeclinedAttendees.clear();
7932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mTentativeAttendees.clear();
7942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mNoResponseAttendees.clear();
7952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                do {
7972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    int status = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS);
7982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    String name = mAttendeesCursor.getString(ATTENDEES_INDEX_NAME);
7992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    String email = mAttendeesCursor.getString(ATTENDEES_INDEX_EMAIL);
8002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
801d845fbe558d5229102b58cce70a1b29fe6cb6967Erik                    if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE &&
8022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            mCalendarOwnerAccount.equalsIgnoreCase(email)) {
8032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        mCalendarOwnerAttendeeId = mAttendeesCursor.getInt(ATTENDEES_INDEX_ID);
8042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        mOriginalAttendeeResponse = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS);
8052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    } else {
8062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        // Don't show your own status in the list because:
8072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        //  1) it doesn't make sense for event without other guests.
8082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        //  2) there's a spinner for that for events with guests.
8092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        switch(status) {
8102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            case Attendees.ATTENDEE_STATUS_ACCEPTED:
811fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                mAcceptedAttendees.add(new Attendee(name, email,
812fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                        Attendees.ATTENDEE_STATUS_ACCEPTED));
8132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                break;
8142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            case Attendees.ATTENDEE_STATUS_DECLINED:
815fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                mDeclinedAttendees.add(new Attendee(name, email,
816fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                        Attendees.ATTENDEE_STATUS_DECLINED));
8172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                break;
8188ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                            case Attendees.ATTENDEE_STATUS_TENTATIVE:
819fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                mTentativeAttendees.add(new Attendee(name, email,
820fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                        Attendees.ATTENDEE_STATUS_TENTATIVE));
8218ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                                break;
8228ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                            default:
823fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                mNoResponseAttendees.add(new Attendee(name, email,
824fe25c502fa0822a57201c7be8b00f0f26b22a385Isaac Katzenelson                                        Attendees.ATTENDEE_STATUS_NONE));
8252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        }
8262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    }
8272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                } while (mAttendeesCursor.moveToNext());
8282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mAttendeesCursor.moveToFirst();
8292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateAttendees(view);
8312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
8322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
8332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
8342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
8364003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void onSaveInstanceState(Bundle outState) {
8374003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        super.onSaveInstanceState(outState);
8384003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_EVENT_ID, mEventId);
8394003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_START_MILLIS, mStartMillis);
8404003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_END_MILLIS, mEndMillis);
84171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        outState.putBoolean(BUNDLE_KEY_IS_DIALOG, mIsDialog);
8427ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        outState.putInt(BUNDLE_KEY_WINDOW_STYLE, mWindowStyle);
84386ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        outState.putBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE, mDeleteDialogVisible);
84460f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        outState.putInt(BUNDLE_KEY_ATTENDEE_RESPONSE, mAttendeeResponseFromIntent);
84560f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    }
84660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson
84760f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson
84860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    @Override
84960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
85060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        super.onCreateOptionsMenu(menu, inflater);
8517ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        // Show edit/delete buttons only in non-dialog configuration
8527ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        if (!mIsDialog && !mIsTabletConfig || mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) {
85360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson            inflater.inflate(R.menu.event_info_title_bar, menu);
854d8353fb85ef59a88580125207be9c914a8586758RoboErik            mMenu = menu;
855d8353fb85ef59a88580125207be9c914a8586758RoboErik            updateMenu();
85660f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        }
8574003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
8584003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
859d8353fb85ef59a88580125207be9c914a8586758RoboErik    @Override
860d8353fb85ef59a88580125207be9c914a8586758RoboErik    public boolean onOptionsItemSelected(MenuItem item) {
861d8353fb85ef59a88580125207be9c914a8586758RoboErik
8627ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        // If we're a dialog we don't want to handle menu buttons
8637ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson        if (mIsDialog) {
864d8353fb85ef59a88580125207be9c914a8586758RoboErik            return false;
865d8353fb85ef59a88580125207be9c914a8586758RoboErik        }
866d8353fb85ef59a88580125207be9c914a8586758RoboErik        // Handles option menu selections:
867d8353fb85ef59a88580125207be9c914a8586758RoboErik        // Home button - close event info activity and start the main calendar
868d8353fb85ef59a88580125207be9c914a8586758RoboErik        // one
869d8353fb85ef59a88580125207be9c914a8586758RoboErik        // Edit button - start the event edit activity and close the info
870d8353fb85ef59a88580125207be9c914a8586758RoboErik        // activity
871d8353fb85ef59a88580125207be9c914a8586758RoboErik        // Delete button - start a delete query that calls a runnable that close
872d8353fb85ef59a88580125207be9c914a8586758RoboErik        // the info activity
873d8353fb85ef59a88580125207be9c914a8586758RoboErik
874d8353fb85ef59a88580125207be9c914a8586758RoboErik        switch (item.getItemId()) {
875d8353fb85ef59a88580125207be9c914a8586758RoboErik            case android.R.id.home:
87615b4dcc873336ceb35fa335410b467aed3a834eaRoboErik                Utils.returnToCalendarHome(mContext);
877d8353fb85ef59a88580125207be9c914a8586758RoboErik                mActivity.finish();
878d8353fb85ef59a88580125207be9c914a8586758RoboErik                return true;
879d8353fb85ef59a88580125207be9c914a8586758RoboErik            case R.id.info_action_edit:
880d8353fb85ef59a88580125207be9c914a8586758RoboErik                Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
881d8353fb85ef59a88580125207be9c914a8586758RoboErik                Intent intent = new Intent(Intent.ACTION_EDIT, uri);
882d8353fb85ef59a88580125207be9c914a8586758RoboErik                intent.putExtra(EXTRA_EVENT_BEGIN_TIME, mStartMillis);
883d8353fb85ef59a88580125207be9c914a8586758RoboErik                intent.putExtra(EXTRA_EVENT_END_TIME, mEndMillis);
884d8353fb85ef59a88580125207be9c914a8586758RoboErik                intent.setClass(mActivity, EditEventActivity.class);
885d8353fb85ef59a88580125207be9c914a8586758RoboErik                intent.putExtra(EVENT_EDIT_ON_LAUNCH, true);
886d8353fb85ef59a88580125207be9c914a8586758RoboErik                startActivity(intent);
887d8353fb85ef59a88580125207be9c914a8586758RoboErik                mActivity.finish();
888d8353fb85ef59a88580125207be9c914a8586758RoboErik                break;
889d8353fb85ef59a88580125207be9c914a8586758RoboErik            case R.id.info_action_delete:
89086ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper =
891d8353fb85ef59a88580125207be9c914a8586758RoboErik                        new DeleteEventHelper(mActivity, mActivity, true /* exitWhenDone */);
89286ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper.setDeleteNotificationListener(EventInfoFragment.this);
89386ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener());
89486ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteDialogVisible = true;
89586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable);
896d8353fb85ef59a88580125207be9c914a8586758RoboErik                break;
897d8353fb85ef59a88580125207be9c914a8586758RoboErik            default:
898d8353fb85ef59a88580125207be9c914a8586758RoboErik                break;
899d8353fb85ef59a88580125207be9c914a8586758RoboErik        }
900d8353fb85ef59a88580125207be9c914a8586758RoboErik        return super.onOptionsItemSelected(item);
901d8353fb85ef59a88580125207be9c914a8586758RoboErik    }
9024003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
9034003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    @Override
9044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void onDestroyView() {
905b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson        if (!mEventDeletionStarted) {
906b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson            if (saveResponse() || saveReminders()) {
907b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson                Toast.makeText(getActivity(), R.string.saving_event, Toast.LENGTH_SHORT).show();
908b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson            }
9092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9104003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        super.onDestroyView();
9112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
9142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onDestroy() {
9152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mEventCursor != null) {
9162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mEventCursor.close();
9172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mCalendarsCursor != null) {
9192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCalendarsCursor.close();
9202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mAttendeesCursor != null) {
9222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mAttendeesCursor.close();
9232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
92471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        super.onDestroy();
9252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
9282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Asynchronously saves the response to an invitation if the user changed
9292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * the response. Returns true if the database will be updated.
9302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     *
9312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * @return true if the database will be changed
9322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
9332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean saveResponse() {
9342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mAttendeesCursor == null || mEventCursor == null) {
9352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
9362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
937f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan
938f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        RadioGroup radioGroup = (RadioGroup) getView().findViewById(R.id.response_value);
939f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        int status = getResponseFromButtonId(radioGroup.getCheckedRadioButtonId());
940f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        if (status == Attendees.ATTENDEE_STATUS_NONE) {
9412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
9422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If the status has not changed, then don't update the database
9452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (status == mOriginalAttendeeResponse) {
9462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
9472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If we never got an owner attendee id we can't set the status
950d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE) {
9512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
9522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (!mIsRepeating) {
9552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // This is a non-repeating event
9562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            updateResponse(mEventId, mCalendarOwnerAttendeeId, status);
9572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return true;
9582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // This is a repeating event
9612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        int whichEvents = mEditResponseHelper.getWhichEvents();
9622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        switch (whichEvents) {
9632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case -1:
9642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return false;
9652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case UPDATE_SINGLE:
966c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden                createExceptionResponse(mEventId, status);
9672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return true;
9682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case UPDATE_ALL:
9692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateResponse(mEventId, mCalendarOwnerAttendeeId, status);
9702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return true;
9712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            default:
9722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Log.e(TAG, "Unexpected choice for updating invitation response");
9732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
9742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return false;
9762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateResponse(long eventId, long attendeeId, int status) {
9792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Update the attendee status in the attendees table.  the provider
9802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // takes care of updating the self attendance status.
9812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        ContentValues values = new ContentValues();
9822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (!TextUtils.isEmpty(mCalendarOwnerAccount)) {
9842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            values.put(Attendees.ATTENDEE_EMAIL, mCalendarOwnerAccount);
9852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Attendees.ATTENDEE_STATUS, status);
9872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Attendees.EVENT_ID, eventId);
9882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Uri uri = ContentUris.withAppendedId(Attendees.CONTENT_URI, attendeeId);
9902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler.startUpdate(mHandler.getNextToken(), null, uri, values,
9922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                null, null, Utils.UNDO_DELAY);
9932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
995c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden    /**
996c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     * Creates an exception to a recurring event.  The only change we're making is to the
997c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     * "self attendee status" value.  The provider will take care of updating the corresponding
998c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     * Attendees.attendeeStatus entry.
999c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     *
1000c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     * @param eventId The recurring event.
1001c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     * @param status The new value for selfAttendeeStatus.
1002c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden     */
1003c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden    private void createExceptionResponse(long eventId, int status) {
10042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        ContentValues values = new ContentValues();
10052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis);
10062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.SELF_ATTENDEE_STATUS, status);
1007c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden        values.put(Events.STATUS, Events.STATUS_CONFIRMED);
10082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1009364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erik        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
101079b2c8c946c29ea9107957fe72a9fa9f560da345Andy McFadden        Uri exceptionUri = Uri.withAppendedPath(Events.CONTENT_EXCEPTION_URI,
1011c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden                String.valueOf(eventId));
1012c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden        ops.add(ContentProviderOperation.newInsert(exceptionUri).withValues(values).build());
1013364309f0bb9c3aeee8efd0c24faf478f7c62c6d7Erik
1014c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden        mHandler.startBatch(mHandler.getNextToken(), null, CalendarContract.AUTHORITY, ops,
1015c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden                Utils.UNDO_DELAY);
1016c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden   }
10172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1018f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    public static int getResponseFromButtonId(int buttonId) {
1019f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        int response;
1020f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        switch (buttonId) {
1021f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            case R.id.response_yes:
1022f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                response = Attendees.ATTENDEE_STATUS_ACCEPTED;
1023f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                break;
1024f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            case R.id.response_maybe:
1025f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                response = Attendees.ATTENDEE_STATUS_TENTATIVE;
1026f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                break;
1027f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            case R.id.response_no:
1028f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                response = Attendees.ATTENDEE_STATUS_DECLINED;
1029f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                break;
1030f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            default:
1031f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                response = Attendees.ATTENDEE_STATUS_NONE;
10322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
1033f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        return response;
1034f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    }
1035f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan
1036f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    public static int findButtonIdForResponse(int response) {
1037f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        int buttonId;
1038f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        switch (response) {
1039f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            case Attendees.ATTENDEE_STATUS_ACCEPTED:
1040f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                buttonId = R.id.response_yes;
1041f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                break;
1042f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            case Attendees.ATTENDEE_STATUS_TENTATIVE:
1043f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                buttonId = R.id.response_maybe;
1044f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                break;
1045f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            case Attendees.ATTENDEE_STATUS_DECLINED:
1046f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                buttonId = R.id.response_no;
1047f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                break;
1048f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                default:
1049f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                    buttonId = -1;
1050f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        }
1051f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        return buttonId;
10522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
10532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void doEdit() {
1055c41b99be504e395b8c7264a0d626906ccbff1c57Erik        Context c = getActivity();
1056c41b99be504e395b8c7264a0d626906ccbff1c57Erik        // This ensures that we aren't in the process of closing and have been
1057c41b99be504e395b8c7264a0d626906ccbff1c57Erik        // unattached already
1058c41b99be504e395b8c7264a0d626906ccbff1c57Erik        if (c != null) {
1059c41b99be504e395b8c7264a0d626906ccbff1c57Erik            CalendarController.getInstance(c).sendEventRelatedEvent(
106061bf59383cc3d38ef0447635ed65ab986796d7deMichael Chan                    this, EventType.EDIT_EVENT, mEventId, mStartMillis, mEndMillis, 0
106160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                    , 0, -1);
1062c41b99be504e395b8c7264a0d626906ccbff1c57Erik        }
10632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
10642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateEvent(View view) {
1066b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson        if (mEventCursor == null || view == null) {
10672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
10682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
10692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String eventName = mEventCursor.getString(EVENT_INDEX_TITLE);
10712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (eventName == null || eventName.length() == 0) {
10722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            eventName = getActivity().getString(R.string.no_title_label);
10732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
10742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
10762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION);
10772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION);
10782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
1079f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson        String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
10802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10814acb2fd087308dea146b8b10f5278c59df387680RoboErik        mColor = Utils.getDisplayColorFromColor(mEventCursor.getInt(EVENT_INDEX_COLOR));
1082fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        mHeadlines.setBackgroundColor(mColor);
10832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // What
10852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (eventName != null) {
10862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setTextCommon(view, R.id.title, eventName);
10872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
10882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
10892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // When
1090fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        // Set the date and repeats (if any)
109174c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson        String whenDate;
109274c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson        int flagsTime = DateUtils.FORMAT_SHOW_TIME;
109374c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson        int flagsDate = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY |
109474c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson                DateUtils.FORMAT_SHOW_YEAR;
109574c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson
109674c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson        if (DateFormat.is24HourFormat(getActivity())) {
109774c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson            flagsTime |= DateUtils.FORMAT_24HOUR;
109874c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson        }
1099fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson
1100fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        // Put repeat after the date (if any)
1101fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        String repeatString = null;
1102fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        if (!TextUtils.isEmpty(rRule)) {
1103fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            EventRecurrence eventRecurrence = new EventRecurrence();
1104fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            eventRecurrence.parse(rRule);
1105fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            Time date = new Time(Utils.getTimeZone(getActivity(), mTZUpdater));
1106fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            if (allDay) {
1107fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                date.timezone = Time.TIMEZONE_UTC;
1108fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            }
1109fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            date.set(mStartMillis);
1110fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            eventRecurrence.setStartDate(date);
1111fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            repeatString = EventRecurrenceFormatter.getRepeatString(
1112fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                    getActivity().getResources(), eventRecurrence);
1113fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        }
1114fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        // If an all day event , show the date without the time
11152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (allDay) {
111674c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson            Formatter f = new Formatter(new StringBuilder(50), Locale.getDefault());
111717dae9170b03408caf7ce23baa755b7a8c31b404Michael Chan            whenDate = DateUtils.formatDateRange(getActivity(), f, mStartMillis, mEndMillis,
111874c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson                    flagsDate, Time.TIMEZONE_UTC).toString();
1119fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            if (repeatString != null) {
1120fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                setTextCommon(view, R.id.when_date, whenDate + " (" + repeatString + ")");
1121fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            } else {
1122fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                setTextCommon(view, R.id.when_date, whenDate);
1123fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            }
112474c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson            view.findViewById(R.id.when_time).setVisibility(View.GONE);
112574c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson
11262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
1127fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            // Show date for none all-day events
112874c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson            whenDate = Utils.formatDateRange(getActivity(), mStartMillis, mEndMillis, flagsDate);
112974c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson            String whenTime = Utils.formatDateRange(getActivity(), mStartMillis, mEndMillis,
113074c90321e327fc97aa06ff893f5265661555deb1Isaac Katzenelson                    flagsTime);
1131fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            if (repeatString != null) {
1132fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                setTextCommon(view, R.id.when_date, whenDate + " (" + repeatString + ")");
1133f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson            } else {
1134fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                setTextCommon(view, R.id.when_date, whenDate);
1135f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson            }
1136f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson
1137fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            // Show the event timezone if it is different from the local timezone after the time
11381121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik            String localTimezone = Utils.getTimeZone(mActivity, mTZUpdater);
11391121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik            if (!TextUtils.equals(localTimezone, eventTimezone)) {
1140fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                String displayName;
11411121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                // Figure out if this is in DST
11421121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                Time date = new Time(Utils.getTimeZone(getActivity(), mTZUpdater));
11431121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                if (allDay) {
11441121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                    date.timezone = Time.TIMEZONE_UTC;
11451121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                }
11461121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                date.set(mStartMillis);
11471121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik
11481121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                TimeZone tz = TimeZone.getTimeZone(localTimezone);
1149fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                if (tz == null || tz.getID().equals("GMT")) {
1150fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                    displayName = localTimezone;
1151fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                } else {
11521121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik                    displayName = tz.getDisplayName(date.isDst != 0, TimeZone.LONG);
1153fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                }
1154fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                setTextCommon(view, R.id.when_time, whenTime + " (" + displayName + ")");
1155fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            }
1156fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            else {
1157fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                setTextCommon(view, R.id.when_time, whenTime);
1158fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            }
1159f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson        }
1160f6f797769a5cac9f9796574fe6c5ca767b1c269aIsaac Katzenelson
1161fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson
11622e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson        // Organizer view is setup in the updateCalendar method
11632e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson
11642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
11652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Where
1166ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan        if (location == null || location.trim().length() == 0) {
11672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setVisibilityCommon(view, R.id.where, View.GONE);
11682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
1169259b8f9a21fffd3858218581e9daaf689b6b888fErik            final TextView textView = mWhere;
11702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (textView != null) {
1171ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                textView.setAutoLinkMask(0);
1172ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                textView.setText(location.trim());
117373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                linkifyTextView(textView);
117473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
1175ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                textView.setOnTouchListener(new OnTouchListener() {
1176c928e3d4ce097389b59eea82a5ca9827a44a8c9cAndy McFadden                    @Override
1177ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                    public boolean onTouch(View v, MotionEvent event) {
1178ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                        try {
1179ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                            return v.onTouchEvent(event);
1180ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                        } catch (ActivityNotFoundException e) {
1181ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                            // ignore
1182ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                            return true;
11832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        }
1184ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                    }
1185ddfb59d54494c97c0c0b5326821a9594b1fe8896Michael Chan                });
11862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
11872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
11882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
11892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Description
1190352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        if (description != null && description.length() != 0) {
11912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setTextCommon(view, R.id.description, description);
11922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
1193da5ab4a059f67e9d75ecf6cc82eb203305f9df7aMichael Chan        updateDescription();  // Expand or collapse full description
11942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
11952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
119673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    /**
119773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     * Replaces stretches of text that look like addresses and phone numbers with clickable
119873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     * links.
119973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     * <p>
120073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     * This is really just an enhanced version of Linkify.addLinks().
120173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     */
120273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    private static void linkifyTextView(TextView textView) {
120373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        /*
120473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * If the text includes a street address like "1600 Amphitheater Parkway, 94043",
120573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * the current Linkify code will identify "94043" as a phone number and invite
120673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * you to dial it (and not provide a map link for the address).  We want to
120773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * have better recognition of phone numbers without losing any of the existing
120873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * annotations.
120973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         *
121073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Ideally this would be addressed by improving Linkify.  For now we manage it as
121173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * a second pass over the text.
121273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         *
121373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * URIs and e-mail addresses are pretty easy to pick out of text.  Phone numbers
121473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * are a bit tricky because they have radically different formats in different
121573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * countries, in terms of both the digits and the way in which they are commonly
121673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * written or presented (e.g. the punctuation and spaces in "(650) 555-1212").
121773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * The expected format of a street address is defined in WebView.findAddress().  It's
121873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * pretty narrowly defined, so it won't often match.
121973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         *
122073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * The RFC 3966 specification defines the format of a "tel:" URI.
122173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         */
122273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
122373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        /*
122473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Start by letting Linkify find anything that isn't a phone number.  We have to let it
122573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * run first because every invocation removes all previous URLSpan annotations.
122673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         */
122773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        boolean linkifyFoundLinks = Linkify.addLinks(textView,
122873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                Linkify.ALL & ~(Linkify.PHONE_NUMBERS));
122973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
123073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        /*
123173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Search for phone numbers.
123273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         *
123373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * The "leniency" value can be VALID or POSSIBLE.  With VALID we won't match NANP numbers
123473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * shorter than 10 digits, which is inconvenient.  With POSSIBLE we get NANP 7-digit
123573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * numbers, and possibly strings of digits inside URIs, but happily we don't flag
123673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * five-digit zip codes like Linkify does.
123773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         *
123873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Phone links inside URIs will be annotated by the earlier URI linkification, so we just
123973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * need to avoid creating overlapping spans.
124073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         */
124173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        String defaultPhoneRegion = System.getProperty("user.region", "US");
124273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
124373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        CharSequence text = textView.getText();
124473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        Iterable<PhoneNumberMatch> phoneIterable = phoneUtil.findNumbers(text, defaultPhoneRegion,
124573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                PhoneNumberUtil.Leniency.POSSIBLE, Long.MAX_VALUE);
124673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
124773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        /*
124873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * If the contents of the TextView are already Spannable (which will be the case if
124973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Linkify found stuff, but might not be otherwise), we can just add annotations
125073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * to what's there.  If it's not, and we find phone numbers, we need to convert it to
125173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * a Spannable form.  (This mimics the behavior of Linkable.addLinks().)
125273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         */
125373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        Spannable spanText;
125473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        if (text instanceof SpannableString) {
125573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            spanText = (SpannableString) text;
125673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        } else {
125773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            spanText = SpannableString.valueOf(text);
125873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        }
125973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
126073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        /*
126173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Get a list of any spans created by Linkify, for the overlapping span check.
126273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         */
126373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
126473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
126573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        /*
126673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         * Insert spans for the numbers we found.  We generate "tel:" URIs.
126773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden         */
126873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        int phoneCount = 0;
126973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        for (PhoneNumberMatch match : phoneIterable) {
127073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            int start = match.start();
127173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            int end = match.end();
127273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
127373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            if (spanWillOverlap(spanText, existingSpans, start, end)) {
127473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                if (Log.isLoggable(TAG, Log.VERBOSE)) {
127573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                    Log.v(TAG, "Not linkifying " + match.number().getNationalNumber() +
127673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                            " as phone number due to overlap");
127773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                }
127873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                continue;
127973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            }
128073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
128173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            /*
128273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * A quick comparison of PhoneNumberUtil number parsing & formatting, with
128373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * defaultRegion="US":
128473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             *
128573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * Input string     RFC3966                     NATIONAL
128673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * 5551212          +1-5551212                  555-1212
128773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * 6505551212       +1-650-555-1212             (650) 555-1212
128873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * 6505551212x123   +1-650-555-1212;ext=123     (650) 555-1212 ext. 123
128973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * +41446681800     +41-44-668-18-00            044 668 18 00
129073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             *
129173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * The conversion of NANP 7-digit numbers to RFC3966 is not compatible with our dialer
129273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * (which tries to dial 8 digits, and fails).  So that won't work.
129373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             *
129473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * The conversion of the Swiss number to NATIONAL format loses the country code,
129573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * so that won't work.
129673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             *
129773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * The Linkify code takes the matching span and strips out everything that isn't a
129873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * digit or '+' sign.  We do the same here.  Extension numbers will get appended
129973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * without a separator, but the dialer wasn't doing anything useful with ";ext="
130073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             * anyway.
130173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden             */
130273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
130373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            //String dialStr = phoneUtil.format(match.number(),
130473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            //        PhoneNumberUtil.PhoneNumberFormat.RFC3966);
130573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            StringBuilder dialBuilder = new StringBuilder();
130673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            for (int i = start; i < end; i++) {
130773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                char ch = spanText.charAt(i);
130873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                if (ch == '+' || Character.isDigit(ch)) {
130973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                    dialBuilder.append(ch);
131073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                }
131173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            }
131273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            URLSpan span = new URLSpan("tel:" + dialBuilder.toString());
131373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
131473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
131573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            phoneCount++;
131673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        }
131773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
131873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        if (phoneCount != 0) {
131973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            // If we had to "upgrade" to Spannable, store the object into the TextView.
132073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            if (spanText != text) {
132173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                textView.setText(spanText);
132273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            }
132373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
132473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            // Linkify.addLinks() sets the TextView movement method if it finds any links.  We
132573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            // want to do the same here.  (This is cloned from Linkify.addLinkMovementMethod().)
132673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            MovementMethod mm = textView.getMovementMethod();
132773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
132873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            if ((mm == null) || !(mm instanceof LinkMovementMethod)) {
132973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                if (textView.getLinksClickable()) {
133073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                    textView.setMovementMethod(LinkMovementMethod.getInstance());
133173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                }
133273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            }
133373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        }
133473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
133573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        if (!linkifyFoundLinks && phoneCount == 0) {
133673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            if (Log.isLoggable(TAG, Log.VERBOSE)) {
133773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                Log.v(TAG, "No linkification matches, using geo default");
133873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            }
133973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q=");
134073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        }
134173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    }
134273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
134373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    /**
134473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     * Determines whether a new span at [start,end) will overlap with any existing span.
134573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden     */
134673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    private static boolean spanWillOverlap(Spannable spanText, URLSpan[] spanList, int start,
134773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            int end) {
134873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        if (start == end) {
134973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            // empty span, ignore
135073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            return false;
135173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        }
135273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        for (URLSpan span : spanList) {
135373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            int existingStart = spanText.getSpanStart(span);
135473b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            int existingEnd = spanText.getSpanEnd(span);
135573b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            if ((start >= existingStart && start < existingEnd) ||
135673b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                    end > existingStart && end <= existingEnd) {
135773b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden                return true;
135873b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden            }
135973b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        }
136073b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
136173b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden        return false;
136273b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden    }
136373b07655afcea1ba2ce8ed580a50992bf0baf857Andy McFadden
1364259b8f9a21fffd3858218581e9daaf689b6b888fErik    private void sendAccessibilityEvent() {
1365ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden        AccessibilityManager am =
1366ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden            (AccessibilityManager) getActivity().getSystemService(Service.ACCESSIBILITY_SERVICE);
1367259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (!am.isEnabled()) {
1368259b8f9a21fffd3858218581e9daaf689b6b888fErik            return;
1369259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
1370259b8f9a21fffd3858218581e9daaf689b6b888fErik
1371259b8f9a21fffd3858218581e9daaf689b6b888fErik        AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED);
1372259b8f9a21fffd3858218581e9daaf689b6b888fErik        event.setClassName(getClass().getName());
1373259b8f9a21fffd3858218581e9daaf689b6b888fErik        event.setPackageName(getActivity().getPackageName());
1374259b8f9a21fffd3858218581e9daaf689b6b888fErik        List<CharSequence> text = event.getText();
1375259b8f9a21fffd3858218581e9daaf689b6b888fErik
1376259b8f9a21fffd3858218581e9daaf689b6b888fErik        addFieldToAccessibilityEvent(text, mTitle);
1377aeae98bf8f8c5c544f65f5b6b7f29cfd31366ad5Michael Chan        addFieldToAccessibilityEvent(text, mWhenDate);
1378aeae98bf8f8c5c544f65f5b6b7f29cfd31366ad5Michael Chan        addFieldToAccessibilityEvent(text, mWhenTime);
1379259b8f9a21fffd3858218581e9daaf689b6b888fErik        addFieldToAccessibilityEvent(text, mWhere);
13802d2cc0a9604dfd803729a8f2be211e6800e9b410Michael Chan        addFieldToAccessibilityEvent(text, mDesc);
1381259b8f9a21fffd3858218581e9daaf689b6b888fErik
1382259b8f9a21fffd3858218581e9daaf689b6b888fErik        RadioGroup response = (RadioGroup) getView().findViewById(R.id.response_value);
1383259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (response.getVisibility() == View.VISIBLE) {
1384259b8f9a21fffd3858218581e9daaf689b6b888fErik            int id = response.getCheckedRadioButtonId();
1385259b8f9a21fffd3858218581e9daaf689b6b888fErik            if (id != View.NO_ID) {
1386259b8f9a21fffd3858218581e9daaf689b6b888fErik                text.add(((TextView) getView().findViewById(R.id.response_label)).getText());
1387259b8f9a21fffd3858218581e9daaf689b6b888fErik                text.add((((RadioButton) (response.findViewById(id))).getText() + PERIOD_SPACE));
1388259b8f9a21fffd3858218581e9daaf689b6b888fErik            }
1389259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
1390259b8f9a21fffd3858218581e9daaf689b6b888fErik
1391259b8f9a21fffd3858218581e9daaf689b6b888fErik        am.sendAccessibilityEvent(event);
1392259b8f9a21fffd3858218581e9daaf689b6b888fErik    }
1393259b8f9a21fffd3858218581e9daaf689b6b888fErik
1394259b8f9a21fffd3858218581e9daaf689b6b888fErik    /**
1395259b8f9a21fffd3858218581e9daaf689b6b888fErik     * @param text
1396259b8f9a21fffd3858218581e9daaf689b6b888fErik     */
1397259b8f9a21fffd3858218581e9daaf689b6b888fErik    private void addFieldToAccessibilityEvent(List<CharSequence> text, TextView view) {
13989ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson        if (view == null) {
13999ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson            return;
14009ceed1f3df98c5fc85441da0c6e7e5d45cf17a1eIsaac Katzenelson        }
1401b4c0150b7d6460bf44fca60aa38d355ab669adaaRoboErik        String str = view.getText().toString().trim();
1402259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (!TextUtils.isEmpty(str)) {
1403b4c0150b7d6460bf44fca60aa38d355ab669adaaRoboErik            text.add(str);
1404259b8f9a21fffd3858218581e9daaf689b6b888fErik            text.add(PERIOD_SPACE);
1405259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
1406259b8f9a21fffd3858218581e9daaf689b6b888fErik    }
1407259b8f9a21fffd3858218581e9daaf689b6b888fErik
14082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateCalendar(View view) {
14092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mCalendarOwnerAccount = "";
14102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mCalendarsCursor != null && mEventCursor != null) {
14112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCalendarsCursor.moveToFirst();
14122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String tempAccount = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT);
14132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCalendarOwnerAccount = (tempAccount == null) ? "" : tempAccount;
1414352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            mOwnerCanRespond = mCalendarsCursor.getInt(CALENDARS_INDEX_OWNER_CAN_RESPOND) != 0;
14152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
14162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String displayName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
14172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
14182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // start duplicate calendars query
14192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mHandler.startQuery(TOKEN_QUERY_DUPLICATE_CALENDARS, null, Calendars.CONTENT_URI,
14202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    CALENDARS_PROJECTION, CALENDARS_DUPLICATE_NAME_WHERE,
14212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    new String[] {displayName}, null);
14222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
14232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String eventOrganizer = mEventCursor.getString(EVENT_INDEX_ORGANIZER);
14242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mIsOrganizer = mCalendarOwnerAccount.equalsIgnoreCase(eventOrganizer);
14252e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson            setTextCommon(view, R.id.organizer, eventOrganizer);
1426b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson            if (!mIsOrganizer) {
1427b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson                setVisibilityCommon(view, R.id.organizer_container, View.VISIBLE);
1428b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson            } else {
1429b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson                setVisibilityCommon(view, R.id.organizer_container, View.GONE);
1430b7762cf45d4606916b54edca5f31fd225e4a2b03Isaac Katzenelson            }
14312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mHasAttendeeData = mEventCursor.getInt(EVENT_INDEX_HAS_ATTENDEE_DATA) != 0;
143265eeb79e62034d706503ce29d88c0e05ebd726feRoboErik            mCanModifyCalendar = mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL)
143365eeb79e62034d706503ce29d88c0e05ebd726feRoboErik                    >= Calendars.CAL_ACCESS_CONTRIBUTOR;
143465eeb79e62034d706503ce29d88c0e05ebd726feRoboErik            // TODO add "|| guestCanModify" after b/1299071 is fixed
143565eeb79e62034d706503ce29d88c0e05ebd726feRoboErik            mCanModifyEvent = mCanModifyCalendar && mIsOrganizer;
14362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mIsBusyFreeCalendar =
1437ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik                    mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) == Calendars.CAL_ACCESS_FREEBUSY;
1438352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
1439352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            if (!mIsBusyFreeCalendar) {
14408ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                Button b = (Button) mView.findViewById(R.id.edit);
1441352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                b.setEnabled(true);
14428ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                b.setOnClickListener(new OnClickListener() {
14438ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                    @Override
14448ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                    public void onClick(View v) {
14458ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        doEdit();
144610b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson                        // For dialogs, just close the fragment
144710b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson                        // For full screen, close activity on phone, leave it for tablet
144860f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                        if (mIsDialog) {
144960f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                            EventInfoFragment.this.dismiss();
145060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                        }
145110b60216d349641dd03eb65407807539b0b626dfIsaac Katzenelson                        else if (!mIsTabletConfig){
145260f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                            getActivity().finish();
145360f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                        }
1454352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    }
1455352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                });
14568ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }
1457dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira            View button;
1458dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira            if (!mCanModifyCalendar) {
1459dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                button = mView.findViewById(R.id.delete);
1460dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                if (button != null) {
1461dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                    button.setEnabled(false);
1462dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                    button.setVisibility(View.GONE);
146365eeb79e62034d706503ce29d88c0e05ebd726feRoboErik                }
1464dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira            }
1465dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira            if (!mCanModifyEvent) {
1466dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                button = mView.findViewById(R.id.edit);
1467dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                if (button != null) {
1468dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                    button.setEnabled(false);
1469dd15169500bc687107370366c3bbd8339bbcaa74Mindy Pereira                    button.setVisibility(View.GONE);
147060f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson                }
1471d8353fb85ef59a88580125207be9c914a8586758RoboErik            }
14727ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson            if ((!mIsDialog && !mIsTabletConfig ||
14737ef2981ab9ad32a6818b36cefbd39f070ba708edIsaac Katzenelson                    mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) && mMenu != null) {
1474d8353fb85ef59a88580125207be9c914a8586758RoboErik                mActivity.invalidateOptionsMenu();
147569be855eccf7d1e0a4c93377db66eb4b843a1403RoboErik            }
14762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
147771b221ae5d0f514352584a955630f5494f686c51Michael Chan            setVisibilityCommon(view, R.id.calendar, View.GONE);
1478259b8f9a21fffd3858218581e9daaf689b6b888fErik            sendAccessibilityEventIfQueryDone(TOKEN_QUERY_DUPLICATE_CALENDARS);
14792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
14802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
14812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1482d8353fb85ef59a88580125207be9c914a8586758RoboErik    /**
1483d8353fb85ef59a88580125207be9c914a8586758RoboErik     *
1484d8353fb85ef59a88580125207be9c914a8586758RoboErik     */
1485d8353fb85ef59a88580125207be9c914a8586758RoboErik    private void updateMenu() {
1486d8353fb85ef59a88580125207be9c914a8586758RoboErik        if (mMenu == null) {
1487d8353fb85ef59a88580125207be9c914a8586758RoboErik            return;
1488d8353fb85ef59a88580125207be9c914a8586758RoboErik        }
1489d8353fb85ef59a88580125207be9c914a8586758RoboErik        MenuItem delete = mMenu.findItem(R.id.info_action_delete);
1490d8353fb85ef59a88580125207be9c914a8586758RoboErik        MenuItem edit = mMenu.findItem(R.id.info_action_edit);
1491d8353fb85ef59a88580125207be9c914a8586758RoboErik        if (delete != null) {
1492d8353fb85ef59a88580125207be9c914a8586758RoboErik            delete.setVisible(mCanModifyCalendar);
1493d8353fb85ef59a88580125207be9c914a8586758RoboErik            delete.setEnabled(mCanModifyCalendar);
1494d8353fb85ef59a88580125207be9c914a8586758RoboErik        }
1495d8353fb85ef59a88580125207be9c914a8586758RoboErik        if (edit != null) {
149665eeb79e62034d706503ce29d88c0e05ebd726feRoboErik            edit.setVisible(mCanModifyEvent);
149765eeb79e62034d706503ce29d88c0e05ebd726feRoboErik            edit.setEnabled(mCanModifyEvent);
1498d8353fb85ef59a88580125207be9c914a8586758RoboErik        }
1499d8353fb85ef59a88580125207be9c914a8586758RoboErik    }
1500d8353fb85ef59a88580125207be9c914a8586758RoboErik
15012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateAttendees(View view) {
1502fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson        if (mAcceptedAttendees.size() + mDeclinedAttendees.size() +
1503fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson                mTentativeAttendees.size() + mNoResponseAttendees.size() > 0) {
1504c7f3c3896f1bc4cad43aa7f0bca1dee603704613RoboErik            mLongAttendees.clearAttendees();
15054acb2fd087308dea146b8b10f5278c59df387680RoboErik            (mLongAttendees).addAttendees(mAcceptedAttendees);
15064acb2fd087308dea146b8b10f5278c59df387680RoboErik            (mLongAttendees).addAttendees(mDeclinedAttendees);
15074acb2fd087308dea146b8b10f5278c59df387680RoboErik            (mLongAttendees).addAttendees(mTentativeAttendees);
15084acb2fd087308dea146b8b10f5278c59df387680RoboErik            (mLongAttendees).addAttendees(mNoResponseAttendees);
1509fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            mLongAttendees.setEnabled(false);
1510fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            mLongAttendees.setVisibility(View.VISIBLE);
151160f01c23282284e691fcd24918ea67087540f95dIsaac Katzenelson        } else {
1512fae6d5c17df988e957af421498124cf600ded523Isaac Katzenelson            mLongAttendees.setVisibility(View.GONE);
151371b221ae5d0f514352584a955630f5494f686c51Michael Chan        }
15148ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan    }
15158ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
15161ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    public void initReminders(View view, Cursor cursor) {
15171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
15181ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Add reminders
1519c7f3c3896f1bc4cad43aa7f0bca1dee603704613RoboErik        mOriginalReminders.clear();
1520c08957b48e755d34f1496d3937a24d60bdd24904RoboErik        mUnsupportedReminders.clear();
15211ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        while (cursor.moveToNext()) {
15221ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            int minutes = cursor.getInt(EditEventHelper.REMINDERS_INDEX_MINUTES);
15231ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            int method = cursor.getInt(EditEventHelper.REMINDERS_INDEX_METHOD);
1524e35a032c939f357ce435711b2fd8de1887a05011RoboErik
1525c08957b48e755d34f1496d3937a24d60bdd24904RoboErik            if (method != Reminders.METHOD_DEFAULT && !mReminderMethodValues.contains(method)) {
1526e35a032c939f357ce435711b2fd8de1887a05011RoboErik                // Stash unsupported reminder types separately so we don't alter
1527e35a032c939f357ce435711b2fd8de1887a05011RoboErik                // them in the UI
1528e35a032c939f357ce435711b2fd8de1887a05011RoboErik                mUnsupportedReminders.add(ReminderEntry.valueOf(minutes, method));
1529e35a032c939f357ce435711b2fd8de1887a05011RoboErik            } else {
1530e35a032c939f357ce435711b2fd8de1887a05011RoboErik                mOriginalReminders.add(ReminderEntry.valueOf(minutes, method));
1531e35a032c939f357ce435711b2fd8de1887a05011RoboErik            }
15321ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        }
15331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Sort appropriately for display (by time, then type)
15341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Collections.sort(mOriginalReminders);
15351ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
15368b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik        if (mUserModifiedReminders) {
15378b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            // If the user has changed the list of reminders don't change what's
15388b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            // shown.
15398b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik            return;
15408b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik        }
15418b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik
15425d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik        LinearLayout parent = (LinearLayout) mScrollView
15435d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik                .findViewById(R.id.reminder_items_container);
15445d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik        if (parent != null) {
15455d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik            parent.removeAllViews();
15465d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik        }
1547c08957b48e755d34f1496d3937a24d60bdd24904RoboErik        if (mReminderViews != null) {
1548c08957b48e755d34f1496d3937a24d60bdd24904RoboErik            mReminderViews.clear();
1549c08957b48e755d34f1496d3937a24d60bdd24904RoboErik        }
15505d40a380fca9da181dfaf0c7756d4f53cbd2d3d3RoboErik
15511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        if (mHasAlarm) {
15521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            ArrayList<ReminderEntry> reminders = mOriginalReminders;
15531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            // Insert any minute values that aren't represented in the minutes list.
15541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            for (ReminderEntry re : reminders) {
15551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                EventViewUtils.addMinutesToList(
15561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                        mActivity, mReminderMinuteValues, mReminderMinuteLabels, re.getMinutes());
15571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            }
15581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            // Create a UI element for each reminder.  We display all of the reminders we get
15591ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            // from the provider, even if the count exceeds the calendar maximum.  (Also, for
15601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            // a new event, we won't have a maxReminders value available.)
15611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            for (ReminderEntry re : reminders) {
1562e35a032c939f357ce435711b2fd8de1887a05011RoboErik                EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews,
1563e35a032c939f357ce435711b2fd8de1887a05011RoboErik                        mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues,
15648b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                        mReminderMethodLabels, re, Integer.MAX_VALUE, mReminderChangeListener);
15651ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            }
1566e35a032c939f357ce435711b2fd8de1887a05011RoboErik            // TODO show unsupported reminder types in some fashion.
15671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        }
15681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
15691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
15708ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan    private void formatAttendees(ArrayList<Attendee> attendees, SpannableStringBuilder sb, int type) {
15718ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        if (attendees.size() <= 0) {
15728ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            return;
15738ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
15748ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
15758ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        int begin = sb.length();
15768ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        boolean firstTime = sb.length() == 0;
15778ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
15788ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        if (firstTime == false) {
15798ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            begin += 2; // skip over the ", " for formatting.
15808ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
15818ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
15828ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        for (Attendee attendee : attendees) {
15838ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            if (firstTime) {
15848ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                firstTime = false;
15858ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            } else {
15868ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                sb.append(", ");
15878ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }
15888ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
15898ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            String name = attendee.getDisplayName();
15908ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            sb.append(name);
15918ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
15928ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
15938ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        switch (type) {
15948ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            case Attendees.ATTENDEE_STATUS_ACCEPTED:
15958ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                break;
15968ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            case Attendees.ATTENDEE_STATUS_DECLINED:
15978ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                sb.setSpan(new StrikethroughSpan(), begin, sb.length(),
15988ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
15998ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // fall through
16008ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            default:
16018ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // The last INCLUSIVE causes the foreground color to be applied
16028ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // to the rest of the span. If not, the comma at the end of the
16038ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // declined or tentative may be black.
16040a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan                sb.setSpan(new ForegroundColorSpan(0xFF999999), begin, sb.length(),
16058ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
16068ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                break;
16072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
16082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
16092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    void updateResponse(View view) {
16112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // we only let the user accept/reject/etc. a meeting if:
16122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // a) you can edit the event's containing calendar AND
16132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // b) you're not the organizer and only attendee AND
16142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // c) organizerCanRespond is enabled for the calendar
16152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // (if the attendee data has been hidden, the visible number of attendees
16162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // will be 1 -- the calendar owner's).
16172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // (there are more cases involved to be 100% accurate, such as
16182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // paying attention to whether or not an attendee status was
16192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // included in the feed, but we're currently omitting those corner cases
16202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // for simplicity).
1621352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
1622352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        // TODO Switch to EditEventHelper.canRespond when this class uses CalendarEventModel.
1623d785cd533f6a3c23813c15315aed74efa9a116f5Michael Chan        if (!mCanModifyCalendar || (mHasAttendeeData && mIsOrganizer && mNumOfAttendees <= 1) ||
1624352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                (mIsOrganizer && !mOwnerCanRespond)) {
16252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setVisibilityCommon(view, R.id.response_container, View.GONE);
16262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
16272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
16282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        setVisibilityCommon(view, R.id.response_container, View.VISIBLE);
16302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1631f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan
1632f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        int response;
16335afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik        if (mUserSetResponse != CalendarController.ATTENDEE_NO_RESPONSE) {
16345afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik            response = mUserSetResponse;
16355afc08352fb7e2679ed00d41e6e5763ad333a7ecRoboErik        } else if (mAttendeeResponseFromIntent != CalendarController.ATTENDEE_NO_RESPONSE) {
1636f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            response = mAttendeeResponseFromIntent;
16372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
1638f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            response = mOriginalAttendeeResponse;
16392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
1640f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan
1641f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        int buttonToCheck = findButtonIdForResponse(response);
1642f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.response_value);
1643f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        radioGroup.check(buttonToCheck); // -1 clear all radio buttons
1644f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        radioGroup.setOnCheckedChangeListener(this);
16452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
16462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void setTextCommon(View view, int id, CharSequence text) {
16482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        TextView textView = (TextView) view.findViewById(id);
16492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (textView == null)
16502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
16512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        textView.setText(text);
16522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
16532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void setVisibilityCommon(View view, int id, int visibility) {
16552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        View v = view.findViewById(id);
16562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (v != null) {
16572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            v.setVisibility(visibility);
16582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
16592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return;
16602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
16612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
16632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Taken from com.google.android.gm.HtmlConversationActivity
16642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     *
16652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Send the intent that shows the Contact info corresponding to the email address.
16662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
16672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void showContactInfo(Attendee attendee, Rect rect) {
16682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // First perform lookup query to find existing contact
16692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final ContentResolver resolver = getActivity().getContentResolver();
16702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final String address = attendee.mEmail;
16712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final Uri dataUri = Uri.withAppendedPath(CommonDataKinds.Email.CONTENT_FILTER_URI,
16722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Uri.encode(address));
16732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final Uri lookupUri = ContactsContract.Data.getContactLookupUri(resolver, dataUri);
16742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (lookupUri != null) {
16762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // Found matching contact, trigger QuickContact
16772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            QuickContact.showQuickContact(getActivity(), rect, lookupUri,
16782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    QuickContact.MODE_MEDIUM, null);
16792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
16802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // No matching contact, ask user to create one
16812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final Uri mailUri = Uri.fromParts("mailto", address, null);
16822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, mailUri);
16832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // Pass along full E-mail string for possible create dialog
16852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            Rfc822Token sender = new Rfc822Token(attendee.mName, attendee.mEmail, null);
16862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            intent.putExtra(Intents.EXTRA_CREATE_DESCRIPTION, sender.toString());
16872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // Only provide personal name hint if we have one
16892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final String senderPersonal = attendee.mName;
16902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (!TextUtils.isEmpty(senderPersonal)) {
16912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                intent.putExtra(Intents.Insert.NAME, senderPersonal);
16922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
16932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
16942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            startActivity(intent);
16952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
16962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
1697cb81189e4868769ea016253eca104e46df2f033aErik
1698cb81189e4868769ea016253eca104e46df2f033aErik    @Override
16997c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    public void onPause() {
17007c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        mIsPaused = true;
17017c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        mHandler.removeCallbacks(onDeleteRunnable);
17027c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        super.onPause();
170386ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        // Remove event deletion alert box since it is being rebuild in the OnResume
170486ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        // This is done to get the same behavior on OnResume since the AlertDialog is gone on
170586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        // rotation but not if you press the HOME key
170686ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        if (mDeleteDialogVisible && mDeleteHelper != null) {
170786ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson            mDeleteHelper.dismissAlertDialog();
170886ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson            mDeleteHelper = null;
170986ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        }
17107c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    }
17117c6236d5553dc9f3d004ebbed794249713a11d19RoboErik
17127c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    @Override
17137c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    public void onResume() {
17147c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        super.onResume();
17157c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        mIsPaused = false;
17167c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        if (mDismissOnResume) {
17177c6236d5553dc9f3d004ebbed794249713a11d19RoboErik            mHandler.post(onDeleteRunnable);
17187c6236d5553dc9f3d004ebbed794249713a11d19RoboErik        }
171986ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        // Display the "delete confirmation" dialog if needed
172086ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        if (mDeleteDialogVisible) {
172186ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson            mDeleteHelper = new DeleteEventHelper(
172286ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                    mContext, mActivity,
172386ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                    !mIsDialog && !mIsTabletConfig /* exitWhenDone */);
172486ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson            mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener());
172586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson            mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable);
172686ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        }
17277c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    }
17287c6236d5553dc9f3d004ebbed794249713a11d19RoboErik
17297c6236d5553dc9f3d004ebbed794249713a11d19RoboErik    @Override
1730cb81189e4868769ea016253eca104e46df2f033aErik    public void eventsChanged() {
1731cb81189e4868769ea016253eca104e46df2f033aErik    }
1732cb81189e4868769ea016253eca104e46df2f033aErik
1733cb81189e4868769ea016253eca104e46df2f033aErik    @Override
1734cb81189e4868769ea016253eca104e46df2f033aErik    public long getSupportedEventTypes() {
1735cb81189e4868769ea016253eca104e46df2f033aErik        return EventType.EVENTS_CHANGED;
1736cb81189e4868769ea016253eca104e46df2f033aErik    }
1737cb81189e4868769ea016253eca104e46df2f033aErik
1738cb81189e4868769ea016253eca104e46df2f033aErik    @Override
1739cb81189e4868769ea016253eca104e46df2f033aErik    public void handleEvent(EventInfo event) {
1740f836d4af478310abc9b63f1afa6ab964e2478fedRoboErik        if (event.eventType == EventType.EVENTS_CHANGED && mHandler != null) {
1741cb81189e4868769ea016253eca104e46df2f033aErik            // reload the data
1742cb81189e4868769ea016253eca104e46df2f033aErik            mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION,
1743cb81189e4868769ea016253eca104e46df2f033aErik                    null, null, null);
1744cb81189e4868769ea016253eca104e46df2f033aErik        }
1745cb81189e4868769ea016253eca104e46df2f033aErik
1746cb81189e4868769ea016253eca104e46df2f033aErik    }
17471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
17481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
17491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    @Override
17501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    public void onClick(View view) {
17511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
17521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // This must be a click on one of the "remove reminder" buttons
17531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        LinearLayout reminderItem = (LinearLayout) view.getParent();
17541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        LinearLayout parent = (LinearLayout) reminderItem.getParent();
17551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        parent.removeView(reminderItem);
17561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mReminderViews.remove(reminderItem);
17578b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik        mUserModifiedReminders = true;
17581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
17591ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
17601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
17611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    /**
17621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * Add a new reminder when the user hits the "add reminder" button.  We use the default
17631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * reminder time and method.
17641ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     */
17651ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private void addReminder() {
17661ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // TODO: when adding a new reminder, make it different from the
17671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // last one in the list (if any).
17681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        if (mDefaultReminderMinutes == GeneralPreferences.NO_REMINDER) {
17691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews,
17708b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues,
17718b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mReminderMethodLabels,
17728b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    ReminderEntry.valueOf(GeneralPreferences.REMINDER_DEFAULT_TIME), mMaxReminders,
17738b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mReminderChangeListener);
17741ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        } else {
17751ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews,
17768b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues,
17778b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mReminderMethodLabels, ReminderEntry.valueOf(mDefaultReminderMinutes),
17788b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mMaxReminders, mReminderChangeListener);
17791ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        }
17801ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
17811ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
17821ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
1783e35a032c939f357ce435711b2fd8de1887a05011RoboErik    synchronized private void prepareReminders() {
1784e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // Nothing to do if we've already built these lists _and_ we aren't
1785e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // removing not allowed methods
1786e35a032c939f357ce435711b2fd8de1887a05011RoboErik        if (mReminderMinuteValues != null && mReminderMinuteLabels != null
1787e35a032c939f357ce435711b2fd8de1887a05011RoboErik                && mReminderMethodValues != null && mReminderMethodLabels != null
1788e35a032c939f357ce435711b2fd8de1887a05011RoboErik                && mCalendarAllowedReminders == null) {
1789e35a032c939f357ce435711b2fd8de1887a05011RoboErik            return;
1790e35a032c939f357ce435711b2fd8de1887a05011RoboErik        }
1791e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // Load the labels and corresponding numeric values for the minutes and methods lists
1792e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // from the assets.  If we're switching calendars, we need to clear and re-populate the
1793e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // lists (which may have elements added and removed based on calendar properties).  This
1794e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // is mostly relevant for "methods", since we shouldn't have any "minutes" values in a
1795e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // new event that aren't in the default set.
17961ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Resources r = mActivity.getResources();
17971ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mReminderMinuteValues = loadIntegerArray(r, R.array.reminder_minutes_values);
17981ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mReminderMinuteLabels = loadStringArray(r, R.array.reminder_minutes_labels);
17991ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mReminderMethodValues = loadIntegerArray(r, R.array.reminder_methods_values);
18001ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mReminderMethodLabels = loadStringArray(r, R.array.reminder_methods_labels);
1801e35a032c939f357ce435711b2fd8de1887a05011RoboErik
1802e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // Remove any reminder methods that aren't allowed for this calendar.  If this is
1803e35a032c939f357ce435711b2fd8de1887a05011RoboErik        // a new event, mCalendarAllowedReminders may not be set the first time we're called.
1804e35a032c939f357ce435711b2fd8de1887a05011RoboErik        if (mCalendarAllowedReminders != null) {
1805e35a032c939f357ce435711b2fd8de1887a05011RoboErik            EventViewUtils.reduceMethodList(mReminderMethodValues, mReminderMethodLabels,
1806e35a032c939f357ce435711b2fd8de1887a05011RoboErik                    mCalendarAllowedReminders);
1807e35a032c939f357ce435711b2fd8de1887a05011RoboErik        }
1808e35a032c939f357ce435711b2fd8de1887a05011RoboErik        if (mView != null) {
1809e35a032c939f357ce435711b2fd8de1887a05011RoboErik            mView.invalidate();
1810e35a032c939f357ce435711b2fd8de1887a05011RoboErik        }
18111ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
18121ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18131ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18141ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private boolean saveReminders() {
18151ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(3);
18161ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18171ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Read reminders from UI
18181ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        mReminders = EventViewUtils.reminderItemsToReminders(mReminderViews,
18191ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                mReminderMinuteValues, mReminderMethodValues);
1820e35a032c939f357ce435711b2fd8de1887a05011RoboErik        mOriginalReminders.addAll(mUnsupportedReminders);
1821e35a032c939f357ce435711b2fd8de1887a05011RoboErik        Collections.sort(mOriginalReminders);
1822e35a032c939f357ce435711b2fd8de1887a05011RoboErik        mReminders.addAll(mUnsupportedReminders);
1823e35a032c939f357ce435711b2fd8de1887a05011RoboErik        Collections.sort(mReminders);
18241ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18251ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Check if there are any changes in the reminder
18261ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        boolean changed = EditEventHelper.saveReminders(ops, mEventId, mReminders,
18271ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson                mOriginalReminders, false /* no force save */);
18281ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18291ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        if (!changed) {
18301ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            return false;
18311ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        }
18321ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18331ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // save new reminders
18341ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        AsyncQueryService service = new AsyncQueryService(getActivity());
18351ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        service.startBatch(0, null, Calendars.CONTENT_URI.getAuthority(), ops, 0);
18361ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        // Update the "hasAlarm" field for the event
18371ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
18381ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        int len = mReminders.size();
18391ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        boolean hasAlarm = len > 0;
18401ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        if (hasAlarm != mHasAlarm) {
18411ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            ContentValues values = new ContentValues();
18421ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            values.put(Events.HAS_ALARM, hasAlarm ? 1 : 0);
18431ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            service.startUpdate(0, null, uri, values, null, null, 0);
18441ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        }
18451ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        return true;
18461ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
18471ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18481ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    /**
18491ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * Loads an integer array asset into a list.
18501ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     */
18511ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static ArrayList<Integer> loadIntegerArray(Resources r, int resNum) {
18521ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        int[] vals = r.getIntArray(resNum);
18531ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        int size = vals.length;
18541ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        ArrayList<Integer> list = new ArrayList<Integer>(size);
18551ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18561ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        for (int i = 0; i < size; i++) {
18571ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson            list.add(vals[i]);
18581ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        }
18591ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
18601ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        return list;
18611ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
18621ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    /**
18631ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     * Loads a String array asset into a list.
18641ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson     */
18651ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    private static ArrayList<String> loadStringArray(Resources r, int resNum) {
18661ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        String[] labels = r.getStringArray(resNum);
18671ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        ArrayList<String> list = new ArrayList<String>(Arrays.asList(labels));
18681ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson        return list;
18691ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson    }
18701ce35aadf71e3d68b72940bc327f285530a85032Isaac Katzenelson
1871b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson    public void onDeleteStarted() {
1872b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson        mEventDeletionStarted = true;
1873b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson    }
1874b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson
187586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson    private Dialog.OnDismissListener createDeleteOnDismissListener() {
187686ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson        return new Dialog.OnDismissListener() {
187786ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                    @Override
187886ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                    public void onDismiss(DialogInterface dialog) {
187986ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                        // Since OnPause will force the dialog to dismiss , do
188086ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                        // not change the dialog status
188186ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                        if (!mIsPaused) {
188286ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                            mDeleteDialogVisible = false;
188386ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                        }
188486ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                    }
188586ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson                };
188686ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson    }
188786ff2912eea592d6a6ba78559daafb156783c7efIsaac Katzenelson
18882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang}
1889