1eca82e9468c002590045338f98588ad3ce1a0bb3Erik/*
2eca82e9468c002590045338f98588ad3ce1a0bb3Erik * Copyright (C) 2010 The Android Open Source Project
3eca82e9468c002590045338f98588ad3ce1a0bb3Erik *
4eca82e9468c002590045338f98588ad3ce1a0bb3Erik * Licensed under the Apache License, Version 2.0 (the "License");
5eca82e9468c002590045338f98588ad3ce1a0bb3Erik * you may not use this file except in compliance with the License.
6eca82e9468c002590045338f98588ad3ce1a0bb3Erik * You may obtain a copy of the License at
7eca82e9468c002590045338f98588ad3ce1a0bb3Erik *
8eca82e9468c002590045338f98588ad3ce1a0bb3Erik *      http://www.apache.org/licenses/LICENSE-2.0
9eca82e9468c002590045338f98588ad3ce1a0bb3Erik *
10eca82e9468c002590045338f98588ad3ce1a0bb3Erik * Unless required by applicable law or agreed to in writing, software
11eca82e9468c002590045338f98588ad3ce1a0bb3Erik * distributed under the License is distributed on an "AS IS" BASIS,
12eca82e9468c002590045338f98588ad3ce1a0bb3Erik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eca82e9468c002590045338f98588ad3ce1a0bb3Erik * See the License for the specific language governing permissions and
14eca82e9468c002590045338f98588ad3ce1a0bb3Erik * limitations under the License.
15eca82e9468c002590045338f98588ad3ce1a0bb3Erik */
16eca82e9468c002590045338f98588ad3ce1a0bb3Erik
17fbce65e53c7a111955f638db5bf8bee35381e5b7Erikpackage com.android.calendar.event;
18eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1979f228124de7d98146ca526d743436f6419e2365Erikimport android.app.Activity;
20eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.app.AlertDialog;
21e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chanimport android.app.DialogFragment;
22b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.app.FragmentManager;
235f62079ab9daefe95ede87631766e99e8b4a2220Erikimport android.app.ProgressDialog;
24ef31a98202852807f460af49ae3313d1ccf5e288Andy McFaddenimport android.app.Service;
25eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.content.Context;
26eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.content.DialogInterface;
27464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawaimport android.content.Intent;
28eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.content.SharedPreferences;
29eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.content.res.Resources;
30eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.database.Cursor;
31c07a57fb7436d807ad505fa7319b9de13f91e741Erikimport android.graphics.drawable.Drawable;
32b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.os.Bundle;
334afba187f8990ae2b3afaf8fcdb6039f231f4914James Kungimport android.provider.CalendarContract;
34a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees;
35a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars;
369e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport android.provider.CalendarContract.Events;
37a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Reminders;
38464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawaimport android.provider.Settings;
39eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.text.InputFilter;
40eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.text.TextUtils;
41eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.text.format.DateFormat;
42eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.text.format.DateUtils;
43eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.text.format.Time;
44eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.text.util.Rfc822Tokenizer;
457b92da258a480284dcc15a518ea570072329a31dErikimport android.util.Log;
46601ef6e0e7b921141cfeaf849238e444a10b9687Sara Tingimport android.view.KeyEvent;
47eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.view.View;
484afba187f8990ae2b3afaf8fcdb6039f231f4914James Kungimport android.view.View.OnClickListener;
49259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.ViewGroup;
50259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityEvent;
51259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.view.accessibility.AccessibilityManager;
52601ef6e0e7b921141cfeaf849238e444a10b9687Sara Tingimport android.view.inputmethod.EditorInfo;
533400a2bfc1e6be435ea2bb0f436a6ef338446504Erikimport android.widget.AdapterView;
543400a2bfc1e6be435ea2bb0f436a6ef338446504Erikimport android.widget.AdapterView.OnItemSelectedListener;
55eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.ArrayAdapter;
56601ef6e0e7b921141cfeaf849238e444a10b9687Sara Tingimport android.widget.AutoCompleteTextView;
57eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.Button;
58eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.CheckBox;
59eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.CompoundButton;
60eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.LinearLayout;
61eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.MultiAutoCompleteTextView;
62259b8f9a21fffd3858218581e9daaf689b6b888fErikimport android.widget.RadioButton;
63f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chanimport android.widget.RadioGroup;
64eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.ResourceCursorAdapter;
65eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.ScrollView;
66eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.Spinner;
67eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport android.widget.TextView;
68601ef6e0e7b921141cfeaf849238e444a10b9687Sara Tingimport android.widget.TextView.OnEditorActionListener;
69eca82e9468c002590045338f98588ad3ce1a0bb3Erik
709e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.CalendarEventModel;
719e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.CalendarEventModel.Attendee;
729e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.CalendarEventModel.ReminderEntry;
739e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.EmailAddressAdapter;
749e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.EventInfoFragment;
75b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport com.android.calendar.EventRecurrenceFormatter;
769e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.GeneralPreferences;
779e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.R;
789e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.RecipientAdapter;
799e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.Utils;
809e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.calendar.event.EditEventHelper.EditDoneRunnable;
81b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport com.android.calendar.recurrencepicker.RecurrencePickerDialog;
828a528adbba5d46fe0d566f474bc3be190511198eMichael Chanimport com.android.calendarcommon2.EventRecurrence;
839e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.common.Rfc822InputFilter;
849e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.common.Rfc822Validator;
8556f42bfb36d710726051e8268a115697477add61James Kungimport com.android.datetimepicker.date.DatePickerDialog;
8656f42bfb36d710726051e8268a115697477add61James Kungimport com.android.datetimepicker.date.DatePickerDialog.OnDateSetListener;
8756f42bfb36d710726051e8268a115697477add61James Kungimport com.android.datetimepicker.time.RadialPickerLayout;
8856f42bfb36d710726051e8268a115697477add61James Kungimport com.android.datetimepicker.time.TimePickerDialog;
8956f42bfb36d710726051e8268a115697477add61James Kungimport com.android.datetimepicker.time.TimePickerDialog.OnTimeSetListener;
909e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.ex.chips.AccountSpecifier;
919e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.ex.chips.BaseRecipientAdapter;
929e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.ex.chips.ChipsUtil;
939e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chanimport com.android.ex.chips.RecipientEditTextView;
94e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chanimport com.android.timezonepicker.TimeZoneInfo;
95e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chanimport com.android.timezonepicker.TimeZonePickerDialog;
96974343a44435bedc104d89fa98fdeb1ccf362501James Kungimport com.android.timezonepicker.TimeZonePickerUtils;
979e196e46b238e6bca1ef86c7d673807b78ab7016Michael Chan
98eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport java.util.ArrayList;
99eca82e9468c002590045338f98588ad3ce1a0bb3Erikimport java.util.Arrays;
1008a5489641442c022089ae1b00e498e2c1a0ba480Erikimport java.util.Formatter;
101d845fbe558d5229102b58cce70a1b29fe6cb6967Erikimport java.util.HashMap;
1028a5489641442c022089ae1b00e498e2c1a0ba480Erikimport java.util.Locale;
1034c8871bf5dee3b3586b375aee98effde31b781a8Mason Tangimport java.util.TimeZone;
104eca82e9468c002590045338f98588ad3ce1a0bb3Erik
105eca82e9468c002590045338f98588ad3ce1a0bb3Erikpublic class EditEventView implements View.OnClickListener, DialogInterface.OnCancelListener,
106b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        DialogInterface.OnClickListener, OnItemSelectedListener,
107e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        RecurrencePickerDialog.OnRecurrenceSetListener,
108e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        TimeZonePickerDialog.OnTimeZoneSetListener {
109bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung
1107b92da258a480284dcc15a518ea570072329a31dErik    private static final String TAG = "EditEvent";
111352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan    private static final String GOOGLE_SECONDARY_CALENDAR = "calendar.google.com";
112259b8f9a21fffd3858218581e9daaf689b6b888fErik    private static final String PERIOD_SPACE = ". ";
113e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
11456f42bfb36d710726051e8268a115697477add61James Kung    private static final String FRAG_TAG_DATE_PICKER = "datePickerDialogFragment";
1157674b690b018c31207830c2a196927a0c654486cSam Blitzstein    private static final String FRAG_TAG_TIME_PICKER = "timePickerDialogFragment";
116e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    private static final String FRAG_TAG_TIME_ZONE_PICKER = "timeZonePickerDialogFragment";
117e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    private static final String FRAG_TAG_RECUR_PICKER = "recurrencePickerDialogFragment";
118d845fbe558d5229102b58cce70a1b29fe6cb6967Erik
119c07a57fb7436d807ad505fa7319b9de13f91e741Erik    ArrayList<View> mEditOnlyList = new ArrayList<View>();
120c07a57fb7436d807ad505fa7319b9de13f91e741Erik    ArrayList<View> mEditViewList = new ArrayList<View>();
121c07a57fb7436d807ad505fa7319b9de13f91e741Erik    ArrayList<View> mViewOnlyList = new ArrayList<View>();
122eca82e9468c002590045338f98588ad3ce1a0bb3Erik    TextView mLoadingMessage;
123eca82e9468c002590045338f98588ad3ce1a0bb3Erik    ScrollView mScrollView;
124eca82e9468c002590045338f98588ad3ce1a0bb3Erik    Button mStartDateButton;
125eca82e9468c002590045338f98588ad3ce1a0bb3Erik    Button mEndDateButton;
126eca82e9468c002590045338f98588ad3ce1a0bb3Erik    Button mStartTimeButton;
127eca82e9468c002590045338f98588ad3ce1a0bb3Erik    Button mEndTimeButton;
1284c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang    Button mTimezoneButton;
1294afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    View mColorPickerNewEvent;
1304afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    View mColorPickerExistingEvent;
1314afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    OnClickListener mChangeColorOnClickListener;
132b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan    View mTimezoneRow;
1338a5489641442c022089ae1b00e498e2c1a0ba480Erik    TextView mStartTimeHome;
1348a5489641442c022089ae1b00e498e2c1a0ba480Erik    TextView mStartDateHome;
1358a5489641442c022089ae1b00e498e2c1a0ba480Erik    TextView mEndTimeHome;
1368a5489641442c022089ae1b00e498e2c1a0ba480Erik    TextView mEndDateHome;
137eca82e9468c002590045338f98588ad3ce1a0bb3Erik    CheckBox mAllDayCheckBox;
138eca82e9468c002590045338f98588ad3ce1a0bb3Erik    Spinner mCalendarsSpinner;
139b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    Button mRruleButton;
140ced0eb67ef49c3203f72520c296e73d9cb4f654bMichael Chan    Spinner mAvailabilitySpinner;
141ced0eb67ef49c3203f72520c296e73d9cb4f654bMichael Chan    Spinner mAccessLevelSpinner;
142f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan    RadioGroup mResponseRadioGroup;
143d19fa1c8b79d93473157e80911ff12c6283c1b03Sara Ting    TextView mTitleTextView;
1444686b4065af0137f5d6ff7570d867fed562c8120Sara Ting    AutoCompleteTextView mLocationTextView;
1454686b4065af0137f5d6ff7570d867fed562c8120Sara Ting    EventLocationAdapter mLocationAdapter;
146eca82e9468c002590045338f98588ad3ce1a0bb3Erik    TextView mDescriptionTextView;
14724ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan    TextView mWhenView;
1484c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang    TextView mTimezoneTextView;
14924ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan    TextView mTimezoneLabel;
150eca82e9468c002590045338f98588ad3ce1a0bb3Erik    LinearLayout mRemindersContainer;
151eca82e9468c002590045338f98588ad3ce1a0bb3Erik    MultiAutoCompleteTextView mAttendeesList;
152c07a57fb7436d807ad505fa7319b9de13f91e741Erik    View mCalendarSelectorGroup;
153eb51f84a9d77b1d7c2d407b1f594b7e281e277ccMindy Pereira    View mCalendarSelectorWrapper;
154c07a57fb7436d807ad505fa7319b9de13f91e741Erik    View mCalendarStaticGroup;
155a7694eead7cbb293990bc89c3906e17bad36194cErik    View mLocationGroup;
156a7694eead7cbb293990bc89c3906e17bad36194cErik    View mDescriptionGroup;
157c07a57fb7436d807ad505fa7319b9de13f91e741Erik    View mRemindersGroup;
158c07a57fb7436d807ad505fa7319b9de13f91e741Erik    View mResponseGroup;
159c07a57fb7436d807ad505fa7319b9de13f91e741Erik    View mOrganizerGroup;
160c07a57fb7436d807ad505fa7319b9de13f91e741Erik    View mAttendeesGroup;
1618a5489641442c022089ae1b00e498e2c1a0ba480Erik    View mStartHomeGroup;
1628a5489641442c022089ae1b00e498e2c1a0ba480Erik    View mEndHomeGroup;
163c07a57fb7436d807ad505fa7319b9de13f91e741Erik
164efa480cc0733071f311ccb27806916de5efff71cErik    private int[] mOriginalPadding = new int[4];
165eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1664afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    public boolean mIsMultipane;
167eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private ProgressDialog mLoadingCalendarsDialog;
168eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private AlertDialog mNoCalendarsDialog;
169e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    private DialogFragment mTimezoneDialog;
17079f228124de7d98146ca526d743436f6419e2365Erik    private Activity mActivity;
17179f228124de7d98146ca526d743436f6419e2365Erik    private EditDoneRunnable mDone;
172eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private View mView;
173eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private CalendarEventModel mModel;
174eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private Cursor mCalendarsCursor;
17518cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira    private AccountSpecifier mAddressAdapter;
176eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private Rfc822Validator mEmailValidator;
177eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1787674b690b018c31207830c2a196927a0c654486cSam Blitzstein    public boolean mTimeSelectedWasStartTime;
17956f42bfb36d710726051e8268a115697477add61James Kung    public boolean mDateSelectedWasStartDate;
1803cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein    private TimePickerDialog mStartTimePickerDialog;
1813cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein    private TimePickerDialog mEndTimePickerDialog;
18256f42bfb36d710726051e8268a115697477add61James Kung    private DatePickerDialog mDatePickerDialog;
1837674b690b018c31207830c2a196927a0c654486cSam Blitzstein
184fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden    /**
185fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden     * Contents of the "minutes" spinner.  This has default values from the XML file, augmented
186fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden     * with any additional values that were already associated with the event.
187fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden     */
188fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden    private ArrayList<Integer> mReminderMinuteValues;
189fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden    private ArrayList<String> mReminderMinuteLabels;
190fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden
1919645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    /**
1929645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * Contents of the "methods" spinner.  The "values" list specifies the method constant
1939645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * (e.g. {@link Reminders#METHOD_ALERT}) associated with the labels.  Any methods that
1949645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * aren't allowed by the Calendar will be removed.
1959645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     */
1969645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    private ArrayList<Integer> mReminderMethodValues;
1979645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    private ArrayList<String> mReminderMethodLabels;
1989645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
199c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik    /**
200c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik     * Contents of the "availability" spinner. The "values" list specifies the
201c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik     * type constant (e.g. {@link Events#AVAILABILITY_BUSY}) associated with the
202c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik     * labels. Any types that aren't allowed by the Calendar will be removed.
203c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik     */
204c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik    private ArrayList<Integer> mAvailabilityValues;
205c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik    private ArrayList<String> mAvailabilityLabels;
2067cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein    private ArrayList<String> mOriginalAvailabilityLabels;
2077cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein    private ArrayAdapter<String> mAvailabilityAdapter;
2087cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein    private boolean mAvailabilityExplicitlySet;
2097cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein    private boolean mAllDayChangingAvailability;
2107cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein    private int mAvailabilityCurrentlySelected;
211c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik
212eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private int mDefaultReminderMinutes;
213eca82e9468c002590045338f98588ad3ce1a0bb3Erik
214eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private boolean mSaveAfterQueryComplete = false;
215eca82e9468c002590045338f98588ad3ce1a0bb3Erik
21600040c6e081d367567fd579f881e58d448154622Sam Blitzstein    private TimeZonePickerUtils mTzPickerUtils;
217eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private Time mStartTime;
218eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private Time mEndTime;
2194c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang    private String mTimezone;
2208b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan    private boolean mAllDay = false;
221eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private int mModification = EditEventHelper.MODIFY_UNINITIALIZED;
222eca82e9468c002590045338f98588ad3ce1a0bb3Erik
223eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private EventRecurrence mEventRecurrence = new EventRecurrence();
224eca82e9468c002590045338f98588ad3ce1a0bb3Erik
225eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private ArrayList<LinearLayout> mReminderItems = new ArrayList<LinearLayout>(0);
226e35a032c939f357ce435711b2fd8de1887a05011RoboErik    private ArrayList<ReminderEntry> mUnsupportedReminders = new ArrayList<ReminderEntry>();
227b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private String mRrule;
228eca82e9468c002590045338f98588ad3ce1a0bb3Erik
2298a5489641442c022089ae1b00e498e2c1a0ba480Erik    private static StringBuilder mSB = new StringBuilder(50);
2308a5489641442c022089ae1b00e498e2c1a0ba480Erik    private static Formatter mF = new Formatter(mSB, Locale.getDefault());
2318a5489641442c022089ae1b00e498e2c1a0ba480Erik
232eca82e9468c002590045338f98588ad3ce1a0bb3Erik    /* This class is used to update the time buttons. */
233eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private class TimeListener implements OnTimeSetListener {
234eca82e9468c002590045338f98588ad3ce1a0bb3Erik        private View mView;
235eca82e9468c002590045338f98588ad3ce1a0bb3Erik
236eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public TimeListener(View view) {
237eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mView = view;
238eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
239eca82e9468c002590045338f98588ad3ce1a0bb3Erik
2409645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        @Override
241d661d5f15ccb8438b4b656f33b99afd23b2dc39aSam Blitzstein        public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) {
242eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Cache the member variables locally to avoid inner class overhead.
243eca82e9468c002590045338f98588ad3ce1a0bb3Erik            Time startTime = mStartTime;
244eca82e9468c002590045338f98588ad3ce1a0bb3Erik            Time endTime = mEndTime;
245eca82e9468c002590045338f98588ad3ce1a0bb3Erik
246eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Cache the start and end millis so that we limit the number
247eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // of calls to normalize() and toMillis(), which are fairly
248eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // expensive.
249eca82e9468c002590045338f98588ad3ce1a0bb3Erik            long startMillis;
250eca82e9468c002590045338f98588ad3ce1a0bb3Erik            long endMillis;
251eca82e9468c002590045338f98588ad3ce1a0bb3Erik            if (mView == mStartTimeButton) {
252eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // The start time was changed.
253eca82e9468c002590045338f98588ad3ce1a0bb3Erik                int hourDuration = endTime.hour - startTime.hour;
254eca82e9468c002590045338f98588ad3ce1a0bb3Erik                int minuteDuration = endTime.minute - startTime.minute;
255eca82e9468c002590045338f98588ad3ce1a0bb3Erik
256eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startTime.hour = hourOfDay;
257eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startTime.minute = minute;
258eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startMillis = startTime.normalize(true);
259eca82e9468c002590045338f98588ad3ce1a0bb3Erik
260eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // Also update the end time to keep the duration constant.
261eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.hour = hourOfDay + hourDuration;
262eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.minute = minute + minuteDuration;
263559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan
264559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan                // Update tz in case the start time switched from/to DLS
265559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan                populateTimezone(startMillis);
266eca82e9468c002590045338f98588ad3ce1a0bb3Erik            } else {
267eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // The end time was changed.
268eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startMillis = startTime.toMillis(true);
269eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.hour = hourOfDay;
270eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.minute = minute;
271eca82e9468c002590045338f98588ad3ce1a0bb3Erik
272eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // Move to the start time if the end time is before the start
273eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // time.
274eca82e9468c002590045338f98588ad3ce1a0bb3Erik                if (endTime.before(startTime)) {
275eca82e9468c002590045338f98588ad3ce1a0bb3Erik                    endTime.monthDay = startTime.monthDay + 1;
276eca82e9468c002590045338f98588ad3ce1a0bb3Erik                }
277559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan                // Call populateTimezone if we support end time zone as well
278eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
279eca82e9468c002590045338f98588ad3ce1a0bb3Erik
280eca82e9468c002590045338f98588ad3ce1a0bb3Erik            endMillis = endTime.normalize(true);
281eca82e9468c002590045338f98588ad3ce1a0bb3Erik
282eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setDate(mEndDateButton, endMillis);
283eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setTime(mStartTimeButton, startMillis);
284eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setTime(mEndTimeButton, endMillis);
2858a5489641442c022089ae1b00e498e2c1a0ba480Erik            updateHomeTime();
286eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
287eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
288eca82e9468c002590045338f98588ad3ce1a0bb3Erik
289eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private class TimeClickListener implements View.OnClickListener {
290eca82e9468c002590045338f98588ad3ce1a0bb3Erik        private Time mTime;
291eca82e9468c002590045338f98588ad3ce1a0bb3Erik
292eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public TimeClickListener(Time time) {
293eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mTime = time;
294eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
295eca82e9468c002590045338f98588ad3ce1a0bb3Erik
2969645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        @Override
297eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public void onClick(View v) {
2987674b690b018c31207830c2a196927a0c654486cSam Blitzstein
2993cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein            TimePickerDialog dialog;
3007674b690b018c31207830c2a196927a0c654486cSam Blitzstein            if (v == mStartTimeButton) {
3017674b690b018c31207830c2a196927a0c654486cSam Blitzstein                mTimeSelectedWasStartTime = true;
3023cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                if (mStartTimePickerDialog == null) {
3033cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                    mStartTimePickerDialog = TimePickerDialog.newInstance(new TimeListener(v),
3043cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                            mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity));
3053cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                } else {
3063cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                    mStartTimePickerDialog.setStartTime(mTime.hour, mTime.minute);
3073cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                }
3083cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                dialog = mStartTimePickerDialog;
3097674b690b018c31207830c2a196927a0c654486cSam Blitzstein            } else {
3107674b690b018c31207830c2a196927a0c654486cSam Blitzstein                mTimeSelectedWasStartTime = false;
3113cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                if (mEndTimePickerDialog == null) {
3123cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                    mEndTimePickerDialog = TimePickerDialog.newInstance(new TimeListener(v),
3133cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                            mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity));
3143cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                } else {
3153cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                    mEndTimePickerDialog.setStartTime(mTime.hour, mTime.minute);
3163cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                }
3173cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                dialog = mEndTimePickerDialog;
3183cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein
3197674b690b018c31207830c2a196927a0c654486cSam Blitzstein            }
3207674b690b018c31207830c2a196927a0c654486cSam Blitzstein
3216a212e3d34e4deacfc80cadf85d30018180a694bJames Kung            final FragmentManager fm = mActivity.getFragmentManager();
3226a212e3d34e4deacfc80cadf85d30018180a694bJames Kung            fm.executePendingTransactions();
3236a212e3d34e4deacfc80cadf85d30018180a694bJames Kung
3243cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein            if (dialog != null && !dialog.isAdded()) {
3253cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein                dialog.show(fm, FRAG_TAG_TIME_PICKER);
3263cde83462583fc76158e97c21185a95e71039e7cSam Blitzstein            }
327eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
328eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
329eca82e9468c002590045338f98588ad3ce1a0bb3Erik
330eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private class DateListener implements OnDateSetListener {
331eca82e9468c002590045338f98588ad3ce1a0bb3Erik        View mView;
332eca82e9468c002590045338f98588ad3ce1a0bb3Erik
333eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public DateListener(View view) {
334eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mView = view;
335eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
336eca82e9468c002590045338f98588ad3ce1a0bb3Erik
3379645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        @Override
33856f42bfb36d710726051e8268a115697477add61James Kung        public void onDateSet(DatePickerDialog view, int year, int month, int monthDay) {
3390a01fd383c6c3ae46e28c89fa1a55cc0132a15f7Michael Chan            Log.d(TAG, "onDateSet: " + year +  " " + month +  " " + monthDay);
340eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Cache the member variables locally to avoid inner class overhead.
341eca82e9468c002590045338f98588ad3ce1a0bb3Erik            Time startTime = mStartTime;
342eca82e9468c002590045338f98588ad3ce1a0bb3Erik            Time endTime = mEndTime;
343eca82e9468c002590045338f98588ad3ce1a0bb3Erik
344eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Cache the start and end millis so that we limit the number
345eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // of calls to normalize() and toMillis(), which are fairly
346eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // expensive.
347eca82e9468c002590045338f98588ad3ce1a0bb3Erik            long startMillis;
348eca82e9468c002590045338f98588ad3ce1a0bb3Erik            long endMillis;
349eca82e9468c002590045338f98588ad3ce1a0bb3Erik            if (mView == mStartDateButton) {
350eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // The start date was changed.
351eca82e9468c002590045338f98588ad3ce1a0bb3Erik                int yearDuration = endTime.year - startTime.year;
352eca82e9468c002590045338f98588ad3ce1a0bb3Erik                int monthDuration = endTime.month - startTime.month;
353eca82e9468c002590045338f98588ad3ce1a0bb3Erik                int monthDayDuration = endTime.monthDay - startTime.monthDay;
354eca82e9468c002590045338f98588ad3ce1a0bb3Erik
355eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startTime.year = year;
356eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startTime.month = month;
357eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startTime.monthDay = monthDay;
358eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startMillis = startTime.normalize(true);
359eca82e9468c002590045338f98588ad3ce1a0bb3Erik
360eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // Also update the end date to keep the duration constant.
361eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.year = year + yearDuration;
362eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.month = month + monthDuration;
363eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.monthDay = monthDay + monthDayDuration;
364eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endMillis = endTime.normalize(true);
365eca82e9468c002590045338f98588ad3ce1a0bb3Erik
366eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // If the start date has changed then update the repeats.
367eca82e9468c002590045338f98588ad3ce1a0bb3Erik                populateRepeats();
368559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan
369559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan                // Update tz in case the start time switched from/to DLS
370559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan                populateTimezone(startMillis);
371eca82e9468c002590045338f98588ad3ce1a0bb3Erik            } else {
372eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // The end date was changed.
373eca82e9468c002590045338f98588ad3ce1a0bb3Erik                startMillis = startTime.toMillis(true);
374eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.year = year;
375eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.month = month;
376eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endTime.monthDay = monthDay;
377eca82e9468c002590045338f98588ad3ce1a0bb3Erik                endMillis = endTime.normalize(true);
378eca82e9468c002590045338f98588ad3ce1a0bb3Erik
379eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // Do not allow an event to have an end time before the start
380eca82e9468c002590045338f98588ad3ce1a0bb3Erik                // time.
381eca82e9468c002590045338f98588ad3ce1a0bb3Erik                if (endTime.before(startTime)) {
382eca82e9468c002590045338f98588ad3ce1a0bb3Erik                    endTime.set(startTime);
383eca82e9468c002590045338f98588ad3ce1a0bb3Erik                    endMillis = startMillis;
384eca82e9468c002590045338f98588ad3ce1a0bb3Erik                }
385559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan                // Call populateTimezone if we support end time zone as well
386eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
387eca82e9468c002590045338f98588ad3ce1a0bb3Erik
388eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setDate(mStartDateButton, startMillis);
389eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setDate(mEndDateButton, endMillis);
390eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setTime(mEndTimeButton, endMillis); // In case end time had to be
391eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // reset
3928a5489641442c022089ae1b00e498e2c1a0ba480Erik            updateHomeTime();
393eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
394eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
395eca82e9468c002590045338f98588ad3ce1a0bb3Erik
396eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // Fills in the date and time fields
397eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private void populateWhen() {
398eca82e9468c002590045338f98588ad3ce1a0bb3Erik        long startMillis = mStartTime.toMillis(false /* use isDst */);
399eca82e9468c002590045338f98588ad3ce1a0bb3Erik        long endMillis = mEndTime.toMillis(false /* use isDst */);
400eca82e9468c002590045338f98588ad3ce1a0bb3Erik        setDate(mStartDateButton, startMillis);
401eca82e9468c002590045338f98588ad3ce1a0bb3Erik        setDate(mEndDateButton, endMillis);
402eca82e9468c002590045338f98588ad3ce1a0bb3Erik
403eca82e9468c002590045338f98588ad3ce1a0bb3Erik        setTime(mStartTimeButton, startMillis);
404eca82e9468c002590045338f98588ad3ce1a0bb3Erik        setTime(mEndTimeButton, endMillis);
405eca82e9468c002590045338f98588ad3ce1a0bb3Erik
406eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mStartDateButton.setOnClickListener(new DateClickListener(mStartTime));
407eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mEndDateButton.setOnClickListener(new DateClickListener(mEndTime));
408eca82e9468c002590045338f98588ad3ce1a0bb3Erik
409eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mStartTimeButton.setOnClickListener(new TimeClickListener(mStartTime));
410eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mEndTimeButton.setOnClickListener(new TimeClickListener(mEndTime));
411eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
412eca82e9468c002590045338f98588ad3ce1a0bb3Erik
413e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    // Implements OnTimeZoneSetListener
414e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    @Override
415e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    public void onTimeZoneSet(TimeZoneInfo tzi) {
416e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        setTimezone(tzi.mTzId);
417e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        updateHomeTime();
418e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    }
419e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
420e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    private void setTimezone(String timeZone) {
421e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mTimezone = timeZone;
422e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mStartTime.timezone = mTimezone;
423e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        long timeMillis = mStartTime.normalize(true);
424e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mEndTime.timezone = mTimezone;
425e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mEndTime.normalize(true);
426e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
427e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        populateTimezone(timeMillis);
428e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    }
429e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
430559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan    private void populateTimezone(long eventStartTime) {
43100040c6e081d367567fd579f881e58d448154622Sam Blitzstein        if (mTzPickerUtils == null) {
43200040c6e081d367567fd579f881e58d448154622Sam Blitzstein            mTzPickerUtils = new TimeZonePickerUtils(mActivity);
43300040c6e081d367567fd579f881e58d448154622Sam Blitzstein        }
434dd67b8db0c2e39bee143cd09fc9055b25849910aSam Blitzstein        CharSequence displayName =
435b69ea6371541b833662acbb835ae758316e1d0bbSam Blitzstein                mTzPickerUtils.getGmtDisplayName(mActivity, mTimezone, eventStartTime, true);
436e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
437e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mTimezoneTextView.setText(displayName);
438e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mTimezoneButton.setText(displayName);
439e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan    }
440e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
4414c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang    private void showTimezoneDialog() {
442e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        Bundle b = new Bundle();
443e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        b.putLong(TimeZonePickerDialog.BUNDLE_START_TIME_MILLIS, mStartTime.toMillis(false));
444e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        b.putString(TimeZonePickerDialog.BUNDLE_TIME_ZONE, mTimezone);
445e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan
446e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        FragmentManager fm = mActivity.getFragmentManager();
447e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        TimeZonePickerDialog tzpd = (TimeZonePickerDialog) fm
448e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan                .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER);
449e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        if (tzpd != null) {
450e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan            tzpd.dismiss();
451e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        }
452e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        tzpd = new TimeZonePickerDialog();
453e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        tzpd.setArguments(b);
454e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        tzpd.setOnTimeZoneSetListener(EditEventView.this);
455e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER);
4564c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang    }
4574c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang
458eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private void populateRepeats() {
459eca82e9468c002590045338f98588ad3ce1a0bb3Erik        Resources r = mActivity.getResources();
460b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        String repeatString;
461b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        boolean enabled;
462b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (!TextUtils.isEmpty(mRrule)) {
463b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            repeatString = EventRecurrenceFormatter.getRepeatString(mActivity, r,
464b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mEventRecurrence, true);
465b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
466b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (repeatString == null) {
467b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                repeatString = r.getString(R.string.custom);
468b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                Log.e(TAG, "Can't generate display string for " + mRrule);
469b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                enabled = false;
470eca82e9468c002590045338f98588ad3ce1a0bb3Erik            } else {
471b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                // TODO Should give option to clear/reset rrule
472b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                enabled = RecurrencePickerDialog.canHandleRecurrenceRule(mEventRecurrence);
473b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (!enabled) {
474b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    Log.e(TAG, "UI can't handle " + mRrule);
475eca82e9468c002590045338f98588ad3ce1a0bb3Erik                }
476eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
477b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else {
478b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            repeatString = r.getString(R.string.does_not_repeat);
479b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            enabled = true;
480eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
481b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
482b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRruleButton.setText(repeatString);
483eca82e9468c002590045338f98588ad3ce1a0bb3Erik
484eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // Don't allow the user to make exceptions recurring events.
48528dab653f55caccbed32f700274f5274abaee089RoboErik        if (mModel.mOriginalSyncId != null) {
486b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            enabled = false;
487eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
488b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRruleButton.setOnClickListener(this);
489b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRruleButton.setEnabled(enabled);
490eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
491eca82e9468c002590045338f98588ad3ce1a0bb3Erik
492eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private class DateClickListener implements View.OnClickListener {
493eca82e9468c002590045338f98588ad3ce1a0bb3Erik        private Time mTime;
494eca82e9468c002590045338f98588ad3ce1a0bb3Erik
495eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public DateClickListener(Time time) {
496eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mTime = time;
497eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
498eca82e9468c002590045338f98588ad3ce1a0bb3Erik
499b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
500eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public void onClick(View v) {
50196cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert            if (!mView.hasWindowFocus()) {
50296cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert                // Don't do anything if the activity if paused. Since Activity doesn't
50396cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert                // have a built in way to do this, we would have to implement one ourselves and
50496cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert                // either cast our Activity to a specialized activity base class or implement some
50596cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert                // generic interface that tells us if an activity is paused. hasWindowFocus() is
50696cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert                // close enough if not quite perfect.
50796cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert                return;
50896cce4ae26c09dfc552fe98ae1dac667914d7e5cAlon Albert            }
50956f42bfb36d710726051e8268a115697477add61James Kung            if (v == mStartDateButton) {
51056f42bfb36d710726051e8268a115697477add61James Kung                mDateSelectedWasStartDate = true;
511cf7b691adbac805ad963141622d67fd39eaaabbdRoboErik            } else {
51256f42bfb36d710726051e8268a115697477add61James Kung                mDateSelectedWasStartDate = false;
513cf7b691adbac805ad963141622d67fd39eaaabbdRoboErik            }
51456f42bfb36d710726051e8268a115697477add61James Kung
51556f42bfb36d710726051e8268a115697477add61James Kung            final DateListener listener = new DateListener(v);
51656f42bfb36d710726051e8268a115697477add61James Kung            if (mDatePickerDialog != null) {
51756f42bfb36d710726051e8268a115697477add61James Kung                mDatePickerDialog.dismiss();
51856f42bfb36d710726051e8268a115697477add61James Kung            }
51956f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog = DatePickerDialog.newInstance(listener,
52056f42bfb36d710726051e8268a115697477add61James Kung                    mTime.year, mTime.month, mTime.monthDay);
52156f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.setFirstDayOfWeek(Utils.getFirstDayOfWeekAsCalendar(mActivity));
52256f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.setYearRange(Utils.YEAR_MIN, Utils.YEAR_MAX);
52356f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.show(mActivity.getFragmentManager(), FRAG_TAG_DATE_PICKER);
524eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
525eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
526eca82e9468c002590045338f98588ad3ce1a0bb3Erik
52709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    public static class CalendarsAdapter extends ResourceCursorAdapter {
52809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        public CalendarsAdapter(Context context, int resourceId, Cursor c) {
52909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            super(context, resourceId, c);
530eca82e9468c002590045338f98588ad3ce1a0bb3Erik            setDropDownViewResource(R.layout.calendars_dropdown_item);
531eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
532eca82e9468c002590045338f98588ad3ce1a0bb3Erik
533eca82e9468c002590045338f98588ad3ce1a0bb3Erik        @Override
534eca82e9468c002590045338f98588ad3ce1a0bb3Erik        public void bindView(View view, Context context, Cursor cursor) {
535eca82e9468c002590045338f98588ad3ce1a0bb3Erik            View colorBar = view.findViewById(R.id.color);
5360e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik            int colorColumn = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
537ef2add9145f058ea103ade2870a8ba899b9ed1c9RoboErik            int nameColumn = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME);
538eca82e9468c002590045338f98588ad3ce1a0bb3Erik            int ownerColumn = cursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);
539eca82e9468c002590045338f98588ad3ce1a0bb3Erik            if (colorBar != null) {
5404acb2fd087308dea146b8b10f5278c59df387680RoboErik                colorBar.setBackgroundColor(Utils.getDisplayColorFromColor(cursor
5414acb2fd087308dea146b8b10f5278c59df387680RoboErik                        .getInt(colorColumn)));
542eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
543eca82e9468c002590045338f98588ad3ce1a0bb3Erik
544eca82e9468c002590045338f98588ad3ce1a0bb3Erik            TextView name = (TextView) view.findViewById(R.id.calendar_name);
545eca82e9468c002590045338f98588ad3ce1a0bb3Erik            if (name != null) {
546eca82e9468c002590045338f98588ad3ce1a0bb3Erik                String displayName = cursor.getString(nameColumn);
547eca82e9468c002590045338f98588ad3ce1a0bb3Erik                name.setText(displayName);
548eca82e9468c002590045338f98588ad3ce1a0bb3Erik
549eca82e9468c002590045338f98588ad3ce1a0bb3Erik                TextView accountName = (TextView) view.findViewById(R.id.account_name);
550eca82e9468c002590045338f98588ad3ce1a0bb3Erik                if (accountName != null) {
551eca82e9468c002590045338f98588ad3ce1a0bb3Erik                    accountName.setText(cursor.getString(ownerColumn));
552eca82e9468c002590045338f98588ad3ce1a0bb3Erik                    accountName.setVisibility(TextView.VISIBLE);
553eca82e9468c002590045338f98588ad3ce1a0bb3Erik                }
554eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
555eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
556eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
557eca82e9468c002590045338f98588ad3ce1a0bb3Erik
5587b92da258a480284dcc15a518ea570072329a31dErik    /**
5597b92da258a480284dcc15a518ea570072329a31dErik     * Does prep steps for saving a calendar event.
5607b92da258a480284dcc15a518ea570072329a31dErik     *
5617b92da258a480284dcc15a518ea570072329a31dErik     * This triggers a parse of the attendees list and checks if the event is
5625f62079ab9daefe95ede87631766e99e8b4a2220Erik     * ready to be saved. An event is ready to be saved so long as a model
5635f62079ab9daefe95ede87631766e99e8b4a2220Erik     * exists and has a calendar it can be associated with, either because it's
5645f62079ab9daefe95ede87631766e99e8b4a2220Erik     * an existing event or we've finished querying.
5657b92da258a480284dcc15a518ea570072329a31dErik     *
5665f62079ab9daefe95ede87631766e99e8b4a2220Erik     * @return false if there is no model or no calendar had been loaded yet,
5675f62079ab9daefe95ede87631766e99e8b4a2220Erik     * true otherwise.
5687b92da258a480284dcc15a518ea570072329a31dErik     */
5697b92da258a480284dcc15a518ea570072329a31dErik    public boolean prepareForSave() {
5705f62079ab9daefe95ede87631766e99e8b4a2220Erik        if (mModel == null || (mCalendarsCursor == null && mModel.mUri == null)) {
5717b92da258a480284dcc15a518ea570072329a31dErik            return false;
5727b92da258a480284dcc15a518ea570072329a31dErik        }
5735f62079ab9daefe95ede87631766e99e8b4a2220Erik        return fillModelFromUI();
5747b92da258a480284dcc15a518ea570072329a31dErik    }
5757b92da258a480284dcc15a518ea570072329a31dErik
576a7694eead7cbb293990bc89c3906e17bad36194cErik    public boolean fillModelFromReadOnlyUi() {
577a7694eead7cbb293990bc89c3906e17bad36194cErik        if (mModel == null || (mCalendarsCursor == null && mModel.mUri == null)) {
578a7694eead7cbb293990bc89c3906e17bad36194cErik            return false;
579a7694eead7cbb293990bc89c3906e17bad36194cErik        }
5809645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mReminders = EventViewUtils.reminderItemsToReminders(
5819645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                    mReminderItems, mReminderMinuteValues, mReminderMethodValues);
582e35a032c939f357ce435711b2fd8de1887a05011RoboErik        mModel.mReminders.addAll(mUnsupportedReminders);
583e35a032c939f357ce435711b2fd8de1887a05011RoboErik        mModel.normalizeReminders();
584a7694eead7cbb293990bc89c3906e17bad36194cErik        int status = EventInfoFragment.getResponseFromButtonId(
585a7694eead7cbb293990bc89c3906e17bad36194cErik                mResponseRadioGroup.getCheckedRadioButtonId());
586a7694eead7cbb293990bc89c3906e17bad36194cErik        if (status != Attendees.ATTENDEE_STATUS_NONE) {
587a7694eead7cbb293990bc89c3906e17bad36194cErik            mModel.mSelfAttendeeStatus = status;
588a7694eead7cbb293990bc89c3906e17bad36194cErik        }
589a7694eead7cbb293990bc89c3906e17bad36194cErik        return true;
590a7694eead7cbb293990bc89c3906e17bad36194cErik    }
591a7694eead7cbb293990bc89c3906e17bad36194cErik
592eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // This is called if the user clicks on one of the buttons: "Save",
593eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // "Discard", or "Delete". This is also called if the user clicks
594eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // on the "remove reminder" button.
5959645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    @Override
596bdcb9fcc732d52708fafb068f535a2c93ff2356fDaisuke Miyakawa    public void onClick(View view) {
597b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (view == mRruleButton) {
598b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Bundle b = new Bundle();
599b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            b.putLong(RecurrencePickerDialog.BUNDLE_START_TIME_MILLIS,
600b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mStartTime.toMillis(false));
601b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            b.putString(RecurrencePickerDialog.BUNDLE_TIME_ZONE, mStartTime.timezone);
602b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
603b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            // TODO may be more efficient to serialize and pass in EventRecurrence
604b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            b.putString(RecurrencePickerDialog.BUNDLE_RRULE, mRrule);
605b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
606b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            FragmentManager fm = mActivity.getFragmentManager();
607b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            RecurrencePickerDialog rpd = (RecurrencePickerDialog) fm
608b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    .findFragmentByTag(FRAG_TAG_RECUR_PICKER);
609b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (rpd != null) {
610b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                rpd.dismiss();
611b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
612b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rpd = new RecurrencePickerDialog();
613b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rpd.setArguments(b);
614b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rpd.setOnRecurrenceSetListener(EditEventView.this);
615b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rpd.show(fm, FRAG_TAG_RECUR_PICKER);
616b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return;
617b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
618eca82e9468c002590045338f98588ad3ce1a0bb3Erik
619eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // This must be a click on one of the "remove reminder" buttons
620bdcb9fcc732d52708fafb068f535a2c93ff2356fDaisuke Miyakawa        LinearLayout reminderItem = (LinearLayout) view.getParent();
621eca82e9468c002590045338f98588ad3ce1a0bb3Erik        LinearLayout parent = (LinearLayout) reminderItem.getParent();
622eca82e9468c002590045338f98588ad3ce1a0bb3Erik        parent.removeView(reminderItem);
623eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mReminderItems.remove(reminderItem);
624eca82e9468c002590045338f98588ad3ce1a0bb3Erik        updateRemindersVisibility(mReminderItems.size());
62506f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting        EventViewUtils.updateAddReminderButton(mView, mReminderItems, mModel.mCalendarMaxReminders);
626eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
627eca82e9468c002590045338f98588ad3ce1a0bb3Erik
628b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
629b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onRecurrenceSet(String rrule) {
630b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        Log.d(TAG, "Old rrule:" + mRrule);
631b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        Log.d(TAG, "New rrule:" + rrule);
632b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRrule = rrule;
633b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mRrule != null) {
634b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEventRecurrence.parse(mRrule);
635b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
636b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        populateRepeats();
637b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
638b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
639eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // This is called if the user cancels the "No calendars" dialog.
640eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // The "No calendars" dialog is shown if there are no syncable calendars.
641ddbf80860566df8425f38a32190e9a64cad4e389Michael Chan    @Override
642eca82e9468c002590045338f98588ad3ce1a0bb3Erik    public void onCancel(DialogInterface dialog) {
643eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (dialog == mLoadingCalendarsDialog) {
644eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mLoadingCalendarsDialog = null;
645eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mSaveAfterQueryComplete = false;
646eca82e9468c002590045338f98588ad3ce1a0bb3Erik        } else if (dialog == mNoCalendarsDialog) {
64779f228124de7d98146ca526d743436f6419e2365Erik            mDone.setDoneCode(Utils.DONE_REVERT);
64879f228124de7d98146ca526d743436f6419e2365Erik            mDone.run();
649eca82e9468c002590045338f98588ad3ce1a0bb3Erik            return;
650eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
651eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
652eca82e9468c002590045338f98588ad3ce1a0bb3Erik
653eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // This is called if the user clicks on a dialog button.
654bdcb9fcc732d52708fafb068f535a2c93ff2356fDaisuke Miyakawa    @Override
655eca82e9468c002590045338f98588ad3ce1a0bb3Erik    public void onClick(DialogInterface dialog, int which) {
656eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (dialog == mNoCalendarsDialog) {
65779f228124de7d98146ca526d743436f6419e2365Erik            mDone.setDoneCode(Utils.DONE_REVERT);
65879f228124de7d98146ca526d743436f6419e2365Erik            mDone.run();
659464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa            if (which == DialogInterface.BUTTON_POSITIVE) {
660464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa                Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT);
661464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa                final String[] array = {"com.android.calendar"};
662464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa                nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array);
66315b4dcc873336ceb35fa335410b467aed3a834eaRoboErik                nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
664464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa                mActivity.startActivity(nextIntent);
665464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa            }
666eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
667eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
668eca82e9468c002590045338f98588ad3ce1a0bb3Erik
669eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // Goes through the UI elements and updates the model as necessary
670ddbf80860566df8425f38a32190e9a64cad4e389Michael Chan    private boolean fillModelFromUI() {
671eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (mModel == null) {
672eca82e9468c002590045338f98588ad3ce1a0bb3Erik            return false;
673eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
6749645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mReminders = EventViewUtils.reminderItemsToReminders(mReminderItems,
6759645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                mReminderMinuteValues, mReminderMethodValues);
676e35a032c939f357ce435711b2fd8de1887a05011RoboErik        mModel.mReminders.addAll(mUnsupportedReminders);
677e35a032c939f357ce435711b2fd8de1887a05011RoboErik        mModel.normalizeReminders();
678eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mModel.mHasAlarm = mReminderItems.size() > 0;
6797858f779a913761dd85ee4892168a960790dfeb1Michael Chan        mModel.mTitle = mTitleTextView.getText().toString();
680eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mModel.mAllDay = mAllDayCheckBox.isChecked();
6817858f779a913761dd85ee4892168a960790dfeb1Michael Chan        mModel.mLocation = mLocationTextView.getText().toString();
6827858f779a913761dd85ee4892168a960790dfeb1Michael Chan        mModel.mDescription = mDescriptionTextView.getText().toString();
683cfa4b5b79cc0ce632b654c7e449250ec0bc442eaErik        if (TextUtils.isEmpty(mModel.mLocation)) {
684cfa4b5b79cc0ce632b654c7e449250ec0bc442eaErik            mModel.mLocation = null;
685cfa4b5b79cc0ce632b654c7e449250ec0bc442eaErik        }
686cfa4b5b79cc0ce632b654c7e449250ec0bc442eaErik        if (TextUtils.isEmpty(mModel.mDescription)) {
687cfa4b5b79cc0ce632b654c7e449250ec0bc442eaErik            mModel.mDescription = null;
688cfa4b5b79cc0ce632b654c7e449250ec0bc442eaErik        }
689f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan
690f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        int status = EventInfoFragment.getResponseFromButtonId(mResponseRadioGroup
691f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                .getCheckedRadioButtonId());
692f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        if (status != Attendees.ATTENDEE_STATUS_NONE) {
693f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            mModel.mSelfAttendeeStatus = status;
694d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        }
695d845fbe558d5229102b58cce70a1b29fe6cb6967Erik
696e0e2a4fd0f9e1b31c08610cf83176d61cf1b0749RoboErik        if (mAttendeesList != null) {
6976a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik            mEmailValidator.setRemoveInvalid(true);
6986a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik            mAttendeesList.performValidation();
699e0e2a4fd0f9e1b31c08610cf83176d61cf1b0749RoboErik            mModel.mAttendeesList.clear();
7006a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik            mModel.addAttendees(mAttendeesList.getText().toString(), mEmailValidator);
701e0e2a4fd0f9e1b31c08610cf83176d61cf1b0749RoboErik            mEmailValidator.setRemoveInvalid(false);
702eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
703eca82e9468c002590045338f98588ad3ce1a0bb3Erik
704eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // If this was a new event we need to fill in the Calendar information
705eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (mModel.mUri == null) {
706eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mModel.mCalendarId = mCalendarsSpinner.getSelectedItemId();
707eca82e9468c002590045338f98588ad3ce1a0bb3Erik            int calendarCursorPosition = mCalendarsSpinner.getSelectedItemPosition();
708eca82e9468c002590045338f98588ad3ce1a0bb3Erik            if (mCalendarsCursor.moveToPosition(calendarCursorPosition)) {
7097b92da258a480284dcc15a518ea570072329a31dErik                String defaultCalendar = mCalendarsCursor.getString(
7107b92da258a480284dcc15a518ea570072329a31dErik                        EditEventHelper.CALENDARS_INDEX_OWNER_ACCOUNT);
7117b92da258a480284dcc15a518ea570072329a31dErik                Utils.setSharedPreference(
7127b92da258a480284dcc15a518ea570072329a31dErik                        mActivity, GeneralPreferences.KEY_DEFAULT_CALENDAR, defaultCalendar);
713eca82e9468c002590045338f98588ad3ce1a0bb3Erik                mModel.mOwnerAccount = defaultCalendar;
714eca82e9468c002590045338f98588ad3ce1a0bb3Erik                mModel.mOrganizer = defaultCalendar;
715eca82e9468c002590045338f98588ad3ce1a0bb3Erik                mModel.mCalendarId = mCalendarsCursor.getLong(EditEventHelper.CALENDARS_INDEX_ID);
716eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
717eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
718eca82e9468c002590045338f98588ad3ce1a0bb3Erik
719eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (mModel.mAllDay) {
720eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Reset start and end time, increment the monthDay by 1, and set
721eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // the timezone to UTC, as required for all-day events.
7224c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mTimezone = Time.TIMEZONE_UTC;
723eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mStartTime.hour = 0;
724eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mStartTime.minute = 0;
725eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mStartTime.second = 0;
7264c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mStartTime.timezone = mTimezone;
727eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mModel.mStart = mStartTime.normalize(true);
728eca82e9468c002590045338f98588ad3ce1a0bb3Erik
729eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mEndTime.hour = 0;
730eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mEndTime.minute = 0;
731eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mEndTime.second = 0;
7324c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mEndTime.timezone = mTimezone;
73329190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa            // When a user see the event duration as "X - Y" (e.g. Oct. 28 - Oct. 29), end time
73429190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa            // should be Y + 1 (Oct.30).
73529190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa            final long normalizedEndTimeMillis =
73629190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa                    mEndTime.normalize(true) + DateUtils.DAY_IN_MILLIS;
73729190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa            if (normalizedEndTimeMillis < mModel.mStart) {
73829190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa                // mEnd should be midnight of the next day of mStart.
73929190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa                mModel.mEnd = mModel.mStart + DateUtils.DAY_IN_MILLIS;
74029190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa            } else {
74129190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa                mModel.mEnd = normalizedEndTimeMillis;
74229190975b9238dd6841f822f82f2fb83b0557f36Daisuke Miyakawa            }
743eca82e9468c002590045338f98588ad3ce1a0bb3Erik        } else {
7444c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mStartTime.timezone = mTimezone;
7454c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mEndTime.timezone = mTimezone;
746eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mModel.mStart = mStartTime.toMillis(true);
747eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mModel.mEnd = mEndTime.toMillis(true);
748eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
7494c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        mModel.mTimezone = mTimezone;
750ced0eb67ef49c3203f72520c296e73d9cb4f654bMichael Chan        mModel.mAccessLevel = mAccessLevelSpinner.getSelectedItemPosition();
751c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        // TODO set correct availability value
752c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        mModel.mAvailability = mAvailabilityValues.get(mAvailabilitySpinner
753c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik                .getSelectedItemPosition());
754eca82e9468c002590045338f98588ad3ce1a0bb3Erik
755b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // rrrule
756eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // If we're making an exception we don't want it to be a repeating
757eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // event.
758eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (mModification == EditEventHelper.MODIFY_SELECTED) {
759b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.mRrule = null;
760eca82e9468c002590045338f98588ad3ce1a0bb3Erik        } else {
761b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.mRrule = mRrule;
762eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
763eca82e9468c002590045338f98588ad3ce1a0bb3Erik
764eca82e9468c002590045338f98588ad3ce1a0bb3Erik        return true;
765eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
766eca82e9468c002590045338f98588ad3ce1a0bb3Erik
7677674b690b018c31207830c2a196927a0c654486cSam Blitzstein    public EditEventView(Activity activity, View view, EditDoneRunnable done,
76856f42bfb36d710726051e8268a115697477add61James Kung            boolean timeSelectedWasStartTime, boolean dateSelectedWasStartDate) {
769eca82e9468c002590045338f98588ad3ce1a0bb3Erik
770eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mActivity = activity;
771eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mView = view;
77279f228124de7d98146ca526d743436f6419e2365Erik        mDone = done;
773eca82e9468c002590045338f98588ad3ce1a0bb3Erik
774eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // cache top level view elements
775eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mLoadingMessage = (TextView) view.findViewById(R.id.loading_message);
776eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mScrollView = (ScrollView) view.findViewById(R.id.scroll_view);
777eca82e9468c002590045338f98588ad3ce1a0bb3Erik
778eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // cache all the widgets
7799d5f351e45e20ff04da6f9118031cc2cc7419905Michael Chan        mCalendarsSpinner = (Spinner) view.findViewById(R.id.calendars_spinner);
780d19fa1c8b79d93473157e80911ff12c6283c1b03Sara Ting        mTitleTextView = (TextView) view.findViewById(R.id.title);
7814686b4065af0137f5d6ff7570d867fed562c8120Sara Ting        mLocationTextView = (AutoCompleteTextView) view.findViewById(R.id.location);
782eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mDescriptionTextView = (TextView) view.findViewById(R.id.description);
78324ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        mTimezoneLabel = (TextView) view.findViewById(R.id.timezone_label);
784eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mStartDateButton = (Button) view.findViewById(R.id.start_date);
785eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mEndDateButton = (Button) view.findViewById(R.id.end_date);
78624ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        mWhenView = (TextView) mView.findViewById(R.id.when);
78724ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        mTimezoneTextView = (TextView) mView.findViewById(R.id.timezone_textView);
788eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mStartTimeButton = (Button) view.findViewById(R.id.start_time);
789eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mEndTimeButton = (Button) view.findViewById(R.id.end_time);
79024ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        mTimezoneButton = (Button) view.findViewById(R.id.timezone_button);
791e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        mTimezoneButton.setOnClickListener(new View.OnClickListener() {
792e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan            @Override
793e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan            public void onClick(View v) {
794e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan                showTimezoneDialog();
795e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan            }
796e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        });
797b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan        mTimezoneRow = view.findViewById(R.id.timezone_button_row);
798476ba39083f5f348f7afedfb957215a806593b07Isaac Katzenelson        mStartTimeHome = (TextView) view.findViewById(R.id.start_time_home_tz);
799476ba39083f5f348f7afedfb957215a806593b07Isaac Katzenelson        mStartDateHome = (TextView) view.findViewById(R.id.start_date_home_tz);
800476ba39083f5f348f7afedfb957215a806593b07Isaac Katzenelson        mEndTimeHome = (TextView) view.findViewById(R.id.end_time_home_tz);
801476ba39083f5f348f7afedfb957215a806593b07Isaac Katzenelson        mEndDateHome = (TextView) view.findViewById(R.id.end_date_home_tz);
802eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mAllDayCheckBox = (CheckBox) view.findViewById(R.id.is_all_day);
803b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRruleButton = (Button) view.findViewById(R.id.rrule);
804ced0eb67ef49c3203f72520c296e73d9cb4f654bMichael Chan        mAvailabilitySpinner = (Spinner) view.findViewById(R.id.availability);
805ced0eb67ef49c3203f72520c296e73d9cb4f654bMichael Chan        mAccessLevelSpinner = (Spinner) view.findViewById(R.id.visibility);
806c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mCalendarSelectorGroup = view.findViewById(R.id.calendar_selector_group);
807eb51f84a9d77b1d7c2d407b1f594b7e281e277ccMindy Pereira        mCalendarSelectorWrapper = view.findViewById(R.id.calendar_selector_wrapper);
808c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mCalendarStaticGroup = view.findViewById(R.id.calendar_group);
809c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mRemindersGroup = view.findViewById(R.id.reminders_row);
810c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mResponseGroup = view.findViewById(R.id.response_row);
811c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mOrganizerGroup = view.findViewById(R.id.organizer_row);
8121ab41bfed7be237a4a88a52535b21d202cdacd8aMichael Chan        mAttendeesGroup = view.findViewById(R.id.add_attendees_row);
813a7694eead7cbb293990bc89c3906e17bad36194cErik        mLocationGroup = view.findViewById(R.id.where_row);
814a7694eead7cbb293990bc89c3906e17bad36194cErik        mDescriptionGroup = view.findViewById(R.id.description_row);
815476ba39083f5f348f7afedfb957215a806593b07Isaac Katzenelson        mStartHomeGroup = view.findViewById(R.id.from_row_home_tz);
816476ba39083f5f348f7afedfb957215a806593b07Isaac Katzenelson        mEndHomeGroup = view.findViewById(R.id.to_row_home_tz);
8176a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        mAttendeesList = (MultiAutoCompleteTextView) view.findViewById(R.id.attendees);
818c07a57fb7436d807ad505fa7319b9de13f91e741Erik
8194afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        mColorPickerNewEvent = view.findViewById(R.id.change_color_new_event);
8204afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        mColorPickerExistingEvent = view.findViewById(R.id.change_color_existing_event);
8214afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung
822efa480cc0733071f311ccb27806916de5efff71cErik        mTitleTextView.setTag(mTitleTextView.getBackground());
823efa480cc0733071f311ccb27806916de5efff71cErik        mLocationTextView.setTag(mLocationTextView.getBackground());
8244686b4065af0137f5d6ff7570d867fed562c8120Sara Ting        mLocationAdapter = new EventLocationAdapter(activity);
8254686b4065af0137f5d6ff7570d867fed562c8120Sara Ting        mLocationTextView.setAdapter(mLocationAdapter);
8264686b4065af0137f5d6ff7570d867fed562c8120Sara Ting        mLocationTextView.setOnEditorActionListener(new OnEditorActionListener() {
8274686b4065af0137f5d6ff7570d867fed562c8120Sara Ting            @Override
8284686b4065af0137f5d6ff7570d867fed562c8120Sara Ting            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
8294686b4065af0137f5d6ff7570d867fed562c8120Sara Ting                if (actionId == EditorInfo.IME_ACTION_DONE) {
8304686b4065af0137f5d6ff7570d867fed562c8120Sara Ting                    // Dismiss the suggestions dropdown.  Return false so the other
8314686b4065af0137f5d6ff7570d867fed562c8120Sara Ting                    // side effects still occur (soft keyboard going away, etc.).
8324686b4065af0137f5d6ff7570d867fed562c8120Sara Ting                    mLocationTextView.dismissDropDown();
8334686b4065af0137f5d6ff7570d867fed562c8120Sara Ting                }
8344686b4065af0137f5d6ff7570d867fed562c8120Sara Ting                return false;
8354686b4065af0137f5d6ff7570d867fed562c8120Sara Ting            }
8364686b4065af0137f5d6ff7570d867fed562c8120Sara Ting        });
8374686b4065af0137f5d6ff7570d867fed562c8120Sara Ting
8387cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAvailabilityExplicitlySet = false;
8397cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAllDayChangingAvailability = false;
8407cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAvailabilityCurrentlySelected = -1;
8417cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAvailabilitySpinner.setOnItemSelectedListener(
8427cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                new OnItemSelectedListener() {
8437cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            @Override
8447cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            public void onItemSelected(AdapterView<?> parent,
8457cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                    View view, int position, long id) {
8467cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // The spinner's onItemSelected gets called while it is being
8477cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // initialized to the first item, and when we explicitly set it
8487cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // in the allDay checkbox toggling, so we need these checks to
8497cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // find out when the spinner is actually being clicked.
8507cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein
8517cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // Set the initial selection.
8527cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                if (mAvailabilityCurrentlySelected == -1) {
8537cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                    mAvailabilityCurrentlySelected = position;
8547cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                }
8557cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein
8567cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                if (mAvailabilityCurrentlySelected != position &&
8577cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                        !mAllDayChangingAvailability) {
8587cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                    mAvailabilityExplicitlySet = true;
8597cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                } else {
8607cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                    mAvailabilityCurrentlySelected = position;
8617cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                    mAllDayChangingAvailability = false;
8627cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                }
8637cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            }
8647cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            @Override
8657cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            public void onNothingSelected(AdapterView<?> arg0) { }
8667cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        });
8677cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein
8684686b4065af0137f5d6ff7570d867fed562c8120Sara Ting
869efa480cc0733071f311ccb27806916de5efff71cErik        mDescriptionTextView.setTag(mDescriptionTextView.getBackground());
8706a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        mAttendeesList.setTag(mAttendeesList.getBackground());
871efa480cc0733071f311ccb27806916de5efff71cErik        mOriginalPadding[0] = mLocationTextView.getPaddingLeft();
872efa480cc0733071f311ccb27806916de5efff71cErik        mOriginalPadding[1] = mLocationTextView.getPaddingTop();
873efa480cc0733071f311ccb27806916de5efff71cErik        mOriginalPadding[2] = mLocationTextView.getPaddingRight();
874efa480cc0733071f311ccb27806916de5efff71cErik        mOriginalPadding[3] = mLocationTextView.getPaddingBottom();
875c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditViewList.add(mTitleTextView);
876c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditViewList.add(mLocationTextView);
877c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditViewList.add(mDescriptionTextView);
8786a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        mEditViewList.add(mAttendeesList);
879c07a57fb7436d807ad505fa7319b9de13f91e741Erik
880c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mViewOnlyList.add(view.findViewById(R.id.when_row));
881c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mViewOnlyList.add(view.findViewById(R.id.timezone_textview_row));
882c07a57fb7436d807ad505fa7319b9de13f91e741Erik
883c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditOnlyList.add(view.findViewById(R.id.all_day_row));
884c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditOnlyList.add(view.findViewById(R.id.availability_row));
885c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditOnlyList.add(view.findViewById(R.id.visibility_row));
886c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditOnlyList.add(view.findViewById(R.id.from_row));
887c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mEditOnlyList.add(view.findViewById(R.id.to_row));
888b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan        mEditOnlyList.add(mTimezoneRow);
8898a5489641442c022089ae1b00e498e2c1a0ba480Erik        mEditOnlyList.add(mStartHomeGroup);
8908a5489641442c022089ae1b00e498e2c1a0ba480Erik        mEditOnlyList.add(mEndHomeGroup);
891352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
892f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan        mResponseRadioGroup = (RadioGroup) view.findViewById(R.id.response_value);
893eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mRemindersContainer = (LinearLayout) view.findViewById(R.id.reminder_items_container);
894eca82e9468c002590045338f98588ad3ce1a0bb3Erik
8958a5489641442c022089ae1b00e498e2c1a0ba480Erik        mTimezone = Utils.getTimeZone(activity, null);
8963a002717f71bf66b1d056c674a14963ec9f80fa8RoboErik        mIsMultipane = activity.getResources().getBoolean(R.bool.tablet_config);
8978a5489641442c022089ae1b00e498e2c1a0ba480Erik        mStartTime = new Time(mTimezone);
8988a5489641442c022089ae1b00e498e2c1a0ba480Erik        mEndTime = new Time(mTimezone);
8996a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        mEmailValidator = new Rfc822Validator(null);
9006a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        initMultiAutoCompleteTextView((RecipientEditTextView) mAttendeesList);
901eca82e9468c002590045338f98588ad3ce1a0bb3Erik
902eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // Display loading screen
903eca82e9468c002590045338f98588ad3ce1a0bb3Erik        setModel(null);
904b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
905b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        FragmentManager fm = activity.getFragmentManager();
906b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        RecurrencePickerDialog rpd = (RecurrencePickerDialog) fm
907b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                .findFragmentByTag(FRAG_TAG_RECUR_PICKER);
908b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (rpd != null) {
909b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rpd.setOnRecurrenceSetListener(this);
910b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
911e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        TimeZonePickerDialog tzpd = (TimeZonePickerDialog) fm
912e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan                .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER);
913e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        if (tzpd != null) {
914e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan            tzpd.setOnTimeZoneSetListener(this);
915e6aa93773f2132900f019fbbf203db4c30c5b254Michael Chan        }
9167674b690b018c31207830c2a196927a0c654486cSam Blitzstein        TimePickerDialog tpd = (TimePickerDialog) fm.findFragmentByTag(FRAG_TAG_TIME_PICKER);
9177674b690b018c31207830c2a196927a0c654486cSam Blitzstein        if (tpd != null) {
9187674b690b018c31207830c2a196927a0c654486cSam Blitzstein            View v;
9197674b690b018c31207830c2a196927a0c654486cSam Blitzstein            mTimeSelectedWasStartTime = timeSelectedWasStartTime;
9207674b690b018c31207830c2a196927a0c654486cSam Blitzstein            if (timeSelectedWasStartTime) {
9217674b690b018c31207830c2a196927a0c654486cSam Blitzstein                v = mStartTimeButton;
9227674b690b018c31207830c2a196927a0c654486cSam Blitzstein            } else {
9237674b690b018c31207830c2a196927a0c654486cSam Blitzstein                v = mEndTimeButton;
9247674b690b018c31207830c2a196927a0c654486cSam Blitzstein            }
9257674b690b018c31207830c2a196927a0c654486cSam Blitzstein            tpd.setOnTimeSetListener(new TimeListener(v));
9267674b690b018c31207830c2a196927a0c654486cSam Blitzstein        }
92756f42bfb36d710726051e8268a115697477add61James Kung        mDatePickerDialog = (DatePickerDialog) fm.findFragmentByTag(FRAG_TAG_DATE_PICKER);
92856f42bfb36d710726051e8268a115697477add61James Kung        if (mDatePickerDialog != null) {
92956f42bfb36d710726051e8268a115697477add61James Kung            View v;
93056f42bfb36d710726051e8268a115697477add61James Kung            mDateSelectedWasStartDate = dateSelectedWasStartDate;
93156f42bfb36d710726051e8268a115697477add61James Kung            if (dateSelectedWasStartDate) {
93256f42bfb36d710726051e8268a115697477add61James Kung                v = mStartDateButton;
93356f42bfb36d710726051e8268a115697477add61James Kung            } else {
93456f42bfb36d710726051e8268a115697477add61James Kung                v = mEndDateButton;
93556f42bfb36d710726051e8268a115697477add61James Kung            }
93656f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.setOnDateSetListener(new DateListener(v));
93756f42bfb36d710726051e8268a115697477add61James Kung        }
938eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
939eca82e9468c002590045338f98588ad3ce1a0bb3Erik
9409645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
9419645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    /**
9429645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * Loads an integer array asset into a list.
9439645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     */
9449645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    private static ArrayList<Integer> loadIntegerArray(Resources r, int resNum) {
9459645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        int[] vals = r.getIntArray(resNum);
9469645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        int size = vals.length;
9479645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        ArrayList<Integer> list = new ArrayList<Integer>(size);
9489645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
9499645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        for (int i = 0; i < size; i++) {
9509645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            list.add(vals[i]);
9519645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        }
9529645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
9539645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        return list;
9549645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    }
9559645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
9569645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    /**
9579645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * Loads a String array asset into a list.
9589645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     */
9599645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    private static ArrayList<String> loadStringArray(Resources r, int resNum) {
9609645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        String[] labels = r.getStringArray(resNum);
9619645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        ArrayList<String> list = new ArrayList<String>(Arrays.asList(labels));
9629645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        return list;
9639645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    }
9649645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
965c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik    private void prepareAvailability() {
966c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        Resources r = mActivity.getResources();
967c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik
968c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        mAvailabilityValues = loadIntegerArray(r, R.array.availability_values);
969c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        mAvailabilityLabels = loadStringArray(r, R.array.availability);
9707cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        // Copy the unadulterated availability labels for all-day toggling.
9717cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mOriginalAvailabilityLabels = new ArrayList<String>();
9727cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mOriginalAvailabilityLabels.addAll(mAvailabilityLabels);
973c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik
974c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        if (mModel.mCalendarAllowedAvailability != null) {
975c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik            EventViewUtils.reduceMethodList(mAvailabilityValues, mAvailabilityLabels,
976c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik                    mModel.mCalendarAllowedAvailability);
977c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        }
978c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik
9797cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAvailabilityAdapter = new ArrayAdapter<String>(mActivity,
980c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik                android.R.layout.simple_spinner_item, mAvailabilityLabels);
9817cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAvailabilityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
9827cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        mAvailabilitySpinner.setAdapter(mAvailabilityAdapter);
983c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik    }
984c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik
9859645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    /**
9869645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * Prepares the reminder UI elements.
9879645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * <p>
9889645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * (Re-)loads the minutes / methods lists from the XML assets, adds/removes items as
9899645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * needed for the current set of reminders and calendar properties, and then creates UI
9909645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * elements.
9919645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     */
9929645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    private void prepareReminders() {
9939645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        CalendarEventModel model = mModel;
9949645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        Resources r = mActivity.getResources();
9959645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
9969645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // Load the labels and corresponding numeric values for the minutes and methods lists
9979645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // from the assets.  If we're switching calendars, we need to clear and re-populate the
9989645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // lists (which may have elements added and removed based on calendar properties).  This
9999645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // is mostly relevant for "methods", since we shouldn't have any "minutes" values in a
10009645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // new event that aren't in the default set.
10019645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mReminderMinuteValues = loadIntegerArray(r, R.array.reminder_minutes_values);
10029645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mReminderMinuteLabels = loadStringArray(r, R.array.reminder_minutes_labels);
10039645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mReminderMethodValues = loadIntegerArray(r, R.array.reminder_methods_values);
10049645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mReminderMethodLabels = loadStringArray(r, R.array.reminder_methods_labels);
10059645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
10069645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // Remove any reminder methods that aren't allowed for this calendar.  If this is
10079645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // a new event, mCalendarAllowedReminders may not be set the first time we're called.
10089645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        if (mModel.mCalendarAllowedReminders != null) {
10099645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            EventViewUtils.reduceMethodList(mReminderMethodValues, mReminderMethodLabels,
10109645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                    mModel.mCalendarAllowedReminders);
10119645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        }
10129645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
10139645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        int numReminders = 0;
10149645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        if (model.mHasAlarm) {
10159645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            ArrayList<ReminderEntry> reminders = model.mReminders;
10169645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            numReminders = reminders.size();
10179645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            // Insert any minute values that aren't represented in the minutes list.
10189645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            for (ReminderEntry re : reminders) {
1019e35a032c939f357ce435711b2fd8de1887a05011RoboErik                if (mReminderMethodValues.contains(re.getMethod())) {
1020e35a032c939f357ce435711b2fd8de1887a05011RoboErik                    EventViewUtils.addMinutesToList(mActivity, mReminderMinuteValues,
1021e35a032c939f357ce435711b2fd8de1887a05011RoboErik                            mReminderMinuteLabels, re.getMinutes());
1022e35a032c939f357ce435711b2fd8de1887a05011RoboErik                }
10239645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            }
10249645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
10259645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            // Create a UI element for each reminder.  We display all of the reminders we get
10269645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            // from the provider, even if the count exceeds the calendar maximum.  (Also, for
10279645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            // a new event, we won't have a maxReminders value available.)
1028e35a032c939f357ce435711b2fd8de1887a05011RoboErik            mUnsupportedReminders.clear();
10299645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            for (ReminderEntry re : reminders) {
1030cabc41aacbf721b1aae03cf0a5eac21291c48ca1RoboErik                if (mReminderMethodValues.contains(re.getMethod())
1031cabc41aacbf721b1aae03cf0a5eac21291c48ca1RoboErik                        || re.getMethod() == Reminders.METHOD_DEFAULT) {
1032e35a032c939f357ce435711b2fd8de1887a05011RoboErik                    EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderItems,
1033e35a032c939f357ce435711b2fd8de1887a05011RoboErik                            mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues,
10348b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                            mReminderMethodLabels, re, Integer.MAX_VALUE, null);
1035e35a032c939f357ce435711b2fd8de1887a05011RoboErik                } else {
1036e35a032c939f357ce435711b2fd8de1887a05011RoboErik                    // TODO figure out a way to display unsupported reminders
1037e35a032c939f357ce435711b2fd8de1887a05011RoboErik                    mUnsupportedReminders.add(re);
1038e35a032c939f357ce435711b2fd8de1887a05011RoboErik                }
10399645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            }
10409645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        }
10419645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
10429645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        updateRemindersVisibility(numReminders);
104306f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting        EventViewUtils.updateAddReminderButton(mView, mReminderItems, mModel.mCalendarMaxReminders);
10449645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    }
10459645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
1046eca82e9468c002590045338f98588ad3ce1a0bb3Erik    /**
1047eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * Fill in the view with the contents of the given event model. This allows
1048eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * an edit view to be initialized before the event has been loaded. Passing
1049eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * in null for the model will display a loading screen. A non-null model
1050eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * will fill in the view's fields with the data contained in the model.
1051eca82e9468c002590045338f98588ad3ce1a0bb3Erik     *
1052eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * @param model The event model to pull the data from
1053eca82e9468c002590045338f98588ad3ce1a0bb3Erik     */
1054eca82e9468c002590045338f98588ad3ce1a0bb3Erik    public void setModel(CalendarEventModel model) {
1055eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mModel = model;
1056ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov
1057ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov        // Need to close the autocomplete adapter to prevent leaking cursors.
105818cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira        if (mAddressAdapter != null && mAddressAdapter instanceof EmailAddressAdapter) {
105918cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira            ((EmailAddressAdapter)mAddressAdapter).close();
1060ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov            mAddressAdapter = null;
1061ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov        }
1062ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov
1063eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (model == null) {
1064eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Display loading screen
1065eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mLoadingMessage.setVisibility(View.VISIBLE);
1066eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mScrollView.setVisibility(View.GONE);
1067eca82e9468c002590045338f98588ad3ce1a0bb3Erik            return;
1068eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1069eca82e9468c002590045338f98588ad3ce1a0bb3Erik
107018a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan        boolean canRespond = EditEventHelper.canRespond(model);
107118a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan
1072eca82e9468c002590045338f98588ad3ce1a0bb3Erik        long begin = model.mStart;
1073eca82e9468c002590045338f98588ad3ce1a0bb3Erik        long end = model.mEnd;
107486cdba65209669c5c95015263ff65d178a4196b4Mason Tang        mTimezone = model.mTimezone; // this will be UTC for all day events
1075eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1076eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // Set up the starting times
1077eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (begin > 0) {
10784c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mStartTime.timezone = mTimezone;
1079eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mStartTime.set(begin);
1080eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mStartTime.normalize(true);
1081eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1082eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (end > 0) {
10834c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            mEndTime.timezone = mTimezone;
1084eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mEndTime.set(end);
1085eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mEndTime.normalize(true);
1086eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1087b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1088b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRrule = model.mRrule;
1089b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (!TextUtils.isEmpty(mRrule)) {
1090b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEventRecurrence.parse(mRrule);
1091b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1092b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1093b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mEventRecurrence.startDate == null) {
1094b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEventRecurrence.startDate = mStartTime;
1095eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1096eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1097eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // If the user is allowed to change the attendees set up the view and
1098eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // validator
1099352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        if (!model.mHasAttendeeData) {
11006a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik            mAttendeesGroup.setVisibility(View.GONE);
1101eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1102eca82e9468c002590045338f98588ad3ce1a0bb3Erik
110324ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        mAllDayCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
11049645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            @Override
110524ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1106c07a57fb7436d807ad505fa7319b9de13f91e741Erik                setAllDayViewsVisibility(isChecked);
110724ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan            }
110824ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        });
1109eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1110e8e0fc6b5d85b293514c3641e310407635dd2f9aRoboErik        boolean prevAllDay = mAllDayCheckBox.isChecked();
11118b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan        mAllDay = false; // default to false. Let setAllDayViewsVisibility update it as needed
1112eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (model.mAllDay) {
1113eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mAllDayCheckBox.setChecked(true);
111486cdba65209669c5c95015263ff65d178a4196b4Mason Tang            // put things back in local time for all day events
1115559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan            mTimezone = Utils.getTimeZone(mActivity, null);
111686cdba65209669c5c95015263ff65d178a4196b4Mason Tang            mStartTime.timezone = mTimezone;
111786cdba65209669c5c95015263ff65d178a4196b4Mason Tang            mEndTime.timezone = mTimezone;
111886cdba65209669c5c95015263ff65d178a4196b4Mason Tang            mEndTime.normalize(true);
1119eca82e9468c002590045338f98588ad3ce1a0bb3Erik        } else {
1120eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mAllDayCheckBox.setChecked(false);
1121eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1122e8e0fc6b5d85b293514c3641e310407635dd2f9aRoboErik        // On a rotation we need to update the views but onCheckedChanged
1123e8e0fc6b5d85b293514c3641e310407635dd2f9aRoboErik        // doesn't get called
1124e8e0fc6b5d85b293514c3641e310407635dd2f9aRoboErik        if (prevAllDay == mAllDayCheckBox.isChecked()) {
1125e8e0fc6b5d85b293514c3641e310407635dd2f9aRoboErik            setAllDayViewsVisibility(prevAllDay);
1126e8e0fc6b5d85b293514c3641e310407635dd2f9aRoboErik        }
1127eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1128559cb86bf1aa43c0a9cba7a4c7297d8d6d3a33f8Michael Chan        populateTimezone(mStartTime.normalize(true));
112986cdba65209669c5c95015263ff65d178a4196b4Mason Tang
11304b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa        SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity);
11319d8a376b89fcc36c44d4df0c5cbf6991306131c4Michael Chan        String defaultReminderString = prefs.getString(
11329d8a376b89fcc36c44d4df0c5cbf6991306131c4Michael Chan                GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING);
11339d8a376b89fcc36c44d4df0c5cbf6991306131c4Michael Chan        mDefaultReminderMinutes = Integer.parseInt(defaultReminderString);
1134eca82e9468c002590045338f98588ad3ce1a0bb3Erik
11359645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        prepareReminders();
1136c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        prepareAvailability();
1137eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1138b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan        View reminderAddButton = mView.findViewById(R.id.reminder_add);
1139eca82e9468c002590045338f98588ad3ce1a0bb3Erik        View.OnClickListener addReminderOnClickListener = new View.OnClickListener() {
11409645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            @Override
1141eca82e9468c002590045338f98588ad3ce1a0bb3Erik            public void onClick(View v) {
1142eca82e9468c002590045338f98588ad3ce1a0bb3Erik                addReminder();
1143eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
1144eca82e9468c002590045338f98588ad3ce1a0bb3Erik        };
1145352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        reminderAddButton.setOnClickListener(addReminderOnClickListener);
1146eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1147b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan        if (!mIsMultipane) {
1148b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan            mView.findViewById(R.id.is_all_day_label).setOnClickListener(
1149b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan                    new View.OnClickListener() {
1150b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan                        @Override
1151b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan                        public void onClick(View v) {
1152b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan                            mAllDayCheckBox.setChecked(!mAllDayCheckBox.isChecked());
1153b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan                        }
1154b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan                    });
1155b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan        }
1156b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan
1157b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan        if (model.mTitle != null) {
1158b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan            mTitleTextView.setTextKeepState(model.mTitle);
1159b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan        }
1160b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan
1161352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        if (model.mIsOrganizer || TextUtils.isEmpty(model.mOrganizer)
1162352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                || model.mOrganizer.endsWith(GOOGLE_SECONDARY_CALENDAR)) {
1163352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            mView.findViewById(R.id.organizer_label).setVisibility(View.GONE);
1164352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            mView.findViewById(R.id.organizer).setVisibility(View.GONE);
11652e46cff640b123ba5f7a67c934ae98e6b02a905fIsaac Katzenelson            mOrganizerGroup.setVisibility(View.GONE);
1166352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        } else {
1167352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            ((TextView) mView.findViewById(R.id.organizer)).setText(model.mOrganizerDisplayName);
1168352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        }
1169b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan
1170b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan        if (model.mLocation != null) {
1171b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan            mLocationTextView.setTextKeepState(model.mLocation);
1172b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan        }
1173b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan
1174b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan        if (model.mDescription != null) {
1175b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan            mDescriptionTextView.setTextKeepState(model.mDescription);
1176b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan        }
1177b7c1fcc5c79d094ee981b3e18f6e60d11ab3ec6cMichael Chan
1178c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        int availIndex = mAvailabilityValues.indexOf(model.mAvailability);
1179c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        if (availIndex != -1) {
1180c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik            mAvailabilitySpinner.setSelection(availIndex);
1181c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        }
1182ced0eb67ef49c3203f72520c296e73d9cb4f654bMichael Chan        mAccessLevelSpinner.setSelection(model.mAccessLevel);
1183f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan
1184352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        View responseLabel = mView.findViewById(R.id.response_label);
118518a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan        if (canRespond) {
1186f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            int buttonToCheck = EventInfoFragment
1187f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan                    .findButtonIdForResponse(model.mSelfAttendeeStatus);
1188f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            mResponseRadioGroup.check(buttonToCheck); // -1 clear all radio buttons
1189f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            mResponseRadioGroup.setVisibility(View.VISIBLE);
1190352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            responseLabel.setVisibility(View.VISIBLE);
1191352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        } else {
1192352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            responseLabel.setVisibility(View.GONE);
1193f92f46b20316e71f7291f35f4cd1b64500bebf12Michael Chan            mResponseRadioGroup.setVisibility(View.GONE);
119413ea4e347755bc278d73d39c73dfb51785846193RoboErik            mResponseGroup.setVisibility(View.GONE);
1195352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        }
1196eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1197eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (model.mUri != null) {
1198eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // This is an existing event so hide the calendar spinner
1199eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // since we can't change the calendar.
12009d5f351e45e20ff04da6f9118031cc2cc7419905Michael Chan            View calendarGroup = mView.findViewById(R.id.calendar_selector_group);
12019d5f351e45e20ff04da6f9118031cc2cc7419905Michael Chan            calendarGroup.setVisibility(View.GONE);
12029d5f351e45e20ff04da6f9118031cc2cc7419905Michael Chan            TextView tv = (TextView) mView.findViewById(R.id.calendar_textview);
12039d5f351e45e20ff04da6f9118031cc2cc7419905Michael Chan            tv.setText(model.mCalendarDisplayName);
12040d865f3402b7d2f79d9843e86df655de2b4a3b0eRoboErik            tv = (TextView) mView.findViewById(R.id.calendar_textview_secondary);
12050d865f3402b7d2f79d9843e86df655de2b4a3b0eRoboErik            if (tv != null) {
12060d865f3402b7d2f79d9843e86df655de2b4a3b0eRoboErik                tv.setText(model.mOwnerAccount);
12070d865f3402b7d2f79d9843e86df655de2b4a3b0eRoboErik            }
12089d5f351e45e20ff04da6f9118031cc2cc7419905Michael Chan        } else {
1209eca82e9468c002590045338f98588ad3ce1a0bb3Erik            View calendarGroup = mView.findViewById(R.id.calendar_group);
1210eca82e9468c002590045338f98588ad3ce1a0bb3Erik            calendarGroup.setVisibility(View.GONE);
1211eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1212f56b14972130233fd7e7c64160084793a7a0a55bJames Kung        if (model.isEventColorInitialized()) {
1213f56b14972130233fd7e7c64160084793a7a0a55bJames Kung            updateHeadlineColor(model, model.getEventColor());
1214f56b14972130233fd7e7c64160084793a7a0a55bJames Kung        }
1215eca82e9468c002590045338f98588ad3ce1a0bb3Erik
12168a5489641442c022089ae1b00e498e2c1a0ba480Erik        populateWhen();
1217eca82e9468c002590045338f98588ad3ce1a0bb3Erik        populateRepeats();
1218d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        updateAttendees(model.mAttendeesList);
1219ddbf80860566df8425f38a32190e9a64cad4e389Michael Chan
1220c07a57fb7436d807ad505fa7319b9de13f91e741Erik        updateView();
1221eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mScrollView.setVisibility(View.VISIBLE);
1222eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mLoadingMessage.setVisibility(View.GONE);
1223259b8f9a21fffd3858218581e9daaf689b6b888fErik        sendAccessibilityEvent();
1224259b8f9a21fffd3858218581e9daaf689b6b888fErik    }
1225259b8f9a21fffd3858218581e9daaf689b6b888fErik
12264afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    public void updateHeadlineColor(CalendarEventModel model, int displayColor) {
12274afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        if (model.mUri != null) {
12284afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung            if (mIsMultipane) {
12294afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung                mView.findViewById(R.id.calendar_textview_with_colorpicker)
12304afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung                    .setBackgroundColor(displayColor);
12314afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung            } else {
12324afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung                mView.findViewById(R.id.calendar_group).setBackgroundColor(displayColor);
12334afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung            }
12344afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        } else {
1235317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung            setSpinnerBackgroundColor(displayColor);
1236317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung        }
1237317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung    }
1238317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung
1239317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung    private void setSpinnerBackgroundColor(int displayColor) {
1240317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung        if (mIsMultipane) {
1241317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung            mCalendarSelectorWrapper.setBackgroundColor(displayColor);
1242317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung        } else {
1243317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung            mCalendarSelectorGroup.setBackgroundColor(displayColor);
12444afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        }
12454afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    }
12464afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung
1247259b8f9a21fffd3858218581e9daaf689b6b888fErik    private void sendAccessibilityEvent() {
1248ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden        AccessibilityManager am =
1249ef31a98202852807f460af49ae3313d1ccf5e288Andy McFadden            (AccessibilityManager) mActivity.getSystemService(Service.ACCESSIBILITY_SERVICE);
1250259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (!am.isEnabled() || mModel == null) {
1251259b8f9a21fffd3858218581e9daaf689b6b888fErik            return;
1252259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
1253259b8f9a21fffd3858218581e9daaf689b6b888fErik        StringBuilder b = new StringBuilder();
1254259b8f9a21fffd3858218581e9daaf689b6b888fErik        addFieldsRecursive(b, mView);
1255259b8f9a21fffd3858218581e9daaf689b6b888fErik        CharSequence msg = b.toString();
1256259b8f9a21fffd3858218581e9daaf689b6b888fErik
1257259b8f9a21fffd3858218581e9daaf689b6b888fErik        AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED);
1258259b8f9a21fffd3858218581e9daaf689b6b888fErik        event.setClassName(getClass().getName());
1259259b8f9a21fffd3858218581e9daaf689b6b888fErik        event.setPackageName(mActivity.getPackageName());
1260259b8f9a21fffd3858218581e9daaf689b6b888fErik        event.getText().add(msg);
1261259b8f9a21fffd3858218581e9daaf689b6b888fErik        event.setAddedCount(msg.length());
1262259b8f9a21fffd3858218581e9daaf689b6b888fErik
1263259b8f9a21fffd3858218581e9daaf689b6b888fErik        am.sendAccessibilityEvent(event);
1264259b8f9a21fffd3858218581e9daaf689b6b888fErik    }
1265259b8f9a21fffd3858218581e9daaf689b6b888fErik
1266259b8f9a21fffd3858218581e9daaf689b6b888fErik    private void addFieldsRecursive(StringBuilder b, View v) {
1267259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (v == null || v.getVisibility() != View.VISIBLE) {
1268259b8f9a21fffd3858218581e9daaf689b6b888fErik            return;
1269259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
1270259b8f9a21fffd3858218581e9daaf689b6b888fErik        if (v instanceof TextView) {
1271259b8f9a21fffd3858218581e9daaf689b6b888fErik            CharSequence tv = ((TextView) v).getText();
1272259b8f9a21fffd3858218581e9daaf689b6b888fErik            if (!TextUtils.isEmpty(tv.toString().trim())) {
1273259b8f9a21fffd3858218581e9daaf689b6b888fErik                b.append(tv + PERIOD_SPACE);
1274259b8f9a21fffd3858218581e9daaf689b6b888fErik            }
1275259b8f9a21fffd3858218581e9daaf689b6b888fErik        } else if (v instanceof RadioGroup) {
1276259b8f9a21fffd3858218581e9daaf689b6b888fErik            RadioGroup rg = (RadioGroup) v;
1277259b8f9a21fffd3858218581e9daaf689b6b888fErik            int id = rg.getCheckedRadioButtonId();
1278259b8f9a21fffd3858218581e9daaf689b6b888fErik            if (id != View.NO_ID) {
1279259b8f9a21fffd3858218581e9daaf689b6b888fErik                b.append(((RadioButton) (v.findViewById(id))).getText() + PERIOD_SPACE);
1280259b8f9a21fffd3858218581e9daaf689b6b888fErik            }
1281259b8f9a21fffd3858218581e9daaf689b6b888fErik        } else if (v instanceof Spinner) {
1282259b8f9a21fffd3858218581e9daaf689b6b888fErik            Spinner s = (Spinner) v;
1283259b8f9a21fffd3858218581e9daaf689b6b888fErik            if (s.getSelectedItem() instanceof String) {
1284259b8f9a21fffd3858218581e9daaf689b6b888fErik                String str = ((String) (s.getSelectedItem())).trim();
1285259b8f9a21fffd3858218581e9daaf689b6b888fErik                if (!TextUtils.isEmpty(str)) {
1286259b8f9a21fffd3858218581e9daaf689b6b888fErik                    b.append(str + PERIOD_SPACE);
1287259b8f9a21fffd3858218581e9daaf689b6b888fErik                }
1288259b8f9a21fffd3858218581e9daaf689b6b888fErik            }
1289259b8f9a21fffd3858218581e9daaf689b6b888fErik        } else if (v instanceof ViewGroup) {
1290259b8f9a21fffd3858218581e9daaf689b6b888fErik            ViewGroup vg = (ViewGroup) v;
1291259b8f9a21fffd3858218581e9daaf689b6b888fErik            int children = vg.getChildCount();
1292259b8f9a21fffd3858218581e9daaf689b6b888fErik            for (int i = 0; i < children; i++) {
1293259b8f9a21fffd3858218581e9daaf689b6b888fErik                addFieldsRecursive(b, vg.getChildAt(i));
1294259b8f9a21fffd3858218581e9daaf689b6b888fErik            }
1295259b8f9a21fffd3858218581e9daaf689b6b888fErik        }
1296eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1297eca82e9468c002590045338f98588ad3ce1a0bb3Erik
129824ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan    /**
1299c07a57fb7436d807ad505fa7319b9de13f91e741Erik     * Creates a single line string for the time/duration
130024ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan     */
1301c07a57fb7436d807ad505fa7319b9de13f91e741Erik    protected void setWhenString() {
1302c07a57fb7436d807ad505fa7319b9de13f91e741Erik        String when;
1303c07a57fb7436d807ad505fa7319b9de13f91e741Erik        int flags = DateUtils.FORMAT_SHOW_DATE;
1304a99feb99d4bab964e66f952d005ede6c998ae11bRoboErik        String tz = mTimezone;
1305c07a57fb7436d807ad505fa7319b9de13f91e741Erik        if (mModel.mAllDay) {
1306a99feb99d4bab964e66f952d005ede6c998ae11bRoboErik            flags |= DateUtils.FORMAT_SHOW_WEEKDAY;
1307a99feb99d4bab964e66f952d005ede6c998ae11bRoboErik            tz = Time.TIMEZONE_UTC;
130824ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        } else {
1309c07a57fb7436d807ad505fa7319b9de13f91e741Erik            flags |= DateUtils.FORMAT_SHOW_TIME;
1310c07a57fb7436d807ad505fa7319b9de13f91e741Erik            if (DateFormat.is24HourFormat(mActivity)) {
1311c07a57fb7436d807ad505fa7319b9de13f91e741Erik                flags |= DateUtils.FORMAT_24HOUR;
131224ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan            }
131324ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan        }
1314c07a57fb7436d807ad505fa7319b9de13f91e741Erik        long startMillis = mStartTime.normalize(true);
1315c07a57fb7436d807ad505fa7319b9de13f91e741Erik        long endMillis = mEndTime.normalize(true);
13168a5489641442c022089ae1b00e498e2c1a0ba480Erik        mSB.setLength(0);
1317a99feb99d4bab964e66f952d005ede6c998ae11bRoboErik        when = DateUtils
1318a99feb99d4bab964e66f952d005ede6c998ae11bRoboErik                .formatDateRange(mActivity, mF, startMillis, endMillis, flags, tz).toString();
1319c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mWhenView.setText(when);
132024ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan    }
132124ee336d7ab0120a79d1d03056171d119aef83c9Michael Chan
13229645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    /**
13239645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * Configures the Calendars spinner.  This is only done for new events, because only new
13249645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * events allow you to select a calendar while editing an event.
13259645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * <p>
13269645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * We tuck a reference to a Cursor with calendar database data into the spinner, so that
13279645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * we can easily extract calendar-specific values when the value changes (the spinner's
13289645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * onItemSelected callback is configured).
13299645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     */
133009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    public void setCalendarsCursor(Cursor cursor, boolean userVisible, long selectedCalendarId) {
1331eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // If there are no syncable calendars, then we cannot allow
1332eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // creating a new event.
1333eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mCalendarsCursor = cursor;
1334eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (cursor == null || cursor.getCount() == 0) {
1335eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Cancel the "loading calendars" dialog if it exists
1336eca82e9468c002590045338f98588ad3ce1a0bb3Erik            if (mSaveAfterQueryComplete) {
1337eca82e9468c002590045338f98588ad3ce1a0bb3Erik                mLoadingCalendarsDialog.cancel();
1338eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
13397b92da258a480284dcc15a518ea570072329a31dErik            if (!userVisible) {
13407b92da258a480284dcc15a518ea570072329a31dErik                return;
13417b92da258a480284dcc15a518ea570072329a31dErik            }
1342eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // Create an error message for the user that, when clicked,
1343eca82e9468c002590045338f98588ad3ce1a0bb3Erik            // will exit this activity without saving the event.
1344eca82e9468c002590045338f98588ad3ce1a0bb3Erik            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
1345f6b6fb3204ecd7d5857372b766cbe456585a911aErik            builder.setTitle(R.string.no_syncable_calendars).setIconAttribute(
1346f6b6fb3204ecd7d5857372b766cbe456585a911aErik                    android.R.attr.alertDialogIcon).setMessage(R.string.no_calendars_found)
1347464f350da9b6f264ebee2104dfbeb68b94d933e4Daisuke Miyakawa                    .setPositiveButton(R.string.add_account, this)
1348f6b6fb3204ecd7d5857372b766cbe456585a911aErik                    .setNegativeButton(android.R.string.no, this).setOnCancelListener(this);
1349eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mNoCalendarsDialog = builder.show();
1350eca82e9468c002590045338f98588ad3ce1a0bb3Erik            return;
1351eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1352eca82e9468c002590045338f98588ad3ce1a0bb3Erik
135309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        int selection;
135409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        if (selectedCalendarId != -1) {
135509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            selection = findSelectedCalendarPosition(cursor, selectedCalendarId);
135609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        } else {
135709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            selection = findDefaultCalendarPosition(cursor);
135809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        }
1359eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1360eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // populate the calendars spinner
136109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        CalendarsAdapter adapter = new CalendarsAdapter(mActivity,
136209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            R.layout.calendars_spinner_item, cursor);
1363eca82e9468c002590045338f98588ad3ce1a0bb3Erik        mCalendarsSpinner.setAdapter(adapter);
13643400a2bfc1e6be435ea2bb0f436a6ef338446504Erik        mCalendarsSpinner.setOnItemSelectedListener(this);
136596a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung        mCalendarsSpinner.setSelection(selection);
13663400a2bfc1e6be435ea2bb0f436a6ef338446504Erik
1367eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (mSaveAfterQueryComplete) {
1368eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mLoadingCalendarsDialog.cancel();
13697b92da258a480284dcc15a518ea570072329a31dErik            if (prepareForSave() && fillModelFromUI()) {
13707b92da258a480284dcc15a518ea570072329a31dErik                int exit = userVisible ? Utils.DONE_EXIT : 0;
13717b92da258a480284dcc15a518ea570072329a31dErik                mDone.setDoneCode(Utils.DONE_SAVE | exit);
137279f228124de7d98146ca526d743436f6419e2365Erik                mDone.run();
13737b92da258a480284dcc15a518ea570072329a31dErik            } else if (userVisible) {
13747b92da258a480284dcc15a518ea570072329a31dErik                mDone.setDoneCode(Utils.DONE_EXIT);
137579f228124de7d98146ca526d743436f6419e2365Erik                mDone.run();
13767b92da258a480284dcc15a518ea570072329a31dErik            } else if (Log.isLoggable(TAG, Log.DEBUG)) {
13777b92da258a480284dcc15a518ea570072329a31dErik                Log.d(TAG, "SetCalendarsCursor:Save failed and unable to exit view");
1378eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
1379eca82e9468c002590045338f98588ad3ce1a0bb3Erik            return;
1380eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1381eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1382eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1383c07a57fb7436d807ad505fa7319b9de13f91e741Erik    /**
1384c07a57fb7436d807ad505fa7319b9de13f91e741Erik     * Updates the view based on {@link #mModification} and {@link #mModel}
1385c07a57fb7436d807ad505fa7319b9de13f91e741Erik     */
1386c07a57fb7436d807ad505fa7319b9de13f91e741Erik    public void updateView() {
1387c07a57fb7436d807ad505fa7319b9de13f91e741Erik        if (mModel == null) {
1388c07a57fb7436d807ad505fa7319b9de13f91e741Erik            return;
1389c07a57fb7436d807ad505fa7319b9de13f91e741Erik        }
1390c07a57fb7436d807ad505fa7319b9de13f91e741Erik        if (EditEventHelper.canModifyEvent(mModel)) {
1391c07a57fb7436d807ad505fa7319b9de13f91e741Erik            setViewStates(mModification);
1392c07a57fb7436d807ad505fa7319b9de13f91e741Erik        } else {
1393c07a57fb7436d807ad505fa7319b9de13f91e741Erik            setViewStates(Utils.MODIFY_UNINITIALIZED);
1394c07a57fb7436d807ad505fa7319b9de13f91e741Erik        }
1395c07a57fb7436d807ad505fa7319b9de13f91e741Erik    }
1396c07a57fb7436d807ad505fa7319b9de13f91e741Erik
1397c07a57fb7436d807ad505fa7319b9de13f91e741Erik    private void setViewStates(int mode) {
1398c07a57fb7436d807ad505fa7319b9de13f91e741Erik        // Extra canModify check just in case
1399c07a57fb7436d807ad505fa7319b9de13f91e741Erik        if (mode == Utils.MODIFY_UNINITIALIZED || !EditEventHelper.canModifyEvent(mModel)) {
1400c07a57fb7436d807ad505fa7319b9de13f91e741Erik            setWhenString();
1401c07a57fb7436d807ad505fa7319b9de13f91e741Erik
1402c07a57fb7436d807ad505fa7319b9de13f91e741Erik            for (View v : mViewOnlyList) {
1403c07a57fb7436d807ad505fa7319b9de13f91e741Erik                v.setVisibility(View.VISIBLE);
1404c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1405c07a57fb7436d807ad505fa7319b9de13f91e741Erik            for (View v : mEditOnlyList) {
1406c07a57fb7436d807ad505fa7319b9de13f91e741Erik                v.setVisibility(View.GONE);
1407c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1408c07a57fb7436d807ad505fa7319b9de13f91e741Erik            for (View v : mEditViewList) {
1409c07a57fb7436d807ad505fa7319b9de13f91e741Erik                v.setEnabled(false);
1410efa480cc0733071f311ccb27806916de5efff71cErik                v.setBackgroundDrawable(null);
1411c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1412c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mCalendarSelectorGroup.setVisibility(View.GONE);
1413c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mCalendarStaticGroup.setVisibility(View.VISIBLE);
1414b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mRruleButton.setEnabled(false);
1415c07a57fb7436d807ad505fa7319b9de13f91e741Erik            if (EditEventHelper.canAddReminders(mModel)) {
1416c07a57fb7436d807ad505fa7319b9de13f91e741Erik                mRemindersGroup.setVisibility(View.VISIBLE);
1417c07a57fb7436d807ad505fa7319b9de13f91e741Erik            } else {
1418c07a57fb7436d807ad505fa7319b9de13f91e741Erik                mRemindersGroup.setVisibility(View.GONE);
1419c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1420a7694eead7cbb293990bc89c3906e17bad36194cErik            if (TextUtils.isEmpty(mLocationTextView.getText())) {
1421a7694eead7cbb293990bc89c3906e17bad36194cErik                mLocationGroup.setVisibility(View.GONE);
1422a7694eead7cbb293990bc89c3906e17bad36194cErik            }
1423a7694eead7cbb293990bc89c3906e17bad36194cErik            if (TextUtils.isEmpty(mDescriptionTextView.getText())) {
1424a7694eead7cbb293990bc89c3906e17bad36194cErik                mDescriptionGroup.setVisibility(View.GONE);
1425a7694eead7cbb293990bc89c3906e17bad36194cErik            }
1426c07a57fb7436d807ad505fa7319b9de13f91e741Erik        } else {
1427c07a57fb7436d807ad505fa7319b9de13f91e741Erik            for (View v : mViewOnlyList) {
1428c07a57fb7436d807ad505fa7319b9de13f91e741Erik                v.setVisibility(View.GONE);
1429c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1430c07a57fb7436d807ad505fa7319b9de13f91e741Erik            for (View v : mEditOnlyList) {
1431c07a57fb7436d807ad505fa7319b9de13f91e741Erik                v.setVisibility(View.VISIBLE);
1432c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1433c07a57fb7436d807ad505fa7319b9de13f91e741Erik            for (View v : mEditViewList) {
1434c07a57fb7436d807ad505fa7319b9de13f91e741Erik                v.setEnabled(true);
1435efa480cc0733071f311ccb27806916de5efff71cErik                if (v.getTag() != null) {
1436efa480cc0733071f311ccb27806916de5efff71cErik                    v.setBackgroundDrawable((Drawable) v.getTag());
14370d865f3402b7d2f79d9843e86df655de2b4a3b0eRoboErik                    v.setPadding(mOriginalPadding[0], mOriginalPadding[1], mOriginalPadding[2],
14380d865f3402b7d2f79d9843e86df655de2b4a3b0eRoboErik                            mOriginalPadding[3]);
1439efa480cc0733071f311ccb27806916de5efff71cErik                }
1440c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1441c07a57fb7436d807ad505fa7319b9de13f91e741Erik            if (mModel.mUri == null) {
1442c07a57fb7436d807ad505fa7319b9de13f91e741Erik                mCalendarSelectorGroup.setVisibility(View.VISIBLE);
1443c07a57fb7436d807ad505fa7319b9de13f91e741Erik                mCalendarStaticGroup.setVisibility(View.GONE);
1444c07a57fb7436d807ad505fa7319b9de13f91e741Erik            } else {
1445c07a57fb7436d807ad505fa7319b9de13f91e741Erik                mCalendarSelectorGroup.setVisibility(View.GONE);
1446c07a57fb7436d807ad505fa7319b9de13f91e741Erik                mCalendarStaticGroup.setVisibility(View.VISIBLE);
1447c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
144828dab653f55caccbed32f700274f5274abaee089RoboErik            if (mModel.mOriginalSyncId == null) {
1449b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mRruleButton.setEnabled(true);
1450c07a57fb7436d807ad505fa7319b9de13f91e741Erik            } else {
1451b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mRruleButton.setEnabled(false);
1452018f539c218940e0fad05c10552759e4fa2e77e4Sam Blitzstein                mRruleButton.setBackgroundDrawable(null);
1453c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1454c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mRemindersGroup.setVisibility(View.VISIBLE);
1455c07a57fb7436d807ad505fa7319b9de13f91e741Erik
1456a7694eead7cbb293990bc89c3906e17bad36194cErik            mLocationGroup.setVisibility(View.VISIBLE);
1457a7694eead7cbb293990bc89c3906e17bad36194cErik            mDescriptionGroup.setVisibility(View.VISIBLE);
1458eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1459521e7b8d69e7a944ca2868dd88dac5c56fd0c94aMindy Pereira        setAllDayViewsVisibility(mAllDayCheckBox.isChecked());
1460eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1461eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1462c07a57fb7436d807ad505fa7319b9de13f91e741Erik    public void setModification(int modifyWhich) {
1463c07a57fb7436d807ad505fa7319b9de13f91e741Erik        mModification = modifyWhich;
1464c07a57fb7436d807ad505fa7319b9de13f91e741Erik        updateView();
14658a5489641442c022089ae1b00e498e2c1a0ba480Erik        updateHomeTime();
1466c07a57fb7436d807ad505fa7319b9de13f91e741Erik    }
1467c07a57fb7436d807ad505fa7319b9de13f91e741Erik
146809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    private int findSelectedCalendarPosition(Cursor calendarsCursor, long calendarId) {
146909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        if (calendarsCursor.getCount() <= 0) {
147009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            return -1;
147109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        }
147209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        int calendarIdColumn = calendarsCursor.getColumnIndexOrThrow(Calendars._ID);
147309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        int position = 0;
147409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        calendarsCursor.moveToPosition(-1);
147509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        while (calendarsCursor.moveToNext()) {
147609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            if (calendarsCursor.getLong(calendarIdColumn) == calendarId) {
147709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung                return position;
147809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            }
147909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            position++;
148009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        }
148109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        return 0;
148209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    }
148309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung
1484eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // Find the calendar position in the cursor that matches calendar in
1485eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // preference
1486eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private int findDefaultCalendarPosition(Cursor calendarsCursor) {
1487eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (calendarsCursor.getCount() <= 0) {
1488eca82e9468c002590045338f98588ad3ce1a0bb3Erik            return -1;
1489eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1490eca82e9468c002590045338f98588ad3ce1a0bb3Erik
14917b92da258a480284dcc15a518ea570072329a31dErik        String defaultCalendar = Utils.getSharedPreference(
1492e98dca7e0042f7b36788b0e5d8dc6e94048c895cMichael Chan                mActivity, GeneralPreferences.KEY_DEFAULT_CALENDAR, (String) null);
1493eca82e9468c002590045338f98588ad3ce1a0bb3Erik
149409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        int calendarsOwnerIndex = calendarsCursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);
14958286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting        int accountNameIndex = calendarsCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
1496844cac068835d7d8a80ec118da8019535c0d7450Sara Ting        int accountTypeIndex = calendarsCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE);
1497eca82e9468c002590045338f98588ad3ce1a0bb3Erik        int position = 0;
1498eca82e9468c002590045338f98588ad3ce1a0bb3Erik        calendarsCursor.moveToPosition(-1);
1499eca82e9468c002590045338f98588ad3ce1a0bb3Erik        while (calendarsCursor.moveToNext()) {
150009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            String calendarOwner = calendarsCursor.getString(calendarsOwnerIndex);
15018286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting            if (defaultCalendar == null) {
15028286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting                // There is no stored default upon the first time running.  Use a primary
15038286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting                // calendar in this case.
15048286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting                if (calendarOwner != null &&
1505844cac068835d7d8a80ec118da8019535c0d7450Sara Ting                        calendarOwner.equals(calendarsCursor.getString(accountNameIndex)) &&
1506844cac068835d7d8a80ec118da8019535c0d7450Sara Ting                        !CalendarContract.ACCOUNT_TYPE_LOCAL.equals(
1507844cac068835d7d8a80ec118da8019535c0d7450Sara Ting                                calendarsCursor.getString(accountTypeIndex))) {
15088286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting                    return position;
15098286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting                }
15108286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting            } else if (defaultCalendar.equals(calendarOwner)) {
15118286d2f75e9c808f022c8c6b7431f50e7f60372fSara Ting                // Found the default calendar.
1512eca82e9468c002590045338f98588ad3ce1a0bb3Erik                return position;
1513eca82e9468c002590045338f98588ad3ce1a0bb3Erik            }
1514eca82e9468c002590045338f98588ad3ce1a0bb3Erik            position++;
1515eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1516eca82e9468c002590045338f98588ad3ce1a0bb3Erik        return 0;
1517eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1518eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1519ddbf80860566df8425f38a32190e9a64cad4e389Michael Chan    private void updateAttendees(HashMap<String, Attendee> attendeesList) {
15206a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        if (attendeesList == null || attendeesList.isEmpty()) {
15216a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik            return;
15226a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        }
15236a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        mAttendeesList.setText(null);
15246a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        for (Attendee attendee : attendeesList.values()) {
1525bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung
1526bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung            // TODO: Please remove separator when Calendar uses the chips MR2 project
1527bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung
1528bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung            // Adding a comma separator between email addresses to prevent a chips MR1.1 bug
1529bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung            // in which email addresses are concatenated together with no separator.
1530bb90a7d48cd91cbd5591f1d8b34e2c5d8040b96eJames Kung            mAttendeesList.append(attendee.mEmail + ", ");
15316a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik        }
1532d845fbe558d5229102b58cce70a1b29fe6cb6967Erik    }
15334c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang
1534eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private void updateRemindersVisibility(int numReminders) {
1535eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (numReminders == 0) {
1536eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mRemindersContainer.setVisibility(View.GONE);
1537eca82e9468c002590045338f98588ad3ce1a0bb3Erik        } else {
1538eca82e9468c002590045338f98588ad3ce1a0bb3Erik            mRemindersContainer.setVisibility(View.VISIBLE);
1539eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1540eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1541eca82e9468c002590045338f98588ad3ce1a0bb3Erik
15429645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden    /**
15439645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * Add a new reminder when the user hits the "add reminder" button.  We use the default
15449645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     * reminder time and method.
15459645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden     */
1546ddbf80860566df8425f38a32190e9a64cad4e389Michael Chan    private void addReminder() {
1547eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // TODO: when adding a new reminder, make it different from the
1548eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // last one in the list (if any).
15499d8a376b89fcc36c44d4df0c5cbf6991306131c4Michael Chan        if (mDefaultReminderMinutes == GeneralPreferences.NO_REMINDER) {
155079f228124de7d98146ca526d743436f6419e2365Erik            EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderItems,
1551fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden                    mReminderMinuteValues, mReminderMinuteLabels,
15529645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                    mReminderMethodValues, mReminderMethodLabels,
15539645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                    ReminderEntry.valueOf(GeneralPreferences.REMINDER_DEFAULT_TIME),
15548b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mModel.mCalendarMaxReminders, null);
1555eca82e9468c002590045338f98588ad3ce1a0bb3Erik        } else {
155679f228124de7d98146ca526d743436f6419e2365Erik            EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderItems,
1557fea9af5d69ad3e5687a4efd72d7d3adfb8d056c8Andy McFadden                    mReminderMinuteValues, mReminderMinuteLabels,
15589645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                    mReminderMethodValues, mReminderMethodLabels,
15599645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden                    ReminderEntry.valueOf(mDefaultReminderMinutes),
15608b5743c1bcff53f13b4890ba05fb013bbf8f29bcRoboErik                    mModel.mCalendarMaxReminders, null);
1561eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
1562eca82e9468c002590045338f98588ad3ce1a0bb3Erik        updateRemindersVisibility(mReminderItems.size());
156306f3d6d0d3bd6d194f5a3822efd63830098284dcSara Ting        EventViewUtils.updateAddReminderButton(mView, mReminderItems, mModel.mCalendarMaxReminders);
1564eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1565eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1566eca82e9468c002590045338f98588ad3ce1a0bb3Erik    // From com.google.android.gm.ComposeActivity
15676a7003d1b9bf20f4c6e001d054b1ab556ddec4a4RoboErik    private MultiAutoCompleteTextView initMultiAutoCompleteTextView(RecipientEditTextView list) {
156818cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira        if (ChipsUtil.supportsChipsUi()) {
156918cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira            mAddressAdapter = new RecipientAdapter(mActivity);
157018cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira            list.setAdapter((BaseRecipientAdapter) mAddressAdapter);
1571ce8a833592bc0c44e8be4d5aec5813d364cd0b30RoboErik            list.setOnFocusListShrinkRecipients(false);
157218cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira        } else {
157318cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira            mAddressAdapter = new EmailAddressAdapter(mActivity);
157418cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira            list.setAdapter((EmailAddressAdapter)mAddressAdapter);
157518cabd263b91d7d09f3b93b0bf6c78533bbc2c6aMindy Pereira        }
1576eca82e9468c002590045338f98588ad3ce1a0bb3Erik        list.setTokenizer(new Rfc822Tokenizer());
1577eca82e9468c002590045338f98588ad3ce1a0bb3Erik        list.setValidator(mEmailValidator);
1578eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1579eca82e9468c002590045338f98588ad3ce1a0bb3Erik        // NOTE: assumes no other filters are set
1580eca82e9468c002590045338f98588ad3ce1a0bb3Erik        list.setFilters(sRecipientFilters);
1581eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1582eca82e9468c002590045338f98588ad3ce1a0bb3Erik        return list;
1583eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1584eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1585eca82e9468c002590045338f98588ad3ce1a0bb3Erik    /**
1586eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * From com.google.android.gm.ComposeActivity Implements special address
1587eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * cleanup rules: The first space key entry following an "@" symbol that is
1588eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * followed by any combination of letters and symbols, including one+ dots
1589eca82e9468c002590045338f98588ad3ce1a0bb3Erik     * and zero commas, should insert an extra comma (followed by the space).
1590eca82e9468c002590045338f98588ad3ce1a0bb3Erik     */
15917b92da258a480284dcc15a518ea570072329a31dErik    private static InputFilter[] sRecipientFilters = new InputFilter[] { new Rfc822InputFilter() };
1592eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1593eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private void setDate(TextView view, long millis) {
1594eca82e9468c002590045338f98588ad3ce1a0bb3Erik        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR
1595eca82e9468c002590045338f98588ad3ce1a0bb3Erik                | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_MONTH
1596eca82e9468c002590045338f98588ad3ce1a0bb3Erik                | DateUtils.FORMAT_ABBREV_WEEKDAY;
15974c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang
15984c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // Unfortunately, DateUtils doesn't support a timezone other than the
15994c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // default timezone provided by the system, so we have this ugly hack
16004c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // here to trick it into formatting our time correctly. In order to
16014c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // prevent all sorts of craziness, we synchronize on the TimeZone class
16024c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // to prevent other threads from reading an incorrect timezone from
16034c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // calls to TimeZone#getDefault()
16044c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // TODO fix this if/when DateUtils allows for passing in a timezone
16054c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        String dateString;
16064c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        synchronized (TimeZone.class) {
16074c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            TimeZone.setDefault(TimeZone.getTimeZone(mTimezone));
16084c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            dateString = DateUtils.formatDateTime(mActivity, millis, flags);
16094c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            // setting the default back to null restores the correct behavior
16104c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            TimeZone.setDefault(null);
16114c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        }
16124c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        view.setText(dateString);
1613eca82e9468c002590045338f98588ad3ce1a0bb3Erik    }
1614eca82e9468c002590045338f98588ad3ce1a0bb3Erik
1615eca82e9468c002590045338f98588ad3ce1a0bb3Erik    private void setTime(TextView view, long millis) {
1616eca82e9468c002590045338f98588ad3ce1a0bb3Erik        int flags = DateUtils.FORMAT_SHOW_TIME;
1617614601e83824071df831465150b2198b915005fbPaul Sliwowski        flags |= DateUtils.FORMAT_CAP_NOON_MIDNIGHT;
1618eca82e9468c002590045338f98588ad3ce1a0bb3Erik        if (DateFormat.is24HourFormat(mActivity)) {
1619eca82e9468c002590045338f98588ad3ce1a0bb3Erik            flags |= DateUtils.FORMAT_24HOUR;
1620eca82e9468c002590045338f98588ad3ce1a0bb3Erik        }
16214c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang
16224c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // Unfortunately, DateUtils doesn't support a timezone other than the
16234c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // default timezone provided by the system, so we have this ugly hack
16244c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // here to trick it into formatting our time correctly. In order to
16254c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // prevent all sorts of craziness, we synchronize on the TimeZone class
16264c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // to prevent other threads from reading an incorrect timezone from
16274c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // calls to TimeZone#getDefault()
16284c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        // TODO fix this if/when DateUtils allows for passing in a timezone
16294c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        String timeString;
16304c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        synchronized (TimeZone.class) {
16314c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            TimeZone.setDefault(TimeZone.getTimeZone(mTimezone));
16324c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            timeString = DateUtils.formatDateTime(mActivity, millis, flags);
16334c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang            TimeZone.setDefault(null);
16344c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        }
16354c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang        view.setText(timeString);
16364c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang    }
16374c8871bf5dee3b3586b375aee98effde31b781a8Mason Tang
1638c07a57fb7436d807ad505fa7319b9de13f91e741Erik    /**
1639c07a57fb7436d807ad505fa7319b9de13f91e741Erik     * @param isChecked
1640c07a57fb7436d807ad505fa7319b9de13f91e741Erik     */
1641c07a57fb7436d807ad505fa7319b9de13f91e741Erik    protected void setAllDayViewsVisibility(boolean isChecked) {
1642c07a57fb7436d807ad505fa7319b9de13f91e741Erik        if (isChecked) {
1643c07a57fb7436d807ad505fa7319b9de13f91e741Erik            if (mEndTime.hour == 0 && mEndTime.minute == 0) {
16448b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan                if (mAllDay != isChecked) {
16458b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan                    mEndTime.monthDay--;
16468b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan                }
16478b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan
1648c07a57fb7436d807ad505fa7319b9de13f91e741Erik                long endMillis = mEndTime.normalize(true);
1649c07a57fb7436d807ad505fa7319b9de13f91e741Erik
1650c07a57fb7436d807ad505fa7319b9de13f91e741Erik                // Do not allow an event to have an end time
1651c07a57fb7436d807ad505fa7319b9de13f91e741Erik                // before the
1652c07a57fb7436d807ad505fa7319b9de13f91e741Erik                // start time.
1653c07a57fb7436d807ad505fa7319b9de13f91e741Erik                if (mEndTime.before(mStartTime)) {
1654c07a57fb7436d807ad505fa7319b9de13f91e741Erik                    mEndTime.set(mStartTime);
1655c07a57fb7436d807ad505fa7319b9de13f91e741Erik                    endMillis = mEndTime.normalize(true);
1656c07a57fb7436d807ad505fa7319b9de13f91e741Erik                }
1657c07a57fb7436d807ad505fa7319b9de13f91e741Erik                setDate(mEndDateButton, endMillis);
1658c07a57fb7436d807ad505fa7319b9de13f91e741Erik                setTime(mEndTimeButton, endMillis);
1659c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1660c07a57fb7436d807ad505fa7319b9de13f91e741Erik
1661c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mStartTimeButton.setVisibility(View.GONE);
1662c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mEndTimeButton.setVisibility(View.GONE);
1663b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan            mTimezoneRow.setVisibility(View.GONE);
1664c07a57fb7436d807ad505fa7319b9de13f91e741Erik        } else {
1665c07a57fb7436d807ad505fa7319b9de13f91e741Erik            if (mEndTime.hour == 0 && mEndTime.minute == 0) {
16668b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan                if (mAllDay != isChecked) {
16678b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan                    mEndTime.monthDay++;
16688b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan                }
16698b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan
1670c07a57fb7436d807ad505fa7319b9de13f91e741Erik                long endMillis = mEndTime.normalize(true);
1671c07a57fb7436d807ad505fa7319b9de13f91e741Erik                setDate(mEndDateButton, endMillis);
1672c07a57fb7436d807ad505fa7319b9de13f91e741Erik                setTime(mEndTimeButton, endMillis);
1673c07a57fb7436d807ad505fa7319b9de13f91e741Erik            }
1674c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mStartTimeButton.setVisibility(View.VISIBLE);
1675c07a57fb7436d807ad505fa7319b9de13f91e741Erik            mEndTimeButton.setVisibility(View.VISIBLE);
1676b20942b3087dbef5483669b76e00e9b8b4d5a7b1Michael Chan            mTimezoneRow.setVisibility(View.VISIBLE);
1677c07a57fb7436d807ad505fa7319b9de13f91e741Erik        }
16787cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein
16797cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        // If this is a new event, and if availability has not yet been
16807cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        // explicitly set, toggle busy/available as the inverse of all day.
16817cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        if (mModel.mUri == null && !mAvailabilityExplicitlySet) {
16827cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            // Values are from R.arrays.availability_values.
16837cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            // 0 = busy
16847cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            // 1 = available
16857cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            int newAvailabilityValue = isChecked? 1 : 0;
16867cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            if (mAvailabilityAdapter != null && mAvailabilityValues != null
16877cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                    && mAvailabilityValues.contains(newAvailabilityValue)) {
16887cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // We'll need to let the spinner's listener know that we're
16897cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                // explicitly toggling it.
16907cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                mAllDayChangingAvailability = true;
16917cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein
16927cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                String newAvailabilityLabel = mOriginalAvailabilityLabels.get(newAvailabilityValue);
16937cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                int newAvailabilityPos = mAvailabilityAdapter.getPosition(newAvailabilityLabel);
16947cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein                mAvailabilitySpinner.setSelection(newAvailabilityPos);
16957cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein            }
16967cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein        }
16977cdfb4debc715ff1193eef2e27311e6350954590Sam Blitzstein
16988b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan        mAllDay = isChecked;
16998a5489641442c022089ae1b00e498e2c1a0ba480Erik        updateHomeTime();
1700c07a57fb7436d807ad505fa7319b9de13f91e741Erik    }
17013400a2bfc1e6be435ea2bb0f436a6ef338446504Erik
170296a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung    public void setColorPickerButtonStates(int[] colorArray) {
170396a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung        setColorPickerButtonStates(colorArray != null && colorArray.length > 0);
170496a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung    }
170596a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung
170696a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung    public void setColorPickerButtonStates(boolean showColorPalette) {
170796a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung        if (showColorPalette) {
1708e134cd5c96507107048a50b55fe2fee85fe8e2e7James Kung            mColorPickerNewEvent.setVisibility(View.VISIBLE);
1709e134cd5c96507107048a50b55fe2fee85fe8e2e7James Kung            mColorPickerExistingEvent.setVisibility(View.VISIBLE);
171096a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung        } else {
171196a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung            mColorPickerNewEvent.setVisibility(View.INVISIBLE);
171296a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung            mColorPickerExistingEvent.setVisibility(View.GONE);
17134afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        }
17144afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung    }
17154afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung
171696a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung    public boolean isColorPaletteVisible() {
171796a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung        return mColorPickerNewEvent.getVisibility() == View.VISIBLE ||
171896a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung                mColorPickerExistingEvent.getVisibility() == View.VISIBLE;
171996a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung    }
172096a36f4cb7803d50ecf47945b6a240926f48e7c3James Kung
17213400a2bfc1e6be435ea2bb0f436a6ef338446504Erik    @Override
17223400a2bfc1e6be435ea2bb0f436a6ef338446504Erik    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
17239645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // This is only used for the Calendar spinner in new events, and only fires when the
17246a63b77cb1163f36ca0ef03c60ccf4d97bb22808Isaac Katzenelson        // calendar selection changes or on screen rotation
17253400a2bfc1e6be435ea2bb0f436a6ef338446504Erik        Cursor c = (Cursor) parent.getItemAtPosition(position);
17269645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        if (c == null) {
17279645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            // TODO: can this happen? should we drop this check?
17289645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            Log.w(TAG, "Cursor not set on calendar item");
17299645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            return;
17303400a2bfc1e6be435ea2bb0f436a6ef338446504Erik        }
17319645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
17324afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        // Do nothing if the selection didn't change so that reminders will not get lost
17334afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        int idColumn = c.getColumnIndexOrThrow(Calendars._ID);
17344afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        long calendarId = c.getLong(idColumn);
17359645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        int colorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
17364acb2fd087308dea146b8b10f5278c59df387680RoboErik        int color = c.getInt(colorColumn);
17374acb2fd087308dea146b8b10f5278c59df387680RoboErik        int displayColor = Utils.getDisplayColorFromColor(color);
1738eb51f84a9d77b1d7c2d407b1f594b7e281e277ccMindy Pereira
1739317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung        // Prevents resetting of data (reminders, etc.) on orientation change.
1740f56b14972130233fd7e7c64160084793a7a0a55bJames Kung        if (calendarId == mModel.mCalendarId && mModel.isCalendarColorInitialized() &&
1741f56b14972130233fd7e7c64160084793a7a0a55bJames Kung                displayColor == mModel.getCalendarColor()) {
1742317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung            return;
17433a002717f71bf66b1d056c674a14963ec9f80fa8RoboErik        }
17449645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
1745317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung        setSpinnerBackgroundColor(displayColor);
1746317f66148c6bcd75c83d73cbc5f74090412dcc3aJames Kung
17476a63b77cb1163f36ca0ef03c60ccf4d97bb22808Isaac Katzenelson        mModel.mCalendarId = calendarId;
1748f56b14972130233fd7e7c64160084793a7a0a55bJames Kung        mModel.setCalendarColor(displayColor);
17494afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        mModel.mCalendarAccountName = c.getString(EditEventHelper.CALENDARS_INDEX_ACCOUNT_NAME);
17504afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        mModel.mCalendarAccountType = c.getString(EditEventHelper.CALENDARS_INDEX_ACCOUNT_TYPE);
1751f56b14972130233fd7e7c64160084793a7a0a55bJames Kung        mModel.setEventColor(mModel.getCalendarColor());
17524afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung
17534afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung        setColorPickerButtonStates(mModel.getCalendarEventColors());
17544afba187f8990ae2b3afaf8fcdb6039f231f4914James Kung
17559645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // Update the max/allowed reminders with the new calendar properties.
17569645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        int maxRemindersColumn = c.getColumnIndexOrThrow(Calendars.MAX_REMINDERS);
17579645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mCalendarMaxReminders = c.getInt(maxRemindersColumn);
17589645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        int allowedRemindersColumn = c.getColumnIndexOrThrow(Calendars.ALLOWED_REMINDERS);
17599645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mCalendarAllowedReminders = c.getString(allowedRemindersColumn);
1760c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        int allowedAttendeeTypesColumn = c.getColumnIndexOrThrow(Calendars.ALLOWED_ATTENDEE_TYPES);
1761c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        mModel.mCalendarAllowedAttendeeTypes = c.getString(allowedAttendeeTypesColumn);
1762c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        int allowedAvailabilityColumn = c.getColumnIndexOrThrow(Calendars.ALLOWED_AVAILABILITY);
1763c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        mModel.mCalendarAllowedAvailability = c.getString(allowedAvailabilityColumn);
17649645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
17659645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // Discard the current reminders and replace them with the model's default reminder set.
17669645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // We could attempt to save & restore the reminders that have been added, but that's
17679645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // probably more trouble than it's worth.
17689645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mReminders.clear();
17699645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mReminders.addAll(mModel.mDefaultReminders);
17709645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mModel.mHasAlarm = mModel.mReminders.size() != 0;
17719645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden
17729645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        // Update the UI elements.
17739645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        mReminderItems.clear();
17749645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        LinearLayout reminderLayout =
17759645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden            (LinearLayout) mScrollView.findViewById(R.id.reminder_items_container);
17769645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        reminderLayout.removeAllViews();
17779645d9c3e9b2cfd35c5fc89f41caf6e99153ba10Andy McFadden        prepareReminders();
1778c6680c5819b6ad0d1914420902746fe5f86ba403RoboErik        prepareAvailability();
17793400a2bfc1e6be435ea2bb0f436a6ef338446504Erik    }
17803400a2bfc1e6be435ea2bb0f436a6ef338446504Erik
17818a5489641442c022089ae1b00e498e2c1a0ba480Erik    /**
17828a5489641442c022089ae1b00e498e2c1a0ba480Erik     * Checks if the start and end times for this event should be displayed in
17838a5489641442c022089ae1b00e498e2c1a0ba480Erik     * the Calendar app's time zone as well and formats and displays them.
17848a5489641442c022089ae1b00e498e2c1a0ba480Erik     */
17858a5489641442c022089ae1b00e498e2c1a0ba480Erik    private void updateHomeTime() {
17868a5489641442c022089ae1b00e498e2c1a0ba480Erik        String tz = Utils.getTimeZone(mActivity, null);
17878a5489641442c022089ae1b00e498e2c1a0ba480Erik        if (!mAllDayCheckBox.isChecked() && !TextUtils.equals(tz, mTimezone)
17888a5489641442c022089ae1b00e498e2c1a0ba480Erik                && mModification != EditEventHelper.MODIFY_UNINITIALIZED) {
17898a5489641442c022089ae1b00e498e2c1a0ba480Erik            int flags = DateUtils.FORMAT_SHOW_TIME;
17908a5489641442c022089ae1b00e498e2c1a0ba480Erik            boolean is24Format = DateFormat.is24HourFormat(mActivity);
17918a5489641442c022089ae1b00e498e2c1a0ba480Erik            if (is24Format) {
17928a5489641442c022089ae1b00e498e2c1a0ba480Erik                flags |= DateUtils.FORMAT_24HOUR;
17938a5489641442c022089ae1b00e498e2c1a0ba480Erik            }
17948a5489641442c022089ae1b00e498e2c1a0ba480Erik            long millisStart = mStartTime.toMillis(false);
17958a5489641442c022089ae1b00e498e2c1a0ba480Erik            long millisEnd = mEndTime.toMillis(false);
17968a5489641442c022089ae1b00e498e2c1a0ba480Erik
17978a5489641442c022089ae1b00e498e2c1a0ba480Erik            boolean isDSTStart = mStartTime.isDst != 0;
17988a5489641442c022089ae1b00e498e2c1a0ba480Erik            boolean isDSTEnd = mEndTime.isDst != 0;
17998a5489641442c022089ae1b00e498e2c1a0ba480Erik
18008a5489641442c022089ae1b00e498e2c1a0ba480Erik            // First update the start date and times
18018a5489641442c022089ae1b00e498e2c1a0ba480Erik            String tzDisplay = TimeZone.getTimeZone(tz).getDisplayName(
18028a5489641442c022089ae1b00e498e2c1a0ba480Erik                    isDSTStart, TimeZone.SHORT, Locale.getDefault());
18038a5489641442c022089ae1b00e498e2c1a0ba480Erik            StringBuilder time = new StringBuilder();
18048a5489641442c022089ae1b00e498e2c1a0ba480Erik
18058a5489641442c022089ae1b00e498e2c1a0ba480Erik            mSB.setLength(0);
18068a5489641442c022089ae1b00e498e2c1a0ba480Erik            time.append(DateUtils
18078a5489641442c022089ae1b00e498e2c1a0ba480Erik                    .formatDateRange(mActivity, mF, millisStart, millisStart, flags, tz))
18088a5489641442c022089ae1b00e498e2c1a0ba480Erik                    .append(" ").append(tzDisplay);
18098a5489641442c022089ae1b00e498e2c1a0ba480Erik            mStartTimeHome.setText(time.toString());
18108a5489641442c022089ae1b00e498e2c1a0ba480Erik
18118a5489641442c022089ae1b00e498e2c1a0ba480Erik            flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE
18128a5489641442c022089ae1b00e498e2c1a0ba480Erik                    | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_WEEKDAY;
18138a5489641442c022089ae1b00e498e2c1a0ba480Erik            mSB.setLength(0);
18148a5489641442c022089ae1b00e498e2c1a0ba480Erik            mStartDateHome
18158a5489641442c022089ae1b00e498e2c1a0ba480Erik                    .setText(DateUtils.formatDateRange(
18168a5489641442c022089ae1b00e498e2c1a0ba480Erik                            mActivity, mF, millisStart, millisStart, flags, tz).toString());
18178a5489641442c022089ae1b00e498e2c1a0ba480Erik
18188a5489641442c022089ae1b00e498e2c1a0ba480Erik            // Make any adjustments needed for the end times
18198a5489641442c022089ae1b00e498e2c1a0ba480Erik            if (isDSTEnd != isDSTStart) {
18208a5489641442c022089ae1b00e498e2c1a0ba480Erik                tzDisplay = TimeZone.getTimeZone(tz).getDisplayName(
18218a5489641442c022089ae1b00e498e2c1a0ba480Erik                        isDSTEnd, TimeZone.SHORT, Locale.getDefault());
18228a5489641442c022089ae1b00e498e2c1a0ba480Erik            }
18238a5489641442c022089ae1b00e498e2c1a0ba480Erik            flags = DateUtils.FORMAT_SHOW_TIME;
18248a5489641442c022089ae1b00e498e2c1a0ba480Erik            if (is24Format) {
18258a5489641442c022089ae1b00e498e2c1a0ba480Erik                flags |= DateUtils.FORMAT_24HOUR;
18268a5489641442c022089ae1b00e498e2c1a0ba480Erik            }
18278a5489641442c022089ae1b00e498e2c1a0ba480Erik
18288a5489641442c022089ae1b00e498e2c1a0ba480Erik            // Then update the end times
18298a5489641442c022089ae1b00e498e2c1a0ba480Erik            time.setLength(0);
18308a5489641442c022089ae1b00e498e2c1a0ba480Erik            mSB.setLength(0);
18318a5489641442c022089ae1b00e498e2c1a0ba480Erik            time.append(DateUtils.formatDateRange(
18328a5489641442c022089ae1b00e498e2c1a0ba480Erik                    mActivity, mF, millisEnd, millisEnd, flags, tz)).append(" ").append(tzDisplay);
18338a5489641442c022089ae1b00e498e2c1a0ba480Erik            mEndTimeHome.setText(time.toString());
18348a5489641442c022089ae1b00e498e2c1a0ba480Erik
18358a5489641442c022089ae1b00e498e2c1a0ba480Erik            flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE
18368a5489641442c022089ae1b00e498e2c1a0ba480Erik                    | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_WEEKDAY;
18378a5489641442c022089ae1b00e498e2c1a0ba480Erik            mSB.setLength(0);
18388a5489641442c022089ae1b00e498e2c1a0ba480Erik            mEndDateHome.setText(DateUtils.formatDateRange(
18398a5489641442c022089ae1b00e498e2c1a0ba480Erik                            mActivity, mF, millisEnd, millisEnd, flags, tz).toString());
18408a5489641442c022089ae1b00e498e2c1a0ba480Erik
18418a5489641442c022089ae1b00e498e2c1a0ba480Erik            mStartHomeGroup.setVisibility(View.VISIBLE);
18428a5489641442c022089ae1b00e498e2c1a0ba480Erik            mEndHomeGroup.setVisibility(View.VISIBLE);
18438a5489641442c022089ae1b00e498e2c1a0ba480Erik        } else {
18448a5489641442c022089ae1b00e498e2c1a0ba480Erik            mStartHomeGroup.setVisibility(View.GONE);
18458a5489641442c022089ae1b00e498e2c1a0ba480Erik            mEndHomeGroup.setVisibility(View.GONE);
18468a5489641442c022089ae1b00e498e2c1a0ba480Erik        }
18478a5489641442c022089ae1b00e498e2c1a0ba480Erik    }
18488a5489641442c022089ae1b00e498e2c1a0ba480Erik
18493400a2bfc1e6be435ea2bb0f436a6ef338446504Erik    @Override
18503400a2bfc1e6be435ea2bb0f436a6ef338446504Erik    public void onNothingSelected(AdapterView<?> parent) {
18513400a2bfc1e6be435ea2bb0f436a6ef338446504Erik    }
1852eca82e9468c002590045338f98588ad3ce1a0bb3Erik}
1853