Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Erik | fbce65e | 2010-08-16 12:43:13 -0700 | [diff] [blame] | 17 | package com.android.calendar.event; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 18 | |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 19 | import android.app.Activity; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 20 | import android.app.AlertDialog; |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 21 | import android.app.DialogFragment; |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 22 | import android.app.FragmentManager; |
Erik | 5f62079 | 2010-10-27 12:42:01 -0700 | [diff] [blame] | 23 | import android.app.ProgressDialog; |
Andy McFadden | ef31a98 | 2011-06-09 07:38:56 -0700 | [diff] [blame] | 24 | import android.app.Service; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 25 | import android.content.Context; |
| 26 | import android.content.DialogInterface; |
Daisuke Miyakawa | 464f350 | 2010-09-21 22:12:55 -0700 | [diff] [blame] | 27 | import android.content.Intent; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 28 | import android.content.SharedPreferences; |
| 29 | import android.content.res.Resources; |
| 30 | import android.database.Cursor; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 31 | import android.graphics.drawable.Drawable; |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 32 | import android.os.Bundle; |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 33 | import android.provider.CalendarContract; |
RoboErik | a7c0390 | 2011-06-14 11:06:44 -0700 | [diff] [blame] | 34 | import android.provider.CalendarContract.Attendees; |
| 35 | import android.provider.CalendarContract.Calendars; |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 36 | import android.provider.CalendarContract.Events; |
RoboErik | a7c0390 | 2011-06-14 11:06:44 -0700 | [diff] [blame] | 37 | import android.provider.CalendarContract.Reminders; |
Daisuke Miyakawa | 464f350 | 2010-09-21 22:12:55 -0700 | [diff] [blame] | 38 | import android.provider.Settings; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 39 | import android.text.InputFilter; |
| 40 | import android.text.TextUtils; |
| 41 | import android.text.format.DateFormat; |
| 42 | import android.text.format.DateUtils; |
| 43 | import android.text.format.Time; |
| 44 | import android.text.util.Rfc822Tokenizer; |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 45 | import android.util.Log; |
Sara Ting | 601ef6e | 2012-07-10 14:54:19 -0700 | [diff] [blame] | 46 | import android.view.KeyEvent; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 47 | import android.view.View; |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 48 | import android.view.View.OnClickListener; |
Erik | 259b8f9 | 2011-01-12 14:01:12 -0800 | [diff] [blame] | 49 | import android.view.ViewGroup; |
| 50 | import android.view.accessibility.AccessibilityEvent; |
| 51 | import android.view.accessibility.AccessibilityManager; |
Sara Ting | 601ef6e | 2012-07-10 14:54:19 -0700 | [diff] [blame] | 52 | import android.view.inputmethod.EditorInfo; |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 53 | import android.widget.AdapterView; |
| 54 | import android.widget.AdapterView.OnItemSelectedListener; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 55 | import android.widget.ArrayAdapter; |
Sara Ting | 601ef6e | 2012-07-10 14:54:19 -0700 | [diff] [blame] | 56 | import android.widget.AutoCompleteTextView; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 57 | import android.widget.Button; |
| 58 | import android.widget.CheckBox; |
| 59 | import android.widget.CompoundButton; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 60 | import android.widget.LinearLayout; |
| 61 | import android.widget.MultiAutoCompleteTextView; |
Erik | 259b8f9 | 2011-01-12 14:01:12 -0800 | [diff] [blame] | 62 | import android.widget.RadioButton; |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 63 | import android.widget.RadioGroup; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 64 | import android.widget.ResourceCursorAdapter; |
| 65 | import android.widget.ScrollView; |
| 66 | import android.widget.Spinner; |
| 67 | import android.widget.TextView; |
Sara Ting | 601ef6e | 2012-07-10 14:54:19 -0700 | [diff] [blame] | 68 | import android.widget.TextView.OnEditorActionListener; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 69 | |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 70 | import com.android.calendar.CalendarEventModel; |
| 71 | import com.android.calendar.CalendarEventModel.Attendee; |
| 72 | import com.android.calendar.CalendarEventModel.ReminderEntry; |
| 73 | import com.android.calendar.EmailAddressAdapter; |
| 74 | import com.android.calendar.EventInfoFragment; |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 75 | import com.android.calendar.EventRecurrenceFormatter; |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 76 | import com.android.calendar.GeneralPreferences; |
| 77 | import com.android.calendar.R; |
| 78 | import com.android.calendar.RecipientAdapter; |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 79 | import com.android.calendar.Utils; |
| 80 | import com.android.calendar.event.EditEventHelper.EditDoneRunnable; |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 81 | import com.android.calendar.recurrencepicker.RecurrencePickerDialog; |
Michael Chan | 8a528ad | 2012-06-26 17:44:34 -0700 | [diff] [blame] | 82 | import com.android.calendarcommon2.EventRecurrence; |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 83 | import com.android.common.Rfc822InputFilter; |
| 84 | import com.android.common.Rfc822Validator; |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 85 | import com.android.datetimepicker.date.DatePickerDialog; |
| 86 | import com.android.datetimepicker.date.DatePickerDialog.OnDateSetListener; |
| 87 | import com.android.datetimepicker.time.RadialPickerLayout; |
| 88 | import com.android.datetimepicker.time.TimePickerDialog; |
| 89 | import com.android.datetimepicker.time.TimePickerDialog.OnTimeSetListener; |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 90 | import com.android.ex.chips.AccountSpecifier; |
| 91 | import com.android.ex.chips.BaseRecipientAdapter; |
| 92 | import com.android.ex.chips.ChipsUtil; |
| 93 | import com.android.ex.chips.RecipientEditTextView; |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 94 | import com.android.timezonepicker.TimeZoneInfo; |
| 95 | import com.android.timezonepicker.TimeZonePickerDialog; |
James Kung | 974343a | 2013-04-03 16:12:38 -0700 | [diff] [blame] | 96 | import com.android.timezonepicker.TimeZonePickerUtils; |
Michael Chan | 9e196e4 | 2012-05-11 09:46:18 -0700 | [diff] [blame] | 97 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 98 | import java.util.ArrayList; |
| 99 | import java.util.Arrays; |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 100 | import java.util.Formatter; |
Erik | d845fbe | 2010-08-12 11:20:01 -0700 | [diff] [blame] | 101 | import java.util.HashMap; |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 102 | import java.util.Locale; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 103 | import java.util.TimeZone; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 104 | |
| 105 | public class EditEventView implements View.OnClickListener, DialogInterface.OnCancelListener, |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 106 | DialogInterface.OnClickListener, OnItemSelectedListener, |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 107 | RecurrencePickerDialog.OnRecurrenceSetListener, |
| 108 | TimeZonePickerDialog.OnTimeZoneSetListener { |
James Kung | bb90a7d | 2013-04-04 15:29:45 -0700 | [diff] [blame] | 109 | |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 110 | private static final String TAG = "EditEvent"; |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 111 | private static final String GOOGLE_SECONDARY_CALENDAR = "calendar.google.com"; |
Erik | 259b8f9 | 2011-01-12 14:01:12 -0800 | [diff] [blame] | 112 | private static final String PERIOD_SPACE = ". "; |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 113 | |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 114 | private static final String FRAG_TAG_DATE_PICKER = "datePickerDialogFragment"; |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 115 | private static final String FRAG_TAG_TIME_PICKER = "timePickerDialogFragment"; |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 116 | private static final String FRAG_TAG_TIME_ZONE_PICKER = "timeZonePickerDialogFragment"; |
| 117 | private static final String FRAG_TAG_RECUR_PICKER = "recurrencePickerDialogFragment"; |
Erik | d845fbe | 2010-08-12 11:20:01 -0700 | [diff] [blame] | 118 | |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 119 | ArrayList<View> mEditOnlyList = new ArrayList<View>(); |
| 120 | ArrayList<View> mEditViewList = new ArrayList<View>(); |
| 121 | ArrayList<View> mViewOnlyList = new ArrayList<View>(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 122 | TextView mLoadingMessage; |
| 123 | ScrollView mScrollView; |
| 124 | Button mStartDateButton; |
| 125 | Button mEndDateButton; |
| 126 | Button mStartTimeButton; |
| 127 | Button mEndTimeButton; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 128 | Button mTimezoneButton; |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 129 | View mColorPickerNewEvent; |
| 130 | View mColorPickerExistingEvent; |
| 131 | OnClickListener mChangeColorOnClickListener; |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 132 | View mTimezoneRow; |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 133 | TextView mStartTimeHome; |
| 134 | TextView mStartDateHome; |
| 135 | TextView mEndTimeHome; |
| 136 | TextView mEndDateHome; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 137 | CheckBox mAllDayCheckBox; |
| 138 | Spinner mCalendarsSpinner; |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 139 | Button mRruleButton; |
Michael Chan | ced0eb6 | 2011-05-31 18:12:52 -0700 | [diff] [blame] | 140 | Spinner mAvailabilitySpinner; |
| 141 | Spinner mAccessLevelSpinner; |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 142 | RadioGroup mResponseRadioGroup; |
Sara Ting | d19fa1c | 2012-12-05 11:02:11 -0800 | [diff] [blame] | 143 | TextView mTitleTextView; |
Sara Ting | 4686b40 | 2012-11-13 13:52:54 -0800 | [diff] [blame] | 144 | AutoCompleteTextView mLocationTextView; |
| 145 | EventLocationAdapter mLocationAdapter; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 146 | TextView mDescriptionTextView; |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 147 | TextView mWhenView; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 148 | TextView mTimezoneTextView; |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 149 | TextView mTimezoneLabel; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 150 | LinearLayout mRemindersContainer; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 151 | MultiAutoCompleteTextView mAttendeesList; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 152 | View mCalendarSelectorGroup; |
Mindy Pereira | eb51f84 | 2011-11-11 14:45:54 -0800 | [diff] [blame] | 153 | View mCalendarSelectorWrapper; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 154 | View mCalendarStaticGroup; |
Erik | a7694ee | 2010-12-07 15:46:18 -0800 | [diff] [blame] | 155 | View mLocationGroup; |
| 156 | View mDescriptionGroup; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 157 | View mRemindersGroup; |
| 158 | View mResponseGroup; |
| 159 | View mOrganizerGroup; |
| 160 | View mAttendeesGroup; |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 161 | View mStartHomeGroup; |
| 162 | View mEndHomeGroup; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 163 | |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 164 | private int[] mOriginalPadding = new int[4]; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 165 | |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 166 | public boolean mIsMultipane; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 167 | private ProgressDialog mLoadingCalendarsDialog; |
| 168 | private AlertDialog mNoCalendarsDialog; |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 169 | private DialogFragment mTimezoneDialog; |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 170 | private Activity mActivity; |
| 171 | private EditDoneRunnable mDone; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 172 | private View mView; |
| 173 | private CalendarEventModel mModel; |
| 174 | private Cursor mCalendarsCursor; |
Mindy Pereira | 18cabd2 | 2011-06-09 18:31:23 -0700 | [diff] [blame] | 175 | private AccountSpecifier mAddressAdapter; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 176 | private Rfc822Validator mEmailValidator; |
| 177 | |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 178 | public boolean mTimeSelectedWasStartTime; |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 179 | public boolean mDateSelectedWasStartDate; |
Sam Blitzstein | 3cde834 | 2013-04-01 13:11:15 -0700 | [diff] [blame] | 180 | private TimePickerDialog mStartTimePickerDialog; |
| 181 | private TimePickerDialog mEndTimePickerDialog; |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 182 | private DatePickerDialog mDatePickerDialog; |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 183 | |
Andy McFadden | fea9af5 | 2011-05-13 15:40:10 -0700 | [diff] [blame] | 184 | /** |
| 185 | * Contents of the "minutes" spinner. This has default values from the XML file, augmented |
| 186 | * with any additional values that were already associated with the event. |
| 187 | */ |
| 188 | private ArrayList<Integer> mReminderMinuteValues; |
| 189 | private ArrayList<String> mReminderMinuteLabels; |
| 190 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 191 | /** |
| 192 | * Contents of the "methods" spinner. The "values" list specifies the method constant |
| 193 | * (e.g. {@link Reminders#METHOD_ALERT}) associated with the labels. Any methods that |
| 194 | * aren't allowed by the Calendar will be removed. |
| 195 | */ |
| 196 | private ArrayList<Integer> mReminderMethodValues; |
| 197 | private ArrayList<String> mReminderMethodLabels; |
| 198 | |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 199 | /** |
| 200 | * Contents of the "availability" spinner. The "values" list specifies the |
| 201 | * type constant (e.g. {@link Events#AVAILABILITY_BUSY}) associated with the |
| 202 | * labels. Any types that aren't allowed by the Calendar will be removed. |
| 203 | */ |
| 204 | private ArrayList<Integer> mAvailabilityValues; |
| 205 | private ArrayList<String> mAvailabilityLabels; |
Sam Blitzstein | 7cdfb4d | 2013-02-22 15:30:27 -0800 | [diff] [blame] | 206 | private ArrayList<String> mOriginalAvailabilityLabels; |
| 207 | private ArrayAdapter<String> mAvailabilityAdapter; |
| 208 | private boolean mAvailabilityExplicitlySet; |
| 209 | private boolean mAllDayChangingAvailability; |
| 210 | private int mAvailabilityCurrentlySelected; |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 211 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 212 | private int mDefaultReminderMinutes; |
| 213 | |
| 214 | private boolean mSaveAfterQueryComplete = false; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 215 | |
Sam Blitzstein | 00040c6 | 2013-04-11 10:13:47 -0700 | [diff] [blame] | 216 | private TimeZonePickerUtils mTzPickerUtils; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 217 | private Time mStartTime; |
| 218 | private Time mEndTime; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 219 | private String mTimezone; |
Michael Chan | 8b1119b | 2012-01-06 16:04:55 -0800 | [diff] [blame] | 220 | private boolean mAllDay = false; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 221 | private int mModification = EditEventHelper.MODIFY_UNINITIALIZED; |
| 222 | |
| 223 | private EventRecurrence mEventRecurrence = new EventRecurrence(); |
| 224 | |
| 225 | private ArrayList<LinearLayout> mReminderItems = new ArrayList<LinearLayout>(0); |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 226 | private ArrayList<ReminderEntry> mUnsupportedReminders = new ArrayList<ReminderEntry>(); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 227 | private String mRrule; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 228 | |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 229 | private static StringBuilder mSB = new StringBuilder(50); |
| 230 | private static Formatter mF = new Formatter(mSB, Locale.getDefault()); |
| 231 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 232 | /* This class is used to update the time buttons. */ |
| 233 | private class TimeListener implements OnTimeSetListener { |
| 234 | private View mView; |
| 235 | |
| 236 | public TimeListener(View view) { |
| 237 | mView = view; |
| 238 | } |
| 239 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 240 | @Override |
Sam Blitzstein | d661d5f | 2013-03-29 15:34:59 -0700 | [diff] [blame] | 241 | public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 242 | // Cache the member variables locally to avoid inner class overhead. |
| 243 | Time startTime = mStartTime; |
| 244 | Time endTime = mEndTime; |
| 245 | |
| 246 | // Cache the start and end millis so that we limit the number |
| 247 | // of calls to normalize() and toMillis(), which are fairly |
| 248 | // expensive. |
| 249 | long startMillis; |
| 250 | long endMillis; |
| 251 | if (mView == mStartTimeButton) { |
| 252 | // The start time was changed. |
| 253 | int hourDuration = endTime.hour - startTime.hour; |
| 254 | int minuteDuration = endTime.minute - startTime.minute; |
| 255 | |
| 256 | startTime.hour = hourOfDay; |
| 257 | startTime.minute = minute; |
| 258 | startMillis = startTime.normalize(true); |
| 259 | |
| 260 | // Also update the end time to keep the duration constant. |
| 261 | endTime.hour = hourOfDay + hourDuration; |
| 262 | endTime.minute = minute + minuteDuration; |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 263 | |
| 264 | // Update tz in case the start time switched from/to DLS |
| 265 | populateTimezone(startMillis); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 266 | } else { |
| 267 | // The end time was changed. |
| 268 | startMillis = startTime.toMillis(true); |
| 269 | endTime.hour = hourOfDay; |
| 270 | endTime.minute = minute; |
| 271 | |
| 272 | // Move to the start time if the end time is before the start |
| 273 | // time. |
| 274 | if (endTime.before(startTime)) { |
| 275 | endTime.monthDay = startTime.monthDay + 1; |
| 276 | } |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 277 | // Call populateTimezone if we support end time zone as well |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 278 | } |
| 279 | |
| 280 | endMillis = endTime.normalize(true); |
| 281 | |
| 282 | setDate(mEndDateButton, endMillis); |
| 283 | setTime(mStartTimeButton, startMillis); |
| 284 | setTime(mEndTimeButton, endMillis); |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 285 | updateHomeTime(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 286 | } |
| 287 | } |
| 288 | |
| 289 | private class TimeClickListener implements View.OnClickListener { |
| 290 | private Time mTime; |
| 291 | |
| 292 | public TimeClickListener(Time time) { |
| 293 | mTime = time; |
| 294 | } |
| 295 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 296 | @Override |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 297 | public void onClick(View v) { |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 298 | |
Sam Blitzstein | 3cde834 | 2013-04-01 13:11:15 -0700 | [diff] [blame] | 299 | TimePickerDialog dialog; |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 300 | if (v == mStartTimeButton) { |
| 301 | mTimeSelectedWasStartTime = true; |
Sam Blitzstein | 3cde834 | 2013-04-01 13:11:15 -0700 | [diff] [blame] | 302 | if (mStartTimePickerDialog == null) { |
| 303 | mStartTimePickerDialog = TimePickerDialog.newInstance(new TimeListener(v), |
| 304 | mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity)); |
| 305 | } else { |
| 306 | mStartTimePickerDialog.setStartTime(mTime.hour, mTime.minute); |
| 307 | } |
| 308 | dialog = mStartTimePickerDialog; |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 309 | } else { |
| 310 | mTimeSelectedWasStartTime = false; |
Sam Blitzstein | 3cde834 | 2013-04-01 13:11:15 -0700 | [diff] [blame] | 311 | if (mEndTimePickerDialog == null) { |
| 312 | mEndTimePickerDialog = TimePickerDialog.newInstance(new TimeListener(v), |
| 313 | mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity)); |
| 314 | } else { |
| 315 | mEndTimePickerDialog.setStartTime(mTime.hour, mTime.minute); |
| 316 | } |
| 317 | dialog = mEndTimePickerDialog; |
| 318 | |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 319 | } |
| 320 | |
James Kung | 6a212e3 | 2013-04-11 17:03:56 -0700 | [diff] [blame] | 321 | final FragmentManager fm = mActivity.getFragmentManager(); |
| 322 | fm.executePendingTransactions(); |
| 323 | |
Sam Blitzstein | 3cde834 | 2013-04-01 13:11:15 -0700 | [diff] [blame] | 324 | if (dialog != null && !dialog.isAdded()) { |
Sam Blitzstein | 3cde834 | 2013-04-01 13:11:15 -0700 | [diff] [blame] | 325 | dialog.show(fm, FRAG_TAG_TIME_PICKER); |
| 326 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 327 | } |
| 328 | } |
| 329 | |
| 330 | private class DateListener implements OnDateSetListener { |
| 331 | View mView; |
| 332 | |
| 333 | public DateListener(View view) { |
| 334 | mView = view; |
| 335 | } |
| 336 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 337 | @Override |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 338 | public void onDateSet(DatePickerDialog view, int year, int month, int monthDay) { |
Michael Chan | 0a01fd3 | 2011-01-23 15:13:28 -0800 | [diff] [blame] | 339 | Log.d(TAG, "onDateSet: " + year + " " + month + " " + monthDay); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 340 | // Cache the member variables locally to avoid inner class overhead. |
| 341 | Time startTime = mStartTime; |
| 342 | Time endTime = mEndTime; |
| 343 | |
| 344 | // Cache the start and end millis so that we limit the number |
| 345 | // of calls to normalize() and toMillis(), which are fairly |
| 346 | // expensive. |
| 347 | long startMillis; |
| 348 | long endMillis; |
| 349 | if (mView == mStartDateButton) { |
| 350 | // The start date was changed. |
| 351 | int yearDuration = endTime.year - startTime.year; |
| 352 | int monthDuration = endTime.month - startTime.month; |
| 353 | int monthDayDuration = endTime.monthDay - startTime.monthDay; |
| 354 | |
| 355 | startTime.year = year; |
| 356 | startTime.month = month; |
| 357 | startTime.monthDay = monthDay; |
| 358 | startMillis = startTime.normalize(true); |
| 359 | |
| 360 | // Also update the end date to keep the duration constant. |
| 361 | endTime.year = year + yearDuration; |
| 362 | endTime.month = month + monthDuration; |
| 363 | endTime.monthDay = monthDay + monthDayDuration; |
| 364 | endMillis = endTime.normalize(true); |
| 365 | |
| 366 | // If the start date has changed then update the repeats. |
| 367 | populateRepeats(); |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 368 | |
| 369 | // Update tz in case the start time switched from/to DLS |
| 370 | populateTimezone(startMillis); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 371 | } else { |
| 372 | // The end date was changed. |
| 373 | startMillis = startTime.toMillis(true); |
| 374 | endTime.year = year; |
| 375 | endTime.month = month; |
| 376 | endTime.monthDay = monthDay; |
| 377 | endMillis = endTime.normalize(true); |
| 378 | |
| 379 | // Do not allow an event to have an end time before the start |
| 380 | // time. |
| 381 | if (endTime.before(startTime)) { |
| 382 | endTime.set(startTime); |
| 383 | endMillis = startMillis; |
| 384 | } |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 385 | // Call populateTimezone if we support end time zone as well |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 386 | } |
| 387 | |
| 388 | setDate(mStartDateButton, startMillis); |
| 389 | setDate(mEndDateButton, endMillis); |
| 390 | setTime(mEndTimeButton, endMillis); // In case end time had to be |
| 391 | // reset |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 392 | updateHomeTime(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 393 | } |
| 394 | } |
| 395 | |
| 396 | // Fills in the date and time fields |
| 397 | private void populateWhen() { |
| 398 | long startMillis = mStartTime.toMillis(false /* use isDst */); |
| 399 | long endMillis = mEndTime.toMillis(false /* use isDst */); |
| 400 | setDate(mStartDateButton, startMillis); |
| 401 | setDate(mEndDateButton, endMillis); |
| 402 | |
| 403 | setTime(mStartTimeButton, startMillis); |
| 404 | setTime(mEndTimeButton, endMillis); |
| 405 | |
| 406 | mStartDateButton.setOnClickListener(new DateClickListener(mStartTime)); |
| 407 | mEndDateButton.setOnClickListener(new DateClickListener(mEndTime)); |
| 408 | |
| 409 | mStartTimeButton.setOnClickListener(new TimeClickListener(mStartTime)); |
| 410 | mEndTimeButton.setOnClickListener(new TimeClickListener(mEndTime)); |
| 411 | } |
| 412 | |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 413 | // Implements OnTimeZoneSetListener |
| 414 | @Override |
| 415 | public void onTimeZoneSet(TimeZoneInfo tzi) { |
| 416 | setTimezone(tzi.mTzId); |
| 417 | updateHomeTime(); |
| 418 | } |
| 419 | |
| 420 | private void setTimezone(String timeZone) { |
| 421 | mTimezone = timeZone; |
| 422 | mStartTime.timezone = mTimezone; |
| 423 | long timeMillis = mStartTime.normalize(true); |
| 424 | mEndTime.timezone = mTimezone; |
| 425 | mEndTime.normalize(true); |
| 426 | |
| 427 | populateTimezone(timeMillis); |
| 428 | } |
| 429 | |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 430 | private void populateTimezone(long eventStartTime) { |
Sam Blitzstein | 00040c6 | 2013-04-11 10:13:47 -0700 | [diff] [blame] | 431 | if (mTzPickerUtils == null) { |
| 432 | mTzPickerUtils = new TimeZonePickerUtils(mActivity); |
| 433 | } |
| 434 | String displayName = mTzPickerUtils.getGmtDisplayName(mActivity, mTimezone, eventStartTime); |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 435 | |
| 436 | mTimezoneTextView.setText(displayName); |
| 437 | mTimezoneButton.setText(displayName); |
| 438 | } |
| 439 | |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 440 | private void showTimezoneDialog() { |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 441 | Bundle b = new Bundle(); |
| 442 | b.putLong(TimeZonePickerDialog.BUNDLE_START_TIME_MILLIS, mStartTime.toMillis(false)); |
| 443 | b.putString(TimeZonePickerDialog.BUNDLE_TIME_ZONE, mTimezone); |
Michael Chan | f428b1e | 2011-01-04 14:11:40 -0800 | [diff] [blame] | 444 | |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 445 | FragmentManager fm = mActivity.getFragmentManager(); |
| 446 | TimeZonePickerDialog tzpd = (TimeZonePickerDialog) fm |
| 447 | .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER); |
| 448 | if (tzpd != null) { |
| 449 | tzpd.dismiss(); |
| 450 | } |
| 451 | tzpd = new TimeZonePickerDialog(); |
| 452 | tzpd.setArguments(b); |
| 453 | tzpd.setOnTimeZoneSetListener(EditEventView.this); |
| 454 | tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER); |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 455 | } |
| 456 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 457 | private void populateRepeats() { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 458 | Resources r = mActivity.getResources(); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 459 | String repeatString; |
| 460 | boolean enabled; |
| 461 | if (!TextUtils.isEmpty(mRrule)) { |
| 462 | repeatString = EventRecurrenceFormatter.getRepeatString(mActivity, r, |
| 463 | mEventRecurrence, true); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 464 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 465 | if (repeatString == null) { |
| 466 | repeatString = r.getString(R.string.custom); |
| 467 | Log.e(TAG, "Can't generate display string for " + mRrule); |
| 468 | enabled = false; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 469 | } else { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 470 | // TODO Should give option to clear/reset rrule |
| 471 | enabled = RecurrencePickerDialog.canHandleRecurrenceRule(mEventRecurrence); |
| 472 | if (!enabled) { |
| 473 | Log.e(TAG, "UI can't handle " + mRrule); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 474 | } |
| 475 | } |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 476 | } else { |
| 477 | repeatString = r.getString(R.string.does_not_repeat); |
| 478 | enabled = true; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 479 | } |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 480 | |
| 481 | mRruleButton.setText(repeatString); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 482 | |
| 483 | // Don't allow the user to make exceptions recurring events. |
RoboErik | 28dab65 | 2011-07-21 15:08:39 -0700 | [diff] [blame] | 484 | if (mModel.mOriginalSyncId != null) { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 485 | enabled = false; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 486 | } |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 487 | mRruleButton.setOnClickListener(this); |
| 488 | mRruleButton.setEnabled(enabled); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 489 | } |
| 490 | |
| 491 | private class DateClickListener implements View.OnClickListener { |
| 492 | private Time mTime; |
| 493 | |
| 494 | public DateClickListener(Time time) { |
| 495 | mTime = time; |
| 496 | } |
| 497 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 498 | @Override |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 499 | public void onClick(View v) { |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 500 | |
| 501 | if (v == mStartDateButton) { |
| 502 | mDateSelectedWasStartDate = true; |
RoboErik | cf7b691 | 2011-02-25 15:37:48 -0800 | [diff] [blame] | 503 | } else { |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 504 | mDateSelectedWasStartDate = false; |
RoboErik | cf7b691 | 2011-02-25 15:37:48 -0800 | [diff] [blame] | 505 | } |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 506 | |
| 507 | final DateListener listener = new DateListener(v); |
| 508 | if (mDatePickerDialog != null) { |
| 509 | mDatePickerDialog.dismiss(); |
| 510 | } |
| 511 | mDatePickerDialog = DatePickerDialog.newInstance(listener, |
| 512 | mTime.year, mTime.month, mTime.monthDay); |
| 513 | mDatePickerDialog.setFirstDayOfWeek(Utils.getFirstDayOfWeekAsCalendar(mActivity)); |
| 514 | mDatePickerDialog.setYearRange(Utils.YEAR_MIN, Utils.YEAR_MAX); |
| 515 | mDatePickerDialog.show(mActivity.getFragmentManager(), FRAG_TAG_DATE_PICKER); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 516 | } |
| 517 | } |
| 518 | |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 519 | public static class CalendarsAdapter extends ResourceCursorAdapter { |
| 520 | public CalendarsAdapter(Context context, int resourceId, Cursor c) { |
| 521 | super(context, resourceId, c); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 522 | setDropDownViewResource(R.layout.calendars_dropdown_item); |
| 523 | } |
| 524 | |
| 525 | @Override |
| 526 | public void bindView(View view, Context context, Cursor cursor) { |
| 527 | View colorBar = view.findViewById(R.id.color); |
RoboErik | 0e1e624 | 2011-05-05 15:25:02 -0700 | [diff] [blame] | 528 | int colorColumn = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR); |
RoboErik | ef2add9 | 2011-06-09 14:49:53 -0700 | [diff] [blame] | 529 | int nameColumn = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 530 | int ownerColumn = cursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT); |
| 531 | if (colorBar != null) { |
RoboErik | 4acb2fd | 2011-07-18 15:39:49 -0700 | [diff] [blame] | 532 | colorBar.setBackgroundColor(Utils.getDisplayColorFromColor(cursor |
| 533 | .getInt(colorColumn))); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 534 | } |
| 535 | |
| 536 | TextView name = (TextView) view.findViewById(R.id.calendar_name); |
| 537 | if (name != null) { |
| 538 | String displayName = cursor.getString(nameColumn); |
| 539 | name.setText(displayName); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 540 | |
| 541 | TextView accountName = (TextView) view.findViewById(R.id.account_name); |
| 542 | if (accountName != null) { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 543 | accountName.setText(cursor.getString(ownerColumn)); |
| 544 | accountName.setVisibility(TextView.VISIBLE); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 545 | } |
| 546 | } |
| 547 | } |
| 548 | } |
| 549 | |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 550 | /** |
| 551 | * Does prep steps for saving a calendar event. |
| 552 | * |
| 553 | * This triggers a parse of the attendees list and checks if the event is |
Erik | 5f62079 | 2010-10-27 12:42:01 -0700 | [diff] [blame] | 554 | * ready to be saved. An event is ready to be saved so long as a model |
| 555 | * exists and has a calendar it can be associated with, either because it's |
| 556 | * an existing event or we've finished querying. |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 557 | * |
Erik | 5f62079 | 2010-10-27 12:42:01 -0700 | [diff] [blame] | 558 | * @return false if there is no model or no calendar had been loaded yet, |
| 559 | * true otherwise. |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 560 | */ |
| 561 | public boolean prepareForSave() { |
Erik | 5f62079 | 2010-10-27 12:42:01 -0700 | [diff] [blame] | 562 | if (mModel == null || (mCalendarsCursor == null && mModel.mUri == null)) { |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 563 | return false; |
| 564 | } |
Erik | 5f62079 | 2010-10-27 12:42:01 -0700 | [diff] [blame] | 565 | return fillModelFromUI(); |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 566 | } |
| 567 | |
Erik | a7694ee | 2010-12-07 15:46:18 -0800 | [diff] [blame] | 568 | public boolean fillModelFromReadOnlyUi() { |
| 569 | if (mModel == null || (mCalendarsCursor == null && mModel.mUri == null)) { |
| 570 | return false; |
| 571 | } |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 572 | mModel.mReminders = EventViewUtils.reminderItemsToReminders( |
| 573 | mReminderItems, mReminderMinuteValues, mReminderMethodValues); |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 574 | mModel.mReminders.addAll(mUnsupportedReminders); |
| 575 | mModel.normalizeReminders(); |
Erik | a7694ee | 2010-12-07 15:46:18 -0800 | [diff] [blame] | 576 | int status = EventInfoFragment.getResponseFromButtonId( |
| 577 | mResponseRadioGroup.getCheckedRadioButtonId()); |
| 578 | if (status != Attendees.ATTENDEE_STATUS_NONE) { |
| 579 | mModel.mSelfAttendeeStatus = status; |
| 580 | } |
| 581 | return true; |
| 582 | } |
| 583 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 584 | // This is called if the user clicks on one of the buttons: "Save", |
| 585 | // "Discard", or "Delete". This is also called if the user clicks |
| 586 | // on the "remove reminder" button. |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 587 | @Override |
Daisuke Miyakawa | bdcb9fc | 2010-10-18 13:10:56 -0700 | [diff] [blame] | 588 | public void onClick(View view) { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 589 | if (view == mRruleButton) { |
| 590 | Bundle b = new Bundle(); |
| 591 | b.putLong(RecurrencePickerDialog.BUNDLE_START_TIME_MILLIS, |
| 592 | mStartTime.toMillis(false)); |
| 593 | b.putString(RecurrencePickerDialog.BUNDLE_TIME_ZONE, mStartTime.timezone); |
| 594 | |
| 595 | // TODO may be more efficient to serialize and pass in EventRecurrence |
| 596 | b.putString(RecurrencePickerDialog.BUNDLE_RRULE, mRrule); |
| 597 | |
| 598 | FragmentManager fm = mActivity.getFragmentManager(); |
| 599 | RecurrencePickerDialog rpd = (RecurrencePickerDialog) fm |
| 600 | .findFragmentByTag(FRAG_TAG_RECUR_PICKER); |
| 601 | if (rpd != null) { |
| 602 | rpd.dismiss(); |
| 603 | } |
| 604 | rpd = new RecurrencePickerDialog(); |
| 605 | rpd.setArguments(b); |
| 606 | rpd.setOnRecurrenceSetListener(EditEventView.this); |
| 607 | rpd.show(fm, FRAG_TAG_RECUR_PICKER); |
| 608 | return; |
| 609 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 610 | |
| 611 | // This must be a click on one of the "remove reminder" buttons |
Daisuke Miyakawa | bdcb9fc | 2010-10-18 13:10:56 -0700 | [diff] [blame] | 612 | LinearLayout reminderItem = (LinearLayout) view.getParent(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 613 | LinearLayout parent = (LinearLayout) reminderItem.getParent(); |
| 614 | parent.removeView(reminderItem); |
| 615 | mReminderItems.remove(reminderItem); |
| 616 | updateRemindersVisibility(mReminderItems.size()); |
Sara Ting | 06f3d6d | 2012-03-23 17:19:22 -0700 | [diff] [blame] | 617 | EventViewUtils.updateAddReminderButton(mView, mReminderItems, mModel.mCalendarMaxReminders); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 618 | } |
| 619 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 620 | @Override |
| 621 | public void onRecurrenceSet(String rrule) { |
| 622 | Log.d(TAG, "Old rrule:" + mRrule); |
| 623 | Log.d(TAG, "New rrule:" + rrule); |
| 624 | mRrule = rrule; |
| 625 | if (mRrule != null) { |
| 626 | mEventRecurrence.parse(mRrule); |
| 627 | } |
| 628 | populateRepeats(); |
| 629 | } |
| 630 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 631 | // This is called if the user cancels the "No calendars" dialog. |
| 632 | // The "No calendars" dialog is shown if there are no syncable calendars. |
Michael Chan | ddbf808 | 2010-10-26 19:09:32 -0700 | [diff] [blame] | 633 | @Override |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 634 | public void onCancel(DialogInterface dialog) { |
| 635 | if (dialog == mLoadingCalendarsDialog) { |
| 636 | mLoadingCalendarsDialog = null; |
| 637 | mSaveAfterQueryComplete = false; |
| 638 | } else if (dialog == mNoCalendarsDialog) { |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 639 | mDone.setDoneCode(Utils.DONE_REVERT); |
| 640 | mDone.run(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 641 | return; |
| 642 | } |
| 643 | } |
| 644 | |
| 645 | // This is called if the user clicks on a dialog button. |
Daisuke Miyakawa | bdcb9fc | 2010-10-18 13:10:56 -0700 | [diff] [blame] | 646 | @Override |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 647 | public void onClick(DialogInterface dialog, int which) { |
| 648 | if (dialog == mNoCalendarsDialog) { |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 649 | mDone.setDoneCode(Utils.DONE_REVERT); |
| 650 | mDone.run(); |
Daisuke Miyakawa | 464f350 | 2010-09-21 22:12:55 -0700 | [diff] [blame] | 651 | if (which == DialogInterface.BUTTON_POSITIVE) { |
| 652 | Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT); |
| 653 | final String[] array = {"com.android.calendar"}; |
| 654 | nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array); |
RoboErik | 15b4dcc | 2011-09-19 16:21:27 -0700 | [diff] [blame] | 655 | nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); |
Daisuke Miyakawa | 464f350 | 2010-09-21 22:12:55 -0700 | [diff] [blame] | 656 | mActivity.startActivity(nextIntent); |
| 657 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 658 | } |
| 659 | } |
| 660 | |
| 661 | // Goes through the UI elements and updates the model as necessary |
Michael Chan | ddbf808 | 2010-10-26 19:09:32 -0700 | [diff] [blame] | 662 | private boolean fillModelFromUI() { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 663 | if (mModel == null) { |
| 664 | return false; |
| 665 | } |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 666 | mModel.mReminders = EventViewUtils.reminderItemsToReminders(mReminderItems, |
| 667 | mReminderMinuteValues, mReminderMethodValues); |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 668 | mModel.mReminders.addAll(mUnsupportedReminders); |
| 669 | mModel.normalizeReminders(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 670 | mModel.mHasAlarm = mReminderItems.size() > 0; |
Michael Chan | 7858f77 | 2011-01-26 17:46:19 -0800 | [diff] [blame] | 671 | mModel.mTitle = mTitleTextView.getText().toString(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 672 | mModel.mAllDay = mAllDayCheckBox.isChecked(); |
Michael Chan | 7858f77 | 2011-01-26 17:46:19 -0800 | [diff] [blame] | 673 | mModel.mLocation = mLocationTextView.getText().toString(); |
| 674 | mModel.mDescription = mDescriptionTextView.getText().toString(); |
Erik | cfa4b5b | 2010-12-10 15:14:10 -0800 | [diff] [blame] | 675 | if (TextUtils.isEmpty(mModel.mLocation)) { |
| 676 | mModel.mLocation = null; |
| 677 | } |
| 678 | if (TextUtils.isEmpty(mModel.mDescription)) { |
| 679 | mModel.mDescription = null; |
| 680 | } |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 681 | |
| 682 | int status = EventInfoFragment.getResponseFromButtonId(mResponseRadioGroup |
| 683 | .getCheckedRadioButtonId()); |
| 684 | if (status != Attendees.ATTENDEE_STATUS_NONE) { |
| 685 | mModel.mSelfAttendeeStatus = status; |
Erik | d845fbe | 2010-08-12 11:20:01 -0700 | [diff] [blame] | 686 | } |
| 687 | |
RoboErik | e0e2a4f | 2011-08-09 11:31:42 -0700 | [diff] [blame] | 688 | if (mAttendeesList != null) { |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 689 | mEmailValidator.setRemoveInvalid(true); |
| 690 | mAttendeesList.performValidation(); |
RoboErik | e0e2a4f | 2011-08-09 11:31:42 -0700 | [diff] [blame] | 691 | mModel.mAttendeesList.clear(); |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 692 | mModel.addAttendees(mAttendeesList.getText().toString(), mEmailValidator); |
RoboErik | e0e2a4f | 2011-08-09 11:31:42 -0700 | [diff] [blame] | 693 | mEmailValidator.setRemoveInvalid(false); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 694 | } |
| 695 | |
| 696 | // If this was a new event we need to fill in the Calendar information |
| 697 | if (mModel.mUri == null) { |
| 698 | mModel.mCalendarId = mCalendarsSpinner.getSelectedItemId(); |
| 699 | int calendarCursorPosition = mCalendarsSpinner.getSelectedItemPosition(); |
| 700 | if (mCalendarsCursor.moveToPosition(calendarCursorPosition)) { |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 701 | String defaultCalendar = mCalendarsCursor.getString( |
| 702 | EditEventHelper.CALENDARS_INDEX_OWNER_ACCOUNT); |
| 703 | Utils.setSharedPreference( |
| 704 | mActivity, GeneralPreferences.KEY_DEFAULT_CALENDAR, defaultCalendar); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 705 | mModel.mOwnerAccount = defaultCalendar; |
| 706 | mModel.mOrganizer = defaultCalendar; |
| 707 | mModel.mCalendarId = mCalendarsCursor.getLong(EditEventHelper.CALENDARS_INDEX_ID); |
| 708 | } |
| 709 | } |
| 710 | |
| 711 | if (mModel.mAllDay) { |
| 712 | // Reset start and end time, increment the monthDay by 1, and set |
| 713 | // the timezone to UTC, as required for all-day events. |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 714 | mTimezone = Time.TIMEZONE_UTC; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 715 | mStartTime.hour = 0; |
| 716 | mStartTime.minute = 0; |
| 717 | mStartTime.second = 0; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 718 | mStartTime.timezone = mTimezone; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 719 | mModel.mStart = mStartTime.normalize(true); |
| 720 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 721 | mEndTime.hour = 0; |
| 722 | mEndTime.minute = 0; |
| 723 | mEndTime.second = 0; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 724 | mEndTime.timezone = mTimezone; |
Daisuke Miyakawa | 2919097 | 2010-10-27 13:14:38 -0700 | [diff] [blame] | 725 | // When a user see the event duration as "X - Y" (e.g. Oct. 28 - Oct. 29), end time |
| 726 | // should be Y + 1 (Oct.30). |
| 727 | final long normalizedEndTimeMillis = |
| 728 | mEndTime.normalize(true) + DateUtils.DAY_IN_MILLIS; |
| 729 | if (normalizedEndTimeMillis < mModel.mStart) { |
| 730 | // mEnd should be midnight of the next day of mStart. |
| 731 | mModel.mEnd = mModel.mStart + DateUtils.DAY_IN_MILLIS; |
| 732 | } else { |
| 733 | mModel.mEnd = normalizedEndTimeMillis; |
| 734 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 735 | } else { |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 736 | mStartTime.timezone = mTimezone; |
| 737 | mEndTime.timezone = mTimezone; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 738 | mModel.mStart = mStartTime.toMillis(true); |
| 739 | mModel.mEnd = mEndTime.toMillis(true); |
| 740 | } |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 741 | mModel.mTimezone = mTimezone; |
Michael Chan | ced0eb6 | 2011-05-31 18:12:52 -0700 | [diff] [blame] | 742 | mModel.mAccessLevel = mAccessLevelSpinner.getSelectedItemPosition(); |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 743 | // TODO set correct availability value |
| 744 | mModel.mAvailability = mAvailabilityValues.get(mAvailabilitySpinner |
| 745 | .getSelectedItemPosition()); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 746 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 747 | // rrrule |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 748 | // If we're making an exception we don't want it to be a repeating |
| 749 | // event. |
| 750 | if (mModification == EditEventHelper.MODIFY_SELECTED) { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 751 | mModel.mRrule = null; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 752 | } else { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 753 | mModel.mRrule = mRrule; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 754 | } |
| 755 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 756 | return true; |
| 757 | } |
| 758 | |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 759 | public EditEventView(Activity activity, View view, EditDoneRunnable done, |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 760 | boolean timeSelectedWasStartTime, boolean dateSelectedWasStartDate) { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 761 | |
| 762 | mActivity = activity; |
| 763 | mView = view; |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 764 | mDone = done; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 765 | |
| 766 | // cache top level view elements |
| 767 | mLoadingMessage = (TextView) view.findViewById(R.id.loading_message); |
| 768 | mScrollView = (ScrollView) view.findViewById(R.id.scroll_view); |
| 769 | |
| 770 | // cache all the widgets |
Michael Chan | 9d5f351 | 2010-11-05 16:23:57 -0700 | [diff] [blame] | 771 | mCalendarsSpinner = (Spinner) view.findViewById(R.id.calendars_spinner); |
Sara Ting | d19fa1c | 2012-12-05 11:02:11 -0800 | [diff] [blame] | 772 | mTitleTextView = (TextView) view.findViewById(R.id.title); |
Sara Ting | 4686b40 | 2012-11-13 13:52:54 -0800 | [diff] [blame] | 773 | mLocationTextView = (AutoCompleteTextView) view.findViewById(R.id.location); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 774 | mDescriptionTextView = (TextView) view.findViewById(R.id.description); |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 775 | mTimezoneLabel = (TextView) view.findViewById(R.id.timezone_label); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 776 | mStartDateButton = (Button) view.findViewById(R.id.start_date); |
| 777 | mEndDateButton = (Button) view.findViewById(R.id.end_date); |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 778 | mWhenView = (TextView) mView.findViewById(R.id.when); |
| 779 | mTimezoneTextView = (TextView) mView.findViewById(R.id.timezone_textView); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 780 | mStartTimeButton = (Button) view.findViewById(R.id.start_time); |
| 781 | mEndTimeButton = (Button) view.findViewById(R.id.end_time); |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 782 | mTimezoneButton = (Button) view.findViewById(R.id.timezone_button); |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 783 | mTimezoneButton.setOnClickListener(new View.OnClickListener() { |
| 784 | @Override |
| 785 | public void onClick(View v) { |
| 786 | showTimezoneDialog(); |
| 787 | } |
| 788 | }); |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 789 | mTimezoneRow = view.findViewById(R.id.timezone_button_row); |
Isaac Katzenelson | 476ba39 | 2011-04-07 13:33:56 -0700 | [diff] [blame] | 790 | mStartTimeHome = (TextView) view.findViewById(R.id.start_time_home_tz); |
| 791 | mStartDateHome = (TextView) view.findViewById(R.id.start_date_home_tz); |
| 792 | mEndTimeHome = (TextView) view.findViewById(R.id.end_time_home_tz); |
| 793 | mEndDateHome = (TextView) view.findViewById(R.id.end_date_home_tz); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 794 | mAllDayCheckBox = (CheckBox) view.findViewById(R.id.is_all_day); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 795 | mRruleButton = (Button) view.findViewById(R.id.rrule); |
Michael Chan | ced0eb6 | 2011-05-31 18:12:52 -0700 | [diff] [blame] | 796 | mAvailabilitySpinner = (Spinner) view.findViewById(R.id.availability); |
| 797 | mAccessLevelSpinner = (Spinner) view.findViewById(R.id.visibility); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 798 | mCalendarSelectorGroup = view.findViewById(R.id.calendar_selector_group); |
Mindy Pereira | eb51f84 | 2011-11-11 14:45:54 -0800 | [diff] [blame] | 799 | mCalendarSelectorWrapper = view.findViewById(R.id.calendar_selector_wrapper); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 800 | mCalendarStaticGroup = view.findViewById(R.id.calendar_group); |
| 801 | mRemindersGroup = view.findViewById(R.id.reminders_row); |
| 802 | mResponseGroup = view.findViewById(R.id.response_row); |
| 803 | mOrganizerGroup = view.findViewById(R.id.organizer_row); |
Michael Chan | 1ab41bf | 2011-08-10 18:20:14 -0700 | [diff] [blame] | 804 | mAttendeesGroup = view.findViewById(R.id.add_attendees_row); |
Erik | a7694ee | 2010-12-07 15:46:18 -0800 | [diff] [blame] | 805 | mLocationGroup = view.findViewById(R.id.where_row); |
| 806 | mDescriptionGroup = view.findViewById(R.id.description_row); |
Isaac Katzenelson | 476ba39 | 2011-04-07 13:33:56 -0700 | [diff] [blame] | 807 | mStartHomeGroup = view.findViewById(R.id.from_row_home_tz); |
| 808 | mEndHomeGroup = view.findViewById(R.id.to_row_home_tz); |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 809 | mAttendeesList = (MultiAutoCompleteTextView) view.findViewById(R.id.attendees); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 810 | |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 811 | mColorPickerNewEvent = view.findViewById(R.id.change_color_new_event); |
| 812 | mColorPickerExistingEvent = view.findViewById(R.id.change_color_existing_event); |
| 813 | |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 814 | mTitleTextView.setTag(mTitleTextView.getBackground()); |
| 815 | mLocationTextView.setTag(mLocationTextView.getBackground()); |
Sara Ting | 4686b40 | 2012-11-13 13:52:54 -0800 | [diff] [blame] | 816 | mLocationAdapter = new EventLocationAdapter(activity); |
| 817 | mLocationTextView.setAdapter(mLocationAdapter); |
| 818 | mLocationTextView.setOnEditorActionListener(new OnEditorActionListener() { |
| 819 | @Override |
| 820 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { |
| 821 | if (actionId == EditorInfo.IME_ACTION_DONE) { |
| 822 | // Dismiss the suggestions dropdown. Return false so the other |
| 823 | // side effects still occur (soft keyboard going away, etc.). |
| 824 | mLocationTextView.dismissDropDown(); |
| 825 | } |
| 826 | return false; |
| 827 | } |
| 828 | }); |
| 829 | |
Sam Blitzstein | 7cdfb4d | 2013-02-22 15:30:27 -0800 | [diff] [blame] | 830 | mAvailabilityExplicitlySet = false; |
| 831 | mAllDayChangingAvailability = false; |
| 832 | mAvailabilityCurrentlySelected = -1; |
| 833 | mAvailabilitySpinner.setOnItemSelectedListener( |
| 834 | new OnItemSelectedListener() { |
| 835 | @Override |
| 836 | public void onItemSelected(AdapterView<?> parent, |
| 837 | View view, int position, long id) { |
| 838 | // The spinner's onItemSelected gets called while it is being |
| 839 | // initialized to the first item, and when we explicitly set it |
| 840 | // in the allDay checkbox toggling, so we need these checks to |
| 841 | // find out when the spinner is actually being clicked. |
| 842 | |
| 843 | // Set the initial selection. |
| 844 | if (mAvailabilityCurrentlySelected == -1) { |
| 845 | mAvailabilityCurrentlySelected = position; |
| 846 | } |
| 847 | |
| 848 | if (mAvailabilityCurrentlySelected != position && |
| 849 | !mAllDayChangingAvailability) { |
| 850 | mAvailabilityExplicitlySet = true; |
| 851 | } else { |
| 852 | mAvailabilityCurrentlySelected = position; |
| 853 | mAllDayChangingAvailability = false; |
| 854 | } |
| 855 | } |
| 856 | @Override |
| 857 | public void onNothingSelected(AdapterView<?> arg0) { } |
| 858 | }); |
| 859 | |
Sara Ting | 4686b40 | 2012-11-13 13:52:54 -0800 | [diff] [blame] | 860 | |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 861 | mDescriptionTextView.setTag(mDescriptionTextView.getBackground()); |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 862 | mAttendeesList.setTag(mAttendeesList.getBackground()); |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 863 | mOriginalPadding[0] = mLocationTextView.getPaddingLeft(); |
| 864 | mOriginalPadding[1] = mLocationTextView.getPaddingTop(); |
| 865 | mOriginalPadding[2] = mLocationTextView.getPaddingRight(); |
| 866 | mOriginalPadding[3] = mLocationTextView.getPaddingBottom(); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 867 | mEditViewList.add(mTitleTextView); |
| 868 | mEditViewList.add(mLocationTextView); |
| 869 | mEditViewList.add(mDescriptionTextView); |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 870 | mEditViewList.add(mAttendeesList); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 871 | |
| 872 | mViewOnlyList.add(view.findViewById(R.id.when_row)); |
| 873 | mViewOnlyList.add(view.findViewById(R.id.timezone_textview_row)); |
| 874 | |
| 875 | mEditOnlyList.add(view.findViewById(R.id.all_day_row)); |
| 876 | mEditOnlyList.add(view.findViewById(R.id.availability_row)); |
| 877 | mEditOnlyList.add(view.findViewById(R.id.visibility_row)); |
| 878 | mEditOnlyList.add(view.findViewById(R.id.from_row)); |
| 879 | mEditOnlyList.add(view.findViewById(R.id.to_row)); |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 880 | mEditOnlyList.add(mTimezoneRow); |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 881 | mEditOnlyList.add(mStartHomeGroup); |
| 882 | mEditOnlyList.add(mEndHomeGroup); |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 883 | |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 884 | mResponseRadioGroup = (RadioGroup) view.findViewById(R.id.response_value); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 885 | mRemindersContainer = (LinearLayout) view.findViewById(R.id.reminder_items_container); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 886 | |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 887 | mTimezone = Utils.getTimeZone(activity, null); |
RoboErik | 3a00271 | 2011-08-17 18:18:37 -0700 | [diff] [blame] | 888 | mIsMultipane = activity.getResources().getBoolean(R.bool.tablet_config); |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 889 | mStartTime = new Time(mTimezone); |
| 890 | mEndTime = new Time(mTimezone); |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 891 | mEmailValidator = new Rfc822Validator(null); |
| 892 | initMultiAutoCompleteTextView((RecipientEditTextView) mAttendeesList); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 893 | |
| 894 | // Display loading screen |
| 895 | setModel(null); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 896 | |
| 897 | FragmentManager fm = activity.getFragmentManager(); |
| 898 | RecurrencePickerDialog rpd = (RecurrencePickerDialog) fm |
| 899 | .findFragmentByTag(FRAG_TAG_RECUR_PICKER); |
| 900 | if (rpd != null) { |
| 901 | rpd.setOnRecurrenceSetListener(this); |
| 902 | } |
Michael Chan | e6aa937 | 2013-04-01 00:31:54 -0700 | [diff] [blame] | 903 | TimeZonePickerDialog tzpd = (TimeZonePickerDialog) fm |
| 904 | .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER); |
| 905 | if (tzpd != null) { |
| 906 | tzpd.setOnTimeZoneSetListener(this); |
| 907 | } |
Sam Blitzstein | 7674b69 | 2013-01-29 11:45:20 -0800 | [diff] [blame] | 908 | TimePickerDialog tpd = (TimePickerDialog) fm.findFragmentByTag(FRAG_TAG_TIME_PICKER); |
| 909 | if (tpd != null) { |
| 910 | View v; |
| 911 | mTimeSelectedWasStartTime = timeSelectedWasStartTime; |
| 912 | if (timeSelectedWasStartTime) { |
| 913 | v = mStartTimeButton; |
| 914 | } else { |
| 915 | v = mEndTimeButton; |
| 916 | } |
| 917 | tpd.setOnTimeSetListener(new TimeListener(v)); |
| 918 | } |
James Kung | 56f42bf | 2013-03-29 14:59:29 -0700 | [diff] [blame] | 919 | mDatePickerDialog = (DatePickerDialog) fm.findFragmentByTag(FRAG_TAG_DATE_PICKER); |
| 920 | if (mDatePickerDialog != null) { |
| 921 | View v; |
| 922 | mDateSelectedWasStartDate = dateSelectedWasStartDate; |
| 923 | if (dateSelectedWasStartDate) { |
| 924 | v = mStartDateButton; |
| 925 | } else { |
| 926 | v = mEndDateButton; |
| 927 | } |
| 928 | mDatePickerDialog.setOnDateSetListener(new DateListener(v)); |
| 929 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 930 | } |
| 931 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 932 | |
| 933 | /** |
| 934 | * Loads an integer array asset into a list. |
| 935 | */ |
| 936 | private static ArrayList<Integer> loadIntegerArray(Resources r, int resNum) { |
| 937 | int[] vals = r.getIntArray(resNum); |
| 938 | int size = vals.length; |
| 939 | ArrayList<Integer> list = new ArrayList<Integer>(size); |
| 940 | |
| 941 | for (int i = 0; i < size; i++) { |
| 942 | list.add(vals[i]); |
| 943 | } |
| 944 | |
| 945 | return list; |
| 946 | } |
| 947 | |
| 948 | /** |
| 949 | * Loads a String array asset into a list. |
| 950 | */ |
| 951 | private static ArrayList<String> loadStringArray(Resources r, int resNum) { |
| 952 | String[] labels = r.getStringArray(resNum); |
| 953 | ArrayList<String> list = new ArrayList<String>(Arrays.asList(labels)); |
| 954 | return list; |
| 955 | } |
| 956 | |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 957 | private void prepareAvailability() { |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 958 | Resources r = mActivity.getResources(); |
| 959 | |
| 960 | mAvailabilityValues = loadIntegerArray(r, R.array.availability_values); |
| 961 | mAvailabilityLabels = loadStringArray(r, R.array.availability); |
Sam Blitzstein | 7cdfb4d | 2013-02-22 15:30:27 -0800 | [diff] [blame] | 962 | // Copy the unadulterated availability labels for all-day toggling. |
| 963 | mOriginalAvailabilityLabels = new ArrayList<String>(); |
| 964 | mOriginalAvailabilityLabels.addAll(mAvailabilityLabels); |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 965 | |
| 966 | if (mModel.mCalendarAllowedAvailability != null) { |
| 967 | EventViewUtils.reduceMethodList(mAvailabilityValues, mAvailabilityLabels, |
| 968 | mModel.mCalendarAllowedAvailability); |
| 969 | } |
| 970 | |
Sam Blitzstein | 7cdfb4d | 2013-02-22 15:30:27 -0800 | [diff] [blame] | 971 | mAvailabilityAdapter = new ArrayAdapter<String>(mActivity, |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 972 | android.R.layout.simple_spinner_item, mAvailabilityLabels); |
Sam Blitzstein | 7cdfb4d | 2013-02-22 15:30:27 -0800 | [diff] [blame] | 973 | mAvailabilityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
| 974 | mAvailabilitySpinner.setAdapter(mAvailabilityAdapter); |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 975 | } |
| 976 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 977 | /** |
| 978 | * Prepares the reminder UI elements. |
| 979 | * <p> |
| 980 | * (Re-)loads the minutes / methods lists from the XML assets, adds/removes items as |
| 981 | * needed for the current set of reminders and calendar properties, and then creates UI |
| 982 | * elements. |
| 983 | */ |
| 984 | private void prepareReminders() { |
| 985 | CalendarEventModel model = mModel; |
| 986 | Resources r = mActivity.getResources(); |
| 987 | |
| 988 | // Load the labels and corresponding numeric values for the minutes and methods lists |
| 989 | // from the assets. If we're switching calendars, we need to clear and re-populate the |
| 990 | // lists (which may have elements added and removed based on calendar properties). This |
| 991 | // is mostly relevant for "methods", since we shouldn't have any "minutes" values in a |
| 992 | // new event that aren't in the default set. |
| 993 | mReminderMinuteValues = loadIntegerArray(r, R.array.reminder_minutes_values); |
| 994 | mReminderMinuteLabels = loadStringArray(r, R.array.reminder_minutes_labels); |
| 995 | mReminderMethodValues = loadIntegerArray(r, R.array.reminder_methods_values); |
| 996 | mReminderMethodLabels = loadStringArray(r, R.array.reminder_methods_labels); |
| 997 | |
| 998 | // Remove any reminder methods that aren't allowed for this calendar. If this is |
| 999 | // a new event, mCalendarAllowedReminders may not be set the first time we're called. |
| 1000 | if (mModel.mCalendarAllowedReminders != null) { |
| 1001 | EventViewUtils.reduceMethodList(mReminderMethodValues, mReminderMethodLabels, |
| 1002 | mModel.mCalendarAllowedReminders); |
| 1003 | } |
| 1004 | |
| 1005 | int numReminders = 0; |
| 1006 | if (model.mHasAlarm) { |
| 1007 | ArrayList<ReminderEntry> reminders = model.mReminders; |
| 1008 | numReminders = reminders.size(); |
| 1009 | // Insert any minute values that aren't represented in the minutes list. |
| 1010 | for (ReminderEntry re : reminders) { |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 1011 | if (mReminderMethodValues.contains(re.getMethod())) { |
| 1012 | EventViewUtils.addMinutesToList(mActivity, mReminderMinuteValues, |
| 1013 | mReminderMinuteLabels, re.getMinutes()); |
| 1014 | } |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1015 | } |
| 1016 | |
| 1017 | // Create a UI element for each reminder. We display all of the reminders we get |
| 1018 | // from the provider, even if the count exceeds the calendar maximum. (Also, for |
| 1019 | // a new event, we won't have a maxReminders value available.) |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 1020 | mUnsupportedReminders.clear(); |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1021 | for (ReminderEntry re : reminders) { |
RoboErik | cabc41a | 2011-09-08 13:34:32 -0700 | [diff] [blame] | 1022 | if (mReminderMethodValues.contains(re.getMethod()) |
| 1023 | || re.getMethod() == Reminders.METHOD_DEFAULT) { |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 1024 | EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderItems, |
| 1025 | mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues, |
RoboErik | 8b5743c | 2011-09-27 16:07:09 -0700 | [diff] [blame] | 1026 | mReminderMethodLabels, re, Integer.MAX_VALUE, null); |
RoboErik | e35a032 | 2011-09-01 16:21:49 -0700 | [diff] [blame] | 1027 | } else { |
| 1028 | // TODO figure out a way to display unsupported reminders |
| 1029 | mUnsupportedReminders.add(re); |
| 1030 | } |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | updateRemindersVisibility(numReminders); |
Sara Ting | 06f3d6d | 2012-03-23 17:19:22 -0700 | [diff] [blame] | 1035 | EventViewUtils.updateAddReminderButton(mView, mReminderItems, mModel.mCalendarMaxReminders); |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1036 | } |
| 1037 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1038 | /** |
| 1039 | * Fill in the view with the contents of the given event model. This allows |
| 1040 | * an edit view to be initialized before the event has been loaded. Passing |
| 1041 | * in null for the model will display a loading screen. A non-null model |
| 1042 | * will fill in the view's fields with the data contained in the model. |
| 1043 | * |
| 1044 | * @param model The event model to pull the data from |
| 1045 | */ |
| 1046 | public void setModel(CalendarEventModel model) { |
| 1047 | mModel = model; |
Dmitri Plotnikov | ee21220 | 2010-08-27 17:58:19 -0700 | [diff] [blame] | 1048 | |
| 1049 | // Need to close the autocomplete adapter to prevent leaking cursors. |
Mindy Pereira | 18cabd2 | 2011-06-09 18:31:23 -0700 | [diff] [blame] | 1050 | if (mAddressAdapter != null && mAddressAdapter instanceof EmailAddressAdapter) { |
| 1051 | ((EmailAddressAdapter)mAddressAdapter).close(); |
Dmitri Plotnikov | ee21220 | 2010-08-27 17:58:19 -0700 | [diff] [blame] | 1052 | mAddressAdapter = null; |
| 1053 | } |
| 1054 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1055 | if (model == null) { |
| 1056 | // Display loading screen |
| 1057 | mLoadingMessage.setVisibility(View.VISIBLE); |
| 1058 | mScrollView.setVisibility(View.GONE); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1059 | return; |
| 1060 | } |
| 1061 | |
Michael Chan | 18a3c2e | 2010-10-13 09:52:28 -0700 | [diff] [blame] | 1062 | boolean canRespond = EditEventHelper.canRespond(model); |
| 1063 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1064 | long begin = model.mStart; |
| 1065 | long end = model.mEnd; |
Mason Tang | 86cdba6 | 2010-08-17 11:19:32 -0700 | [diff] [blame] | 1066 | mTimezone = model.mTimezone; // this will be UTC for all day events |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1067 | |
| 1068 | // Set up the starting times |
| 1069 | if (begin > 0) { |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 1070 | mStartTime.timezone = mTimezone; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1071 | mStartTime.set(begin); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1072 | mStartTime.normalize(true); |
| 1073 | } |
| 1074 | if (end > 0) { |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 1075 | mEndTime.timezone = mTimezone; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1076 | mEndTime.set(end); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1077 | mEndTime.normalize(true); |
| 1078 | } |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 1079 | |
| 1080 | mRrule = model.mRrule; |
| 1081 | if (!TextUtils.isEmpty(mRrule)) { |
| 1082 | mEventRecurrence.parse(mRrule); |
| 1083 | } |
| 1084 | |
| 1085 | if (mEventRecurrence.startDate == null) { |
| 1086 | mEventRecurrence.startDate = mStartTime; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1087 | } |
| 1088 | |
| 1089 | // If the user is allowed to change the attendees set up the view and |
| 1090 | // validator |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1091 | if (!model.mHasAttendeeData) { |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 1092 | mAttendeesGroup.setVisibility(View.GONE); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1093 | } |
| 1094 | |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1095 | mAllDayCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1096 | @Override |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1097 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1098 | setAllDayViewsVisibility(isChecked); |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1099 | } |
| 1100 | }); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1101 | |
RoboErik | e8e0fc6 | 2011-09-13 09:48:18 -0700 | [diff] [blame] | 1102 | boolean prevAllDay = mAllDayCheckBox.isChecked(); |
Michael Chan | 8b1119b | 2012-01-06 16:04:55 -0800 | [diff] [blame] | 1103 | mAllDay = false; // default to false. Let setAllDayViewsVisibility update it as needed |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1104 | if (model.mAllDay) { |
| 1105 | mAllDayCheckBox.setChecked(true); |
Mason Tang | 86cdba6 | 2010-08-17 11:19:32 -0700 | [diff] [blame] | 1106 | // put things back in local time for all day events |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 1107 | mTimezone = Utils.getTimeZone(mActivity, null); |
Mason Tang | 86cdba6 | 2010-08-17 11:19:32 -0700 | [diff] [blame] | 1108 | mStartTime.timezone = mTimezone; |
Mason Tang | 86cdba6 | 2010-08-17 11:19:32 -0700 | [diff] [blame] | 1109 | mEndTime.timezone = mTimezone; |
| 1110 | mEndTime.normalize(true); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1111 | } else { |
| 1112 | mAllDayCheckBox.setChecked(false); |
| 1113 | } |
RoboErik | e8e0fc6 | 2011-09-13 09:48:18 -0700 | [diff] [blame] | 1114 | // On a rotation we need to update the views but onCheckedChanged |
| 1115 | // doesn't get called |
| 1116 | if (prevAllDay == mAllDayCheckBox.isChecked()) { |
| 1117 | setAllDayViewsVisibility(prevAllDay); |
| 1118 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1119 | |
Michael Chan | 559cb86 | 2012-05-12 07:42:13 -0700 | [diff] [blame] | 1120 | populateTimezone(mStartTime.normalize(true)); |
Mason Tang | 86cdba6 | 2010-08-17 11:19:32 -0700 | [diff] [blame] | 1121 | |
Daisuke Miyakawa | 4b441bd | 2010-09-16 14:55:36 -0700 | [diff] [blame] | 1122 | SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity); |
Michael Chan | 9d8a376 | 2011-03-29 15:40:24 -0700 | [diff] [blame] | 1123 | String defaultReminderString = prefs.getString( |
| 1124 | GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING); |
| 1125 | mDefaultReminderMinutes = Integer.parseInt(defaultReminderString); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1126 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1127 | prepareReminders(); |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 1128 | prepareAvailability(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1129 | |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 1130 | View reminderAddButton = mView.findViewById(R.id.reminder_add); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1131 | View.OnClickListener addReminderOnClickListener = new View.OnClickListener() { |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1132 | @Override |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1133 | public void onClick(View v) { |
| 1134 | addReminder(); |
| 1135 | } |
| 1136 | }; |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1137 | reminderAddButton.setOnClickListener(addReminderOnClickListener); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1138 | |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 1139 | if (!mIsMultipane) { |
| 1140 | mView.findViewById(R.id.is_all_day_label).setOnClickListener( |
| 1141 | new View.OnClickListener() { |
| 1142 | @Override |
| 1143 | public void onClick(View v) { |
| 1144 | mAllDayCheckBox.setChecked(!mAllDayCheckBox.isChecked()); |
| 1145 | } |
| 1146 | }); |
| 1147 | } |
| 1148 | |
Michael Chan | b7c1fcc | 2011-10-03 15:37:18 -0700 | [diff] [blame] | 1149 | if (model.mTitle != null) { |
| 1150 | mTitleTextView.setTextKeepState(model.mTitle); |
| 1151 | } |
| 1152 | |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1153 | if (model.mIsOrganizer || TextUtils.isEmpty(model.mOrganizer) |
| 1154 | || model.mOrganizer.endsWith(GOOGLE_SECONDARY_CALENDAR)) { |
| 1155 | mView.findViewById(R.id.organizer_label).setVisibility(View.GONE); |
| 1156 | mView.findViewById(R.id.organizer).setVisibility(View.GONE); |
Isaac Katzenelson | 2e46cff | 2011-06-09 18:02:44 -0700 | [diff] [blame] | 1157 | mOrganizerGroup.setVisibility(View.GONE); |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1158 | } else { |
| 1159 | ((TextView) mView.findViewById(R.id.organizer)).setText(model.mOrganizerDisplayName); |
| 1160 | } |
Michael Chan | b7c1fcc | 2011-10-03 15:37:18 -0700 | [diff] [blame] | 1161 | |
| 1162 | if (model.mLocation != null) { |
| 1163 | mLocationTextView.setTextKeepState(model.mLocation); |
| 1164 | } |
| 1165 | |
| 1166 | if (model.mDescription != null) { |
| 1167 | mDescriptionTextView.setTextKeepState(model.mDescription); |
| 1168 | } |
| 1169 | |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 1170 | int availIndex = mAvailabilityValues.indexOf(model.mAvailability); |
| 1171 | if (availIndex != -1) { |
| 1172 | mAvailabilitySpinner.setSelection(availIndex); |
| 1173 | } |
Michael Chan | ced0eb6 | 2011-05-31 18:12:52 -0700 | [diff] [blame] | 1174 | mAccessLevelSpinner.setSelection(model.mAccessLevel); |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 1175 | |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1176 | View responseLabel = mView.findViewById(R.id.response_label); |
Michael Chan | 18a3c2e | 2010-10-13 09:52:28 -0700 | [diff] [blame] | 1177 | if (canRespond) { |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 1178 | int buttonToCheck = EventInfoFragment |
| 1179 | .findButtonIdForResponse(model.mSelfAttendeeStatus); |
| 1180 | mResponseRadioGroup.check(buttonToCheck); // -1 clear all radio buttons |
| 1181 | mResponseRadioGroup.setVisibility(View.VISIBLE); |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1182 | responseLabel.setVisibility(View.VISIBLE); |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1183 | } else { |
| 1184 | responseLabel.setVisibility(View.GONE); |
Michael Chan | f92f46b | 2010-10-27 18:59:05 -0700 | [diff] [blame] | 1185 | mResponseRadioGroup.setVisibility(View.GONE); |
RoboErik | 13ea4e3 | 2011-08-08 10:40:38 -0700 | [diff] [blame] | 1186 | mResponseGroup.setVisibility(View.GONE); |
Michael Chan | 352e1a2 | 2010-09-28 05:15:08 -0700 | [diff] [blame] | 1187 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1188 | |
| 1189 | if (model.mUri != null) { |
| 1190 | // This is an existing event so hide the calendar spinner |
| 1191 | // since we can't change the calendar. |
Michael Chan | 9d5f351 | 2010-11-05 16:23:57 -0700 | [diff] [blame] | 1192 | View calendarGroup = mView.findViewById(R.id.calendar_selector_group); |
| 1193 | calendarGroup.setVisibility(View.GONE); |
| 1194 | TextView tv = (TextView) mView.findViewById(R.id.calendar_textview); |
| 1195 | tv.setText(model.mCalendarDisplayName); |
RoboErik | 0d865f3 | 2011-08-09 10:17:25 -0700 | [diff] [blame] | 1196 | tv = (TextView) mView.findViewById(R.id.calendar_textview_secondary); |
| 1197 | if (tv != null) { |
| 1198 | tv.setText(model.mOwnerAccount); |
| 1199 | } |
Michael Chan | 9d5f351 | 2010-11-05 16:23:57 -0700 | [diff] [blame] | 1200 | } else { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1201 | View calendarGroup = mView.findViewById(R.id.calendar_group); |
| 1202 | calendarGroup.setVisibility(View.GONE); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1203 | } |
James Kung | f56b149 | 2013-03-07 15:10:13 -0800 | [diff] [blame] | 1204 | if (model.isEventColorInitialized()) { |
| 1205 | updateHeadlineColor(model, model.getEventColor()); |
| 1206 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1207 | |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 1208 | populateWhen(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1209 | populateRepeats(); |
Erik | d845fbe | 2010-08-12 11:20:01 -0700 | [diff] [blame] | 1210 | updateAttendees(model.mAttendeesList); |
Michael Chan | ddbf808 | 2010-10-26 19:09:32 -0700 | [diff] [blame] | 1211 | |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1212 | updateView(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1213 | mScrollView.setVisibility(View.VISIBLE); |
| 1214 | mLoadingMessage.setVisibility(View.GONE); |
Erik | 259b8f9 | 2011-01-12 14:01:12 -0800 | [diff] [blame] | 1215 | sendAccessibilityEvent(); |
| 1216 | } |
| 1217 | |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1218 | public void updateHeadlineColor(CalendarEventModel model, int displayColor) { |
| 1219 | if (model.mUri != null) { |
| 1220 | if (mIsMultipane) { |
| 1221 | mView.findViewById(R.id.calendar_textview_with_colorpicker) |
| 1222 | .setBackgroundColor(displayColor); |
| 1223 | } else { |
| 1224 | mView.findViewById(R.id.calendar_group).setBackgroundColor(displayColor); |
| 1225 | } |
| 1226 | } else { |
James Kung | 317f661 | 2013-03-05 16:29:14 -0800 | [diff] [blame] | 1227 | setSpinnerBackgroundColor(displayColor); |
| 1228 | } |
| 1229 | } |
| 1230 | |
| 1231 | private void setSpinnerBackgroundColor(int displayColor) { |
| 1232 | if (mIsMultipane) { |
| 1233 | mCalendarSelectorWrapper.setBackgroundColor(displayColor); |
| 1234 | } else { |
| 1235 | mCalendarSelectorGroup.setBackgroundColor(displayColor); |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1236 | } |
| 1237 | } |
| 1238 | |
Erik | 259b8f9 | 2011-01-12 14:01:12 -0800 | [diff] [blame] | 1239 | private void sendAccessibilityEvent() { |
Andy McFadden | ef31a98 | 2011-06-09 07:38:56 -0700 | [diff] [blame] | 1240 | AccessibilityManager am = |
| 1241 | (AccessibilityManager) mActivity.getSystemService(Service.ACCESSIBILITY_SERVICE); |
Erik | 259b8f9 | 2011-01-12 14:01:12 -0800 | [diff] [blame] | 1242 | if (!am.isEnabled() || mModel == null) { |
| 1243 | return; |
| 1244 | } |
| 1245 | StringBuilder b = new StringBuilder(); |
| 1246 | addFieldsRecursive(b, mView); |
| 1247 | CharSequence msg = b.toString(); |
| 1248 | |
| 1249 | AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED); |
| 1250 | event.setClassName(getClass().getName()); |
| 1251 | event.setPackageName(mActivity.getPackageName()); |
| 1252 | event.getText().add(msg); |
| 1253 | event.setAddedCount(msg.length()); |
| 1254 | |
| 1255 | am.sendAccessibilityEvent(event); |
| 1256 | } |
| 1257 | |
| 1258 | private void addFieldsRecursive(StringBuilder b, View v) { |
| 1259 | if (v == null || v.getVisibility() != View.VISIBLE) { |
| 1260 | return; |
| 1261 | } |
| 1262 | if (v instanceof TextView) { |
| 1263 | CharSequence tv = ((TextView) v).getText(); |
| 1264 | if (!TextUtils.isEmpty(tv.toString().trim())) { |
| 1265 | b.append(tv + PERIOD_SPACE); |
| 1266 | } |
| 1267 | } else if (v instanceof RadioGroup) { |
| 1268 | RadioGroup rg = (RadioGroup) v; |
| 1269 | int id = rg.getCheckedRadioButtonId(); |
| 1270 | if (id != View.NO_ID) { |
| 1271 | b.append(((RadioButton) (v.findViewById(id))).getText() + PERIOD_SPACE); |
| 1272 | } |
| 1273 | } else if (v instanceof Spinner) { |
| 1274 | Spinner s = (Spinner) v; |
| 1275 | if (s.getSelectedItem() instanceof String) { |
| 1276 | String str = ((String) (s.getSelectedItem())).trim(); |
| 1277 | if (!TextUtils.isEmpty(str)) { |
| 1278 | b.append(str + PERIOD_SPACE); |
| 1279 | } |
| 1280 | } |
| 1281 | } else if (v instanceof ViewGroup) { |
| 1282 | ViewGroup vg = (ViewGroup) v; |
| 1283 | int children = vg.getChildCount(); |
| 1284 | for (int i = 0; i < children; i++) { |
| 1285 | addFieldsRecursive(b, vg.getChildAt(i)); |
| 1286 | } |
| 1287 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1288 | } |
| 1289 | |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1290 | /** |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1291 | * Creates a single line string for the time/duration |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1292 | */ |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1293 | protected void setWhenString() { |
| 1294 | String when; |
| 1295 | int flags = DateUtils.FORMAT_SHOW_DATE; |
RoboErik | a99feb9 | 2011-02-09 18:03:24 -0800 | [diff] [blame] | 1296 | String tz = mTimezone; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1297 | if (mModel.mAllDay) { |
RoboErik | a99feb9 | 2011-02-09 18:03:24 -0800 | [diff] [blame] | 1298 | flags |= DateUtils.FORMAT_SHOW_WEEKDAY; |
| 1299 | tz = Time.TIMEZONE_UTC; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1300 | } else { |
| 1301 | flags |= DateUtils.FORMAT_SHOW_TIME; |
| 1302 | if (DateFormat.is24HourFormat(mActivity)) { |
| 1303 | flags |= DateUtils.FORMAT_24HOUR; |
| 1304 | } |
| 1305 | } |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1306 | long startMillis = mStartTime.normalize(true); |
| 1307 | long endMillis = mEndTime.normalize(true); |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 1308 | mSB.setLength(0); |
RoboErik | a99feb9 | 2011-02-09 18:03:24 -0800 | [diff] [blame] | 1309 | when = DateUtils |
| 1310 | .formatDateRange(mActivity, mF, startMillis, endMillis, flags, tz).toString(); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1311 | mWhenView.setText(when); |
Michael Chan | 24ee336 | 2010-11-01 19:06:01 -0700 | [diff] [blame] | 1312 | } |
| 1313 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1314 | /** |
| 1315 | * Configures the Calendars spinner. This is only done for new events, because only new |
| 1316 | * events allow you to select a calendar while editing an event. |
| 1317 | * <p> |
| 1318 | * We tuck a reference to a Cursor with calendar database data into the spinner, so that |
| 1319 | * we can easily extract calendar-specific values when the value changes (the spinner's |
| 1320 | * onItemSelected callback is configured). |
| 1321 | */ |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1322 | public void setCalendarsCursor(Cursor cursor, boolean userVisible, long selectedCalendarId) { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1323 | // If there are no syncable calendars, then we cannot allow |
| 1324 | // creating a new event. |
| 1325 | mCalendarsCursor = cursor; |
| 1326 | if (cursor == null || cursor.getCount() == 0) { |
| 1327 | // Cancel the "loading calendars" dialog if it exists |
| 1328 | if (mSaveAfterQueryComplete) { |
| 1329 | mLoadingCalendarsDialog.cancel(); |
| 1330 | } |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 1331 | if (!userVisible) { |
| 1332 | return; |
| 1333 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1334 | // Create an error message for the user that, when clicked, |
| 1335 | // will exit this activity without saving the event. |
| 1336 | AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); |
Erik | f6b6fb3 | 2011-01-18 11:54:50 -0800 | [diff] [blame] | 1337 | builder.setTitle(R.string.no_syncable_calendars).setIconAttribute( |
| 1338 | android.R.attr.alertDialogIcon).setMessage(R.string.no_calendars_found) |
Daisuke Miyakawa | 464f350 | 2010-09-21 22:12:55 -0700 | [diff] [blame] | 1339 | .setPositiveButton(R.string.add_account, this) |
Erik | f6b6fb3 | 2011-01-18 11:54:50 -0800 | [diff] [blame] | 1340 | .setNegativeButton(android.R.string.no, this).setOnCancelListener(this); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1341 | mNoCalendarsDialog = builder.show(); |
| 1342 | return; |
| 1343 | } |
| 1344 | |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1345 | int selection; |
| 1346 | if (selectedCalendarId != -1) { |
| 1347 | selection = findSelectedCalendarPosition(cursor, selectedCalendarId); |
| 1348 | } else { |
| 1349 | selection = findDefaultCalendarPosition(cursor); |
| 1350 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1351 | |
| 1352 | // populate the calendars spinner |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1353 | CalendarsAdapter adapter = new CalendarsAdapter(mActivity, |
| 1354 | R.layout.calendars_spinner_item, cursor); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1355 | mCalendarsSpinner.setAdapter(adapter); |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1356 | mCalendarsSpinner.setSelection(selection); |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1357 | mCalendarsSpinner.setOnItemSelectedListener(this); |
| 1358 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1359 | if (mSaveAfterQueryComplete) { |
| 1360 | mLoadingCalendarsDialog.cancel(); |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 1361 | if (prepareForSave() && fillModelFromUI()) { |
| 1362 | int exit = userVisible ? Utils.DONE_EXIT : 0; |
| 1363 | mDone.setDoneCode(Utils.DONE_SAVE | exit); |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 1364 | mDone.run(); |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 1365 | } else if (userVisible) { |
| 1366 | mDone.setDoneCode(Utils.DONE_EXIT); |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 1367 | mDone.run(); |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 1368 | } else if (Log.isLoggable(TAG, Log.DEBUG)) { |
| 1369 | Log.d(TAG, "SetCalendarsCursor:Save failed and unable to exit view"); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1370 | } |
| 1371 | return; |
| 1372 | } |
| 1373 | } |
| 1374 | |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1375 | /** |
| 1376 | * Updates the view based on {@link #mModification} and {@link #mModel} |
| 1377 | */ |
| 1378 | public void updateView() { |
| 1379 | if (mModel == null) { |
| 1380 | return; |
| 1381 | } |
| 1382 | if (EditEventHelper.canModifyEvent(mModel)) { |
| 1383 | setViewStates(mModification); |
| 1384 | } else { |
| 1385 | setViewStates(Utils.MODIFY_UNINITIALIZED); |
| 1386 | } |
| 1387 | } |
| 1388 | |
| 1389 | private void setViewStates(int mode) { |
| 1390 | // Extra canModify check just in case |
| 1391 | if (mode == Utils.MODIFY_UNINITIALIZED || !EditEventHelper.canModifyEvent(mModel)) { |
| 1392 | setWhenString(); |
| 1393 | |
| 1394 | for (View v : mViewOnlyList) { |
| 1395 | v.setVisibility(View.VISIBLE); |
| 1396 | } |
| 1397 | for (View v : mEditOnlyList) { |
| 1398 | v.setVisibility(View.GONE); |
| 1399 | } |
| 1400 | for (View v : mEditViewList) { |
| 1401 | v.setEnabled(false); |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 1402 | v.setBackgroundDrawable(null); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1403 | } |
| 1404 | mCalendarSelectorGroup.setVisibility(View.GONE); |
| 1405 | mCalendarStaticGroup.setVisibility(View.VISIBLE); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 1406 | mRruleButton.setEnabled(false); |
| 1407 | mRruleButton.setBackgroundDrawable(null); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1408 | if (EditEventHelper.canAddReminders(mModel)) { |
| 1409 | mRemindersGroup.setVisibility(View.VISIBLE); |
| 1410 | } else { |
| 1411 | mRemindersGroup.setVisibility(View.GONE); |
| 1412 | } |
Erik | a7694ee | 2010-12-07 15:46:18 -0800 | [diff] [blame] | 1413 | if (TextUtils.isEmpty(mLocationTextView.getText())) { |
| 1414 | mLocationGroup.setVisibility(View.GONE); |
| 1415 | } |
| 1416 | if (TextUtils.isEmpty(mDescriptionTextView.getText())) { |
| 1417 | mDescriptionGroup.setVisibility(View.GONE); |
| 1418 | } |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1419 | } else { |
| 1420 | for (View v : mViewOnlyList) { |
| 1421 | v.setVisibility(View.GONE); |
| 1422 | } |
| 1423 | for (View v : mEditOnlyList) { |
| 1424 | v.setVisibility(View.VISIBLE); |
| 1425 | } |
| 1426 | for (View v : mEditViewList) { |
| 1427 | v.setEnabled(true); |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 1428 | if (v.getTag() != null) { |
| 1429 | v.setBackgroundDrawable((Drawable) v.getTag()); |
RoboErik | 0d865f3 | 2011-08-09 10:17:25 -0700 | [diff] [blame] | 1430 | v.setPadding(mOriginalPadding[0], mOriginalPadding[1], mOriginalPadding[2], |
| 1431 | mOriginalPadding[3]); |
Erik | efa480c | 2011-01-13 11:57:25 -0800 | [diff] [blame] | 1432 | } |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1433 | } |
| 1434 | if (mModel.mUri == null) { |
| 1435 | mCalendarSelectorGroup.setVisibility(View.VISIBLE); |
| 1436 | mCalendarStaticGroup.setVisibility(View.GONE); |
| 1437 | } else { |
| 1438 | mCalendarSelectorGroup.setVisibility(View.GONE); |
| 1439 | mCalendarStaticGroup.setVisibility(View.VISIBLE); |
| 1440 | } |
RoboErik | 28dab65 | 2011-07-21 15:08:39 -0700 | [diff] [blame] | 1441 | if (mModel.mOriginalSyncId == null) { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 1442 | mRruleButton.setEnabled(true); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1443 | } else { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 1444 | mRruleButton.setEnabled(false); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1445 | } |
| 1446 | mRemindersGroup.setVisibility(View.VISIBLE); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1447 | |
Erik | a7694ee | 2010-12-07 15:46:18 -0800 | [diff] [blame] | 1448 | mLocationGroup.setVisibility(View.VISIBLE); |
| 1449 | mDescriptionGroup.setVisibility(View.VISIBLE); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1450 | } |
Mindy Pereira | 521e7b8 | 2012-05-09 13:04:23 -0700 | [diff] [blame] | 1451 | setAllDayViewsVisibility(mAllDayCheckBox.isChecked()); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1452 | } |
| 1453 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1454 | public void setModification(int modifyWhich) { |
| 1455 | mModification = modifyWhich; |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1456 | updateView(); |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 1457 | updateHomeTime(); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1458 | } |
| 1459 | |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1460 | private int findSelectedCalendarPosition(Cursor calendarsCursor, long calendarId) { |
| 1461 | if (calendarsCursor.getCount() <= 0) { |
| 1462 | return -1; |
| 1463 | } |
| 1464 | int calendarIdColumn = calendarsCursor.getColumnIndexOrThrow(Calendars._ID); |
| 1465 | int position = 0; |
| 1466 | calendarsCursor.moveToPosition(-1); |
| 1467 | while (calendarsCursor.moveToNext()) { |
| 1468 | if (calendarsCursor.getLong(calendarIdColumn) == calendarId) { |
| 1469 | return position; |
| 1470 | } |
| 1471 | position++; |
| 1472 | } |
| 1473 | return 0; |
| 1474 | } |
| 1475 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1476 | // Find the calendar position in the cursor that matches calendar in |
| 1477 | // preference |
| 1478 | private int findDefaultCalendarPosition(Cursor calendarsCursor) { |
| 1479 | if (calendarsCursor.getCount() <= 0) { |
| 1480 | return -1; |
| 1481 | } |
| 1482 | |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 1483 | String defaultCalendar = Utils.getSharedPreference( |
Michael Chan | e98dca7 | 2012-06-16 08:22:47 -0700 | [diff] [blame] | 1484 | mActivity, GeneralPreferences.KEY_DEFAULT_CALENDAR, (String) null); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1485 | |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1486 | int calendarsOwnerIndex = calendarsCursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT); |
Sara Ting | 8286d2f | 2012-09-13 12:17:01 -0700 | [diff] [blame] | 1487 | int accountNameIndex = calendarsCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME); |
Sara Ting | 844cac0 | 2012-09-18 11:02:13 -0700 | [diff] [blame] | 1488 | int accountTypeIndex = calendarsCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1489 | int position = 0; |
| 1490 | calendarsCursor.moveToPosition(-1); |
| 1491 | while (calendarsCursor.moveToNext()) { |
James Kung | 09fbd8e | 2012-11-12 11:19:46 -0800 | [diff] [blame] | 1492 | String calendarOwner = calendarsCursor.getString(calendarsOwnerIndex); |
Sara Ting | 8286d2f | 2012-09-13 12:17:01 -0700 | [diff] [blame] | 1493 | if (defaultCalendar == null) { |
| 1494 | // There is no stored default upon the first time running. Use a primary |
| 1495 | // calendar in this case. |
| 1496 | if (calendarOwner != null && |
Sara Ting | 844cac0 | 2012-09-18 11:02:13 -0700 | [diff] [blame] | 1497 | calendarOwner.equals(calendarsCursor.getString(accountNameIndex)) && |
| 1498 | !CalendarContract.ACCOUNT_TYPE_LOCAL.equals( |
| 1499 | calendarsCursor.getString(accountTypeIndex))) { |
Sara Ting | 8286d2f | 2012-09-13 12:17:01 -0700 | [diff] [blame] | 1500 | return position; |
| 1501 | } |
| 1502 | } else if (defaultCalendar.equals(calendarOwner)) { |
| 1503 | // Found the default calendar. |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1504 | return position; |
| 1505 | } |
| 1506 | position++; |
| 1507 | } |
| 1508 | return 0; |
| 1509 | } |
| 1510 | |
Michael Chan | ddbf808 | 2010-10-26 19:09:32 -0700 | [diff] [blame] | 1511 | private void updateAttendees(HashMap<String, Attendee> attendeesList) { |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 1512 | if (attendeesList == null || attendeesList.isEmpty()) { |
| 1513 | return; |
| 1514 | } |
| 1515 | mAttendeesList.setText(null); |
| 1516 | for (Attendee attendee : attendeesList.values()) { |
James Kung | bb90a7d | 2013-04-04 15:29:45 -0700 | [diff] [blame] | 1517 | |
| 1518 | // TODO: Please remove separator when Calendar uses the chips MR2 project |
| 1519 | |
| 1520 | // Adding a comma separator between email addresses to prevent a chips MR1.1 bug |
| 1521 | // in which email addresses are concatenated together with no separator. |
| 1522 | mAttendeesList.append(attendee.mEmail + ", "); |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 1523 | } |
Erik | d845fbe | 2010-08-12 11:20:01 -0700 | [diff] [blame] | 1524 | } |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 1525 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1526 | private void updateRemindersVisibility(int numReminders) { |
| 1527 | if (numReminders == 0) { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1528 | mRemindersContainer.setVisibility(View.GONE); |
| 1529 | } else { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1530 | mRemindersContainer.setVisibility(View.VISIBLE); |
| 1531 | } |
| 1532 | } |
| 1533 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1534 | /** |
| 1535 | * Add a new reminder when the user hits the "add reminder" button. We use the default |
| 1536 | * reminder time and method. |
| 1537 | */ |
Michael Chan | ddbf808 | 2010-10-26 19:09:32 -0700 | [diff] [blame] | 1538 | private void addReminder() { |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1539 | // TODO: when adding a new reminder, make it different from the |
| 1540 | // last one in the list (if any). |
Michael Chan | 9d8a376 | 2011-03-29 15:40:24 -0700 | [diff] [blame] | 1541 | if (mDefaultReminderMinutes == GeneralPreferences.NO_REMINDER) { |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 1542 | EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderItems, |
Andy McFadden | fea9af5 | 2011-05-13 15:40:10 -0700 | [diff] [blame] | 1543 | mReminderMinuteValues, mReminderMinuteLabels, |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1544 | mReminderMethodValues, mReminderMethodLabels, |
| 1545 | ReminderEntry.valueOf(GeneralPreferences.REMINDER_DEFAULT_TIME), |
RoboErik | 8b5743c | 2011-09-27 16:07:09 -0700 | [diff] [blame] | 1546 | mModel.mCalendarMaxReminders, null); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1547 | } else { |
Erik | 79f2281 | 2010-06-23 16:55:38 -0700 | [diff] [blame] | 1548 | EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderItems, |
Andy McFadden | fea9af5 | 2011-05-13 15:40:10 -0700 | [diff] [blame] | 1549 | mReminderMinuteValues, mReminderMinuteLabels, |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1550 | mReminderMethodValues, mReminderMethodLabels, |
| 1551 | ReminderEntry.valueOf(mDefaultReminderMinutes), |
RoboErik | 8b5743c | 2011-09-27 16:07:09 -0700 | [diff] [blame] | 1552 | mModel.mCalendarMaxReminders, null); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1553 | } |
| 1554 | updateRemindersVisibility(mReminderItems.size()); |
Sara Ting | 06f3d6d | 2012-03-23 17:19:22 -0700 | [diff] [blame] | 1555 | EventViewUtils.updateAddReminderButton(mView, mReminderItems, mModel.mCalendarMaxReminders); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1556 | } |
| 1557 | |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1558 | // From com.google.android.gm.ComposeActivity |
RoboErik | 6a7003d | 2011-08-04 16:23:20 -0700 | [diff] [blame] | 1559 | private MultiAutoCompleteTextView initMultiAutoCompleteTextView(RecipientEditTextView list) { |
Mindy Pereira | 18cabd2 | 2011-06-09 18:31:23 -0700 | [diff] [blame] | 1560 | if (ChipsUtil.supportsChipsUi()) { |
| 1561 | mAddressAdapter = new RecipientAdapter(mActivity); |
| 1562 | list.setAdapter((BaseRecipientAdapter) mAddressAdapter); |
RoboErik | ce8a833 | 2011-08-09 17:13:01 -0700 | [diff] [blame] | 1563 | list.setOnFocusListShrinkRecipients(false); |
Mindy Pereira | 18cabd2 | 2011-06-09 18:31:23 -0700 | [diff] [blame] | 1564 | } else { |
| 1565 | mAddressAdapter = new EmailAddressAdapter(mActivity); |
| 1566 | list.setAdapter((EmailAddressAdapter)mAddressAdapter); |
| 1567 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1568 | list.setTokenizer(new Rfc822Tokenizer()); |
| 1569 | list.setValidator(mEmailValidator); |
| 1570 | |
| 1571 | // NOTE: assumes no other filters are set |
| 1572 | list.setFilters(sRecipientFilters); |
| 1573 | |
| 1574 | return list; |
| 1575 | } |
| 1576 | |
| 1577 | /** |
| 1578 | * From com.google.android.gm.ComposeActivity Implements special address |
| 1579 | * cleanup rules: The first space key entry following an "@" symbol that is |
| 1580 | * followed by any combination of letters and symbols, including one+ dots |
| 1581 | * and zero commas, should insert an extra comma (followed by the space). |
| 1582 | */ |
Erik | 7b92da2 | 2010-09-23 14:55:22 -0700 | [diff] [blame] | 1583 | private static InputFilter[] sRecipientFilters = new InputFilter[] { new Rfc822InputFilter() }; |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1584 | |
| 1585 | private void setDate(TextView view, long millis) { |
| 1586 | int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR |
| 1587 | | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_MONTH |
| 1588 | | DateUtils.FORMAT_ABBREV_WEEKDAY; |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 1589 | |
| 1590 | // Unfortunately, DateUtils doesn't support a timezone other than the |
| 1591 | // default timezone provided by the system, so we have this ugly hack |
| 1592 | // here to trick it into formatting our time correctly. In order to |
| 1593 | // prevent all sorts of craziness, we synchronize on the TimeZone class |
| 1594 | // to prevent other threads from reading an incorrect timezone from |
| 1595 | // calls to TimeZone#getDefault() |
| 1596 | // TODO fix this if/when DateUtils allows for passing in a timezone |
| 1597 | String dateString; |
| 1598 | synchronized (TimeZone.class) { |
| 1599 | TimeZone.setDefault(TimeZone.getTimeZone(mTimezone)); |
| 1600 | dateString = DateUtils.formatDateTime(mActivity, millis, flags); |
| 1601 | // setting the default back to null restores the correct behavior |
| 1602 | TimeZone.setDefault(null); |
| 1603 | } |
| 1604 | view.setText(dateString); |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1605 | } |
| 1606 | |
| 1607 | private void setTime(TextView view, long millis) { |
| 1608 | int flags = DateUtils.FORMAT_SHOW_TIME; |
| 1609 | if (DateFormat.is24HourFormat(mActivity)) { |
| 1610 | flags |= DateUtils.FORMAT_24HOUR; |
| 1611 | } |
Mason Tang | 4c8871b | 2010-08-10 10:17:43 -0700 | [diff] [blame] | 1612 | |
| 1613 | // Unfortunately, DateUtils doesn't support a timezone other than the |
| 1614 | // default timezone provided by the system, so we have this ugly hack |
| 1615 | // here to trick it into formatting our time correctly. In order to |
| 1616 | // prevent all sorts of craziness, we synchronize on the TimeZone class |
| 1617 | // to prevent other threads from reading an incorrect timezone from |
| 1618 | // calls to TimeZone#getDefault() |
| 1619 | // TODO fix this if/when DateUtils allows for passing in a timezone |
| 1620 | String timeString; |
| 1621 | synchronized (TimeZone.class) { |
| 1622 | TimeZone.setDefault(TimeZone.getTimeZone(mTimezone)); |
| 1623 | timeString = DateUtils.formatDateTime(mActivity, millis, flags); |
| 1624 | TimeZone.setDefault(null); |
| 1625 | } |
| 1626 | view.setText(timeString); |
| 1627 | } |
| 1628 | |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1629 | /** |
| 1630 | * @param isChecked |
| 1631 | */ |
| 1632 | protected void setAllDayViewsVisibility(boolean isChecked) { |
| 1633 | if (isChecked) { |
| 1634 | if (mEndTime.hour == 0 && mEndTime.minute == 0) { |
Michael Chan | 8b1119b | 2012-01-06 16:04:55 -0800 | [diff] [blame] | 1635 | if (mAllDay != isChecked) { |
| 1636 | mEndTime.monthDay--; |
| 1637 | } |
| 1638 | |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1639 | long endMillis = mEndTime.normalize(true); |
| 1640 | |
| 1641 | // Do not allow an event to have an end time |
| 1642 | // before the |
| 1643 | // start time. |
| 1644 | if (mEndTime.before(mStartTime)) { |
| 1645 | mEndTime.set(mStartTime); |
| 1646 | endMillis = mEndTime.normalize(true); |
| 1647 | } |
| 1648 | setDate(mEndDateButton, endMillis); |
| 1649 | setTime(mEndTimeButton, endMillis); |
| 1650 | } |
| 1651 | |
| 1652 | mStartTimeButton.setVisibility(View.GONE); |
| 1653 | mEndTimeButton.setVisibility(View.GONE); |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 1654 | mTimezoneRow.setVisibility(View.GONE); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1655 | } else { |
| 1656 | if (mEndTime.hour == 0 && mEndTime.minute == 0) { |
Michael Chan | 8b1119b | 2012-01-06 16:04:55 -0800 | [diff] [blame] | 1657 | if (mAllDay != isChecked) { |
| 1658 | mEndTime.monthDay++; |
| 1659 | } |
| 1660 | |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1661 | long endMillis = mEndTime.normalize(true); |
| 1662 | setDate(mEndDateButton, endMillis); |
| 1663 | setTime(mEndTimeButton, endMillis); |
| 1664 | } |
| 1665 | mStartTimeButton.setVisibility(View.VISIBLE); |
| 1666 | mEndTimeButton.setVisibility(View.VISIBLE); |
Michael Chan | b20942b | 2011-09-08 00:52:18 -0700 | [diff] [blame] | 1667 | mTimezoneRow.setVisibility(View.VISIBLE); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1668 | } |
Sam Blitzstein | 7cdfb4d | 2013-02-22 15:30:27 -0800 | [diff] [blame] | 1669 | |
| 1670 | // If this is a new event, and if availability has not yet been |
| 1671 | // explicitly set, toggle busy/available as the inverse of all day. |
| 1672 | if (mModel.mUri == null && !mAvailabilityExplicitlySet) { |
| 1673 | // Values are from R.arrays.availability_values. |
| 1674 | // 0 = busy |
| 1675 | // 1 = available |
| 1676 | int newAvailabilityValue = isChecked? 1 : 0; |
| 1677 | if (mAvailabilityAdapter != null && mAvailabilityValues != null |
| 1678 | && mAvailabilityValues.contains(newAvailabilityValue)) { |
| 1679 | // We'll need to let the spinner's listener know that we're |
| 1680 | // explicitly toggling it. |
| 1681 | mAllDayChangingAvailability = true; |
| 1682 | |
| 1683 | String newAvailabilityLabel = mOriginalAvailabilityLabels.get(newAvailabilityValue); |
| 1684 | int newAvailabilityPos = mAvailabilityAdapter.getPosition(newAvailabilityLabel); |
| 1685 | mAvailabilitySpinner.setSelection(newAvailabilityPos); |
| 1686 | } |
| 1687 | } |
| 1688 | |
Michael Chan | 8b1119b | 2012-01-06 16:04:55 -0800 | [diff] [blame] | 1689 | mAllDay = isChecked; |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 1690 | updateHomeTime(); |
Erik | c07a57f | 2010-12-01 10:45:48 -0800 | [diff] [blame] | 1691 | } |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1692 | |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1693 | public void setColorPickerButtonStates(int[] eventColors) { |
| 1694 | if (eventColors == null || eventColors.length == 0) { |
James Kung | e134cd5 | 2013-02-13 11:33:49 -0800 | [diff] [blame] | 1695 | mColorPickerNewEvent.setVisibility(View.INVISIBLE); |
James Kung | c2ea150 | 2013-02-14 17:57:44 -0800 | [diff] [blame] | 1696 | mColorPickerExistingEvent.setVisibility(View.GONE); |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1697 | } else { |
James Kung | e134cd5 | 2013-02-13 11:33:49 -0800 | [diff] [blame] | 1698 | mColorPickerNewEvent.setVisibility(View.VISIBLE); |
| 1699 | mColorPickerExistingEvent.setVisibility(View.VISIBLE); |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1700 | } |
| 1701 | } |
| 1702 | |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1703 | @Override |
| 1704 | public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1705 | // This is only used for the Calendar spinner in new events, and only fires when the |
Isaac Katzenelson | 6a63b77 | 2011-09-28 15:56:33 -0700 | [diff] [blame] | 1706 | // calendar selection changes or on screen rotation |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1707 | Cursor c = (Cursor) parent.getItemAtPosition(position); |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1708 | if (c == null) { |
| 1709 | // TODO: can this happen? should we drop this check? |
| 1710 | Log.w(TAG, "Cursor not set on calendar item"); |
| 1711 | return; |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1712 | } |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1713 | |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1714 | // Do nothing if the selection didn't change so that reminders will not get lost |
| 1715 | int idColumn = c.getColumnIndexOrThrow(Calendars._ID); |
| 1716 | long calendarId = c.getLong(idColumn); |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1717 | int colorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR); |
RoboErik | 4acb2fd | 2011-07-18 15:39:49 -0700 | [diff] [blame] | 1718 | int color = c.getInt(colorColumn); |
| 1719 | int displayColor = Utils.getDisplayColorFromColor(color); |
Mindy Pereira | eb51f84 | 2011-11-11 14:45:54 -0800 | [diff] [blame] | 1720 | |
James Kung | 317f661 | 2013-03-05 16:29:14 -0800 | [diff] [blame] | 1721 | // Prevents resetting of data (reminders, etc.) on orientation change. |
James Kung | f56b149 | 2013-03-07 15:10:13 -0800 | [diff] [blame] | 1722 | if (calendarId == mModel.mCalendarId && mModel.isCalendarColorInitialized() && |
| 1723 | displayColor == mModel.getCalendarColor()) { |
James Kung | 317f661 | 2013-03-05 16:29:14 -0800 | [diff] [blame] | 1724 | return; |
RoboErik | 3a00271 | 2011-08-17 18:18:37 -0700 | [diff] [blame] | 1725 | } |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1726 | |
James Kung | 317f661 | 2013-03-05 16:29:14 -0800 | [diff] [blame] | 1727 | setSpinnerBackgroundColor(displayColor); |
| 1728 | |
Isaac Katzenelson | 6a63b77 | 2011-09-28 15:56:33 -0700 | [diff] [blame] | 1729 | mModel.mCalendarId = calendarId; |
James Kung | f56b149 | 2013-03-07 15:10:13 -0800 | [diff] [blame] | 1730 | mModel.setCalendarColor(displayColor); |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1731 | mModel.mCalendarAccountName = c.getString(EditEventHelper.CALENDARS_INDEX_ACCOUNT_NAME); |
| 1732 | mModel.mCalendarAccountType = c.getString(EditEventHelper.CALENDARS_INDEX_ACCOUNT_TYPE); |
James Kung | f56b149 | 2013-03-07 15:10:13 -0800 | [diff] [blame] | 1733 | mModel.setEventColor(mModel.getCalendarColor()); |
James Kung | 4afba18 | 2012-12-18 23:12:08 -0800 | [diff] [blame] | 1734 | |
| 1735 | setColorPickerButtonStates(mModel.getCalendarEventColors()); |
| 1736 | |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1737 | // Update the max/allowed reminders with the new calendar properties. |
| 1738 | int maxRemindersColumn = c.getColumnIndexOrThrow(Calendars.MAX_REMINDERS); |
| 1739 | mModel.mCalendarMaxReminders = c.getInt(maxRemindersColumn); |
| 1740 | int allowedRemindersColumn = c.getColumnIndexOrThrow(Calendars.ALLOWED_REMINDERS); |
| 1741 | mModel.mCalendarAllowedReminders = c.getString(allowedRemindersColumn); |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 1742 | int allowedAttendeeTypesColumn = c.getColumnIndexOrThrow(Calendars.ALLOWED_ATTENDEE_TYPES); |
| 1743 | mModel.mCalendarAllowedAttendeeTypes = c.getString(allowedAttendeeTypesColumn); |
| 1744 | int allowedAvailabilityColumn = c.getColumnIndexOrThrow(Calendars.ALLOWED_AVAILABILITY); |
| 1745 | mModel.mCalendarAllowedAvailability = c.getString(allowedAvailabilityColumn); |
Andy McFadden | 9645d9c | 2011-05-16 15:28:15 -0700 | [diff] [blame] | 1746 | |
| 1747 | // Discard the current reminders and replace them with the model's default reminder set. |
| 1748 | // We could attempt to save & restore the reminders that have been added, but that's |
| 1749 | // probably more trouble than it's worth. |
| 1750 | mModel.mReminders.clear(); |
| 1751 | mModel.mReminders.addAll(mModel.mDefaultReminders); |
| 1752 | mModel.mHasAlarm = mModel.mReminders.size() != 0; |
| 1753 | |
| 1754 | // Update the UI elements. |
| 1755 | mReminderItems.clear(); |
| 1756 | LinearLayout reminderLayout = |
| 1757 | (LinearLayout) mScrollView.findViewById(R.id.reminder_items_container); |
| 1758 | reminderLayout.removeAllViews(); |
| 1759 | prepareReminders(); |
RoboErik | c6680c5 | 2011-10-28 13:57:54 -0700 | [diff] [blame] | 1760 | prepareAvailability(); |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1761 | } |
| 1762 | |
Erik | 8a54896 | 2011-01-10 18:08:03 -0800 | [diff] [blame] | 1763 | /** |
| 1764 | * Checks if the start and end times for this event should be displayed in |
| 1765 | * the Calendar app's time zone as well and formats and displays them. |
| 1766 | */ |
| 1767 | private void updateHomeTime() { |
| 1768 | String tz = Utils.getTimeZone(mActivity, null); |
| 1769 | if (!mAllDayCheckBox.isChecked() && !TextUtils.equals(tz, mTimezone) |
| 1770 | && mModification != EditEventHelper.MODIFY_UNINITIALIZED) { |
| 1771 | int flags = DateUtils.FORMAT_SHOW_TIME; |
| 1772 | boolean is24Format = DateFormat.is24HourFormat(mActivity); |
| 1773 | if (is24Format) { |
| 1774 | flags |= DateUtils.FORMAT_24HOUR; |
| 1775 | } |
| 1776 | long millisStart = mStartTime.toMillis(false); |
| 1777 | long millisEnd = mEndTime.toMillis(false); |
| 1778 | |
| 1779 | boolean isDSTStart = mStartTime.isDst != 0; |
| 1780 | boolean isDSTEnd = mEndTime.isDst != 0; |
| 1781 | |
| 1782 | // First update the start date and times |
| 1783 | String tzDisplay = TimeZone.getTimeZone(tz).getDisplayName( |
| 1784 | isDSTStart, TimeZone.SHORT, Locale.getDefault()); |
| 1785 | StringBuilder time = new StringBuilder(); |
| 1786 | |
| 1787 | mSB.setLength(0); |
| 1788 | time.append(DateUtils |
| 1789 | .formatDateRange(mActivity, mF, millisStart, millisStart, flags, tz)) |
| 1790 | .append(" ").append(tzDisplay); |
| 1791 | mStartTimeHome.setText(time.toString()); |
| 1792 | |
| 1793 | flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
| 1794 | | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_WEEKDAY; |
| 1795 | mSB.setLength(0); |
| 1796 | mStartDateHome |
| 1797 | .setText(DateUtils.formatDateRange( |
| 1798 | mActivity, mF, millisStart, millisStart, flags, tz).toString()); |
| 1799 | |
| 1800 | // Make any adjustments needed for the end times |
| 1801 | if (isDSTEnd != isDSTStart) { |
| 1802 | tzDisplay = TimeZone.getTimeZone(tz).getDisplayName( |
| 1803 | isDSTEnd, TimeZone.SHORT, Locale.getDefault()); |
| 1804 | } |
| 1805 | flags = DateUtils.FORMAT_SHOW_TIME; |
| 1806 | if (is24Format) { |
| 1807 | flags |= DateUtils.FORMAT_24HOUR; |
| 1808 | } |
| 1809 | |
| 1810 | // Then update the end times |
| 1811 | time.setLength(0); |
| 1812 | mSB.setLength(0); |
| 1813 | time.append(DateUtils.formatDateRange( |
| 1814 | mActivity, mF, millisEnd, millisEnd, flags, tz)).append(" ").append(tzDisplay); |
| 1815 | mEndTimeHome.setText(time.toString()); |
| 1816 | |
| 1817 | flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
| 1818 | | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_WEEKDAY; |
| 1819 | mSB.setLength(0); |
| 1820 | mEndDateHome.setText(DateUtils.formatDateRange( |
| 1821 | mActivity, mF, millisEnd, millisEnd, flags, tz).toString()); |
| 1822 | |
| 1823 | mStartHomeGroup.setVisibility(View.VISIBLE); |
| 1824 | mEndHomeGroup.setVisibility(View.VISIBLE); |
| 1825 | } else { |
| 1826 | mStartHomeGroup.setVisibility(View.GONE); |
| 1827 | mEndHomeGroup.setVisibility(View.GONE); |
| 1828 | } |
| 1829 | } |
| 1830 | |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1831 | @Override |
| 1832 | public void onNothingSelected(AdapterView<?> parent) { |
Erik | 3400a2b | 2010-12-06 17:48:44 -0800 | [diff] [blame] | 1833 | } |
Erik | eca82e9 | 2010-06-11 14:05:00 -0700 | [diff] [blame] | 1834 | } |