| /* |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.calendar; |
| |
| import static android.provider.Calendar.EVENT_BEGIN_TIME; |
| import static android.provider.Calendar.EVENT_END_TIME; |
| import android.app.Activity; |
| import android.content.ContentResolver; |
| import android.content.ContentUris; |
| import android.content.ContentValues; |
| import android.content.Intent; |
| import android.content.SharedPreferences; |
| import android.content.res.Resources; |
| import android.database.Cursor; |
| import android.graphics.PorterDuff; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.pim.EventRecurrence; |
| import android.preference.PreferenceManager; |
| import android.provider.Calendar; |
| import android.provider.Calendar.Attendees; |
| import android.provider.Calendar.Calendars; |
| import android.provider.Calendar.Events; |
| import android.provider.Calendar.Reminders; |
| import android.text.format.DateFormat; |
| import android.text.format.DateUtils; |
| import android.text.format.Time; |
| import android.util.Log; |
| import android.view.KeyEvent; |
| import android.view.Menu; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.widget.AdapterView; |
| import android.widget.ArrayAdapter; |
| import android.widget.ImageButton; |
| import android.widget.LinearLayout; |
| import android.widget.Spinner; |
| import android.widget.TextView; |
| import android.widget.Toast; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| |
| public class EventInfoActivity extends Activity implements View.OnClickListener, |
| AdapterView.OnItemSelectedListener { |
| private static final int MAX_REMINDERS = 5; |
| |
| /** |
| * These are the corresponding indices into the array of strings |
| * "R.array.change_response_labels" in the resource file. |
| */ |
| static final int UPDATE_SINGLE = 0; |
| static final int UPDATE_ALL = 1; |
| |
| private static final String[] EVENT_PROJECTION = new String[] { |
| Events._ID, // 0 do not remove; used in DeleteEventHelper |
| Events.TITLE, // 1 do not remove; used in DeleteEventHelper |
| Events.RRULE, // 2 do not remove; used in DeleteEventHelper |
| Events.ALL_DAY, // 3 do not remove; used in DeleteEventHelper |
| Events.CALENDAR_ID, // 4 do not remove; used in DeleteEventHelper |
| Events.DTSTART, // 5 do not remove; used in DeleteEventHelper |
| Events._SYNC_ID, // 6 do not remove; used in DeleteEventHelper |
| Events.EVENT_TIMEZONE, // 7 do not remove; used in DeleteEventHelper |
| Events.DESCRIPTION, // 8 |
| Events.EVENT_LOCATION, // 9 |
| Events.HAS_ALARM, // 10 |
| Events.ACCESS_LEVEL, // 11 |
| Events.COLOR, // 12 |
| }; |
| private static final int EVENT_INDEX_ID = 0; |
| private static final int EVENT_INDEX_TITLE = 1; |
| private static final int EVENT_INDEX_RRULE = 2; |
| private static final int EVENT_INDEX_ALL_DAY = 3; |
| private static final int EVENT_INDEX_CALENDAR_ID = 4; |
| private static final int EVENT_INDEX_SYNC_ID = 6; |
| private static final int EVENT_INDEX_EVENT_TIMEZONE = 7; |
| private static final int EVENT_INDEX_DESCRIPTION = 8; |
| private static final int EVENT_INDEX_EVENT_LOCATION = 9; |
| private static final int EVENT_INDEX_HAS_ALARM = 10; |
| private static final int EVENT_INDEX_ACCESS_LEVEL = 11; |
| private static final int EVENT_INDEX_COLOR = 12; |
| |
| private static final String[] ATTENDEES_PROJECTION = new String[] { |
| Attendees._ID, // 0 |
| Attendees.ATTENDEE_RELATIONSHIP, // 1 |
| Attendees.ATTENDEE_STATUS, // 2 |
| }; |
| private static final int ATTENDEES_INDEX_ID = 0; |
| private static final int ATTENDEES_INDEX_RELATIONSHIP = 1; |
| private static final int ATTENDEES_INDEX_STATUS = 2; |
| private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=%d"; |
| |
| static final String[] CALENDARS_PROJECTION = new String[] { |
| Calendars._ID, // 0 |
| Calendars.DISPLAY_NAME, // 1 |
| }; |
| static final int CALENDARS_INDEX_DISPLAY_NAME = 1; |
| static final String CALENDARS_WHERE = Calendars._ID + "=%d"; |
| |
| private static final String[] REMINDERS_PROJECTION = new String[] { |
| Reminders._ID, // 0 |
| Reminders.MINUTES, // 1 |
| }; |
| private static final int REMINDERS_INDEX_MINUTES = 1; |
| private static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=%d AND (" + |
| Reminders.METHOD + "=" + Reminders.METHOD_ALERT + " OR " + Reminders.METHOD + "=" + |
| Reminders.METHOD_DEFAULT + ")"; |
| |
| private static final int MENU_GROUP_REMINDER = 1; |
| private static final int MENU_GROUP_EDIT = 2; |
| private static final int MENU_GROUP_DELETE = 3; |
| |
| private static final int MENU_ADD_REMINDER = 1; |
| private static final int MENU_EDIT = 2; |
| private static final int MENU_DELETE = 3; |
| |
| private static final int ATTENDEE_NO_RESPONSE = -1; |
| private static final int[] ATTENDEE_VALUES = { |
| ATTENDEE_NO_RESPONSE, |
| Attendees.ATTENDEE_STATUS_ACCEPTED, |
| Attendees.ATTENDEE_STATUS_TENTATIVE, |
| Attendees.ATTENDEE_STATUS_DECLINED, |
| }; |
| |
| private LinearLayout mRemindersContainer; |
| |
| private Uri mUri; |
| private long mEventId; |
| private Cursor mEventCursor; |
| private Cursor mAttendeesCursor; |
| private Cursor mCalendarsCursor; |
| |
| private long mStartMillis; |
| private long mEndMillis; |
| private int mVisibility = Calendars.NO_ACCESS; |
| private int mRelationship = Attendees.RELATIONSHIP_ORGANIZER; |
| |
| private ArrayList<Integer> mOriginalMinutes = new ArrayList<Integer>(); |
| private ArrayList<LinearLayout> mReminderItems = new ArrayList<LinearLayout>(0); |
| private ArrayList<Integer> mReminderValues; |
| private ArrayList<String> mReminderLabels; |
| private int mDefaultReminderMinutes; |
| |
| private DeleteEventHelper mDeleteEventHelper; |
| private EditResponseHelper mEditResponseHelper; |
| |
| private int mResponseOffset; |
| private int mOriginalAttendeeResponse; |
| private boolean mIsRepeating; |
| |
| // This is called when one of the "remove reminder" buttons is selected. |
| public void onClick(View v) { |
| LinearLayout reminderItem = (LinearLayout) v.getParent(); |
| LinearLayout parent = (LinearLayout) reminderItem.getParent(); |
| parent.removeView(reminderItem); |
| mReminderItems.remove(reminderItem); |
| updateRemindersVisibility(); |
| } |
| |
| public void onItemSelected(AdapterView parent, View v, int position, long id) { |
| // If they selected the "No response" option, then don't display the |
| // dialog asking which events to change. |
| if (id == 0 && mResponseOffset == 0) { |
| return; |
| } |
| |
| // If this is not a repeating event, then don't display the dialog |
| // asking which events to change. |
| if (!mIsRepeating) { |
| return; |
| } |
| |
| // If the selection is the same as the original, then don't display the |
| // dialog asking which events to change. |
| int index = findResponseIndexFor(mOriginalAttendeeResponse); |
| if (position == index + mResponseOffset) { |
| return; |
| } |
| |
| // This is a repeating event. We need to ask the user if they mean to |
| // change just this one instance or all instances. |
| mEditResponseHelper.showDialog(mEditResponseHelper.getWhichEvents()); |
| } |
| |
| public void onNothingSelected(AdapterView parent) { |
| } |
| |
| @Override |
| protected void onCreate(Bundle icicle) { |
| super.onCreate(icicle); |
| |
| // Event cursor |
| Intent intent = getIntent(); |
| mUri = intent.getData(); |
| ContentResolver cr = getContentResolver(); |
| mStartMillis = intent.getLongExtra(EVENT_BEGIN_TIME, 0); |
| mEndMillis = intent.getLongExtra(EVENT_END_TIME, 0); |
| mEventCursor = managedQuery(mUri, EVENT_PROJECTION, null, null); |
| if (initEventCursor()) { |
| // The cursor is empty. This can happen if the event was deleted. |
| finish(); |
| return; |
| } |
| |
| setContentView(R.layout.event_info_activity); |
| |
| // Attendees cursor |
| Uri uri = Attendees.CONTENT_URI; |
| String where = String.format(ATTENDEES_WHERE, mEventId); |
| mAttendeesCursor = managedQuery(uri, ATTENDEES_PROJECTION, where, null); |
| initAttendeesCursor(); |
| |
| // Calendars cursor |
| uri = Calendars.CONTENT_URI; |
| where = String.format(CALENDARS_WHERE, mEventCursor.getLong(EVENT_INDEX_CALENDAR_ID)); |
| mCalendarsCursor = managedQuery(uri, CALENDARS_PROJECTION, where, null); |
| initCalendarsCursor(); |
| |
| Resources res = getResources(); |
| |
| if (mVisibility >= Calendars.CONTRIBUTOR_ACCESS && |
| mRelationship == Attendees.RELATIONSHIP_ATTENDEE) { |
| setTitle(res.getString(R.string.event_info_title_invite)); |
| } else { |
| setTitle(res.getString(R.string.event_info_title)); |
| } |
| |
| // Initialize the reminder values array. |
| Resources r = getResources(); |
| String[] strings = r.getStringArray(R.array.reminder_minutes_values); |
| int size = strings.length; |
| ArrayList<Integer> list = new ArrayList<Integer>(size); |
| for (int i = 0 ; i < size ; i++) { |
| list.add(Integer.parseInt(strings[i])); |
| } |
| mReminderValues = list; |
| String[] labels = r.getStringArray(R.array.reminder_minutes_labels); |
| mReminderLabels = new ArrayList<String>(Arrays.asList(labels)); |
| |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); |
| String durationString = |
| prefs.getString(CalendarPreferenceActivity.KEY_DEFAULT_REMINDER, "0"); |
| mDefaultReminderMinutes = Integer.parseInt(durationString); |
| |
| mRemindersContainer = (LinearLayout) findViewById(R.id.reminder_items_container); |
| |
| // Reminders cursor |
| boolean hasAlarm = mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) != 0; |
| if (hasAlarm) { |
| uri = Reminders.CONTENT_URI; |
| where = String.format(REMINDERS_WHERE, mEventId); |
| Cursor reminderCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null); |
| try { |
| // First pass: collect all the custom reminder minutes (e.g., |
| // a reminder of 8 minutes) into a global list. |
| while (reminderCursor.moveToNext()) { |
| int minutes = reminderCursor.getInt(REMINDERS_INDEX_MINUTES); |
| EditEvent.addMinutesToList(this, mReminderValues, mReminderLabels, minutes); |
| } |
| |
| // Second pass: create the reminder spinners |
| reminderCursor.moveToPosition(-1); |
| while (reminderCursor.moveToNext()) { |
| int minutes = reminderCursor.getInt(REMINDERS_INDEX_MINUTES); |
| mOriginalMinutes.add(minutes); |
| EditEvent.addReminder(this, this, mReminderItems, mReminderValues, |
| mReminderLabels, minutes); |
| } |
| } finally { |
| reminderCursor.close(); |
| } |
| } |
| |
| updateView(); |
| updateRemindersVisibility(); |
| |
| // Setup the + Add Reminder Button |
| View.OnClickListener addReminderOnClickListener = new View.OnClickListener() { |
| public void onClick(View v) { |
| addReminder(); |
| } |
| }; |
| ImageButton reminderRemoveButton = (ImageButton) findViewById(R.id.reminder_add); |
| reminderRemoveButton.setOnClickListener(addReminderOnClickListener); |
| |
| mDeleteEventHelper = new DeleteEventHelper(this, true /* exit when done */); |
| mEditResponseHelper = new EditResponseHelper(this); |
| } |
| |
| @Override |
| protected void onResume() { |
| super.onResume(); |
| if (initEventCursor()) { |
| // The cursor is empty. This can happen if the event was deleted. |
| finish(); |
| return; |
| } |
| initAttendeesCursor(); |
| initCalendarsCursor(); |
| } |
| |
| /** |
| * Initializes the event cursor, which is expected to point to the first |
| * (and only) result from a query. |
| * @return true if the cursor is empty. |
| */ |
| private boolean initEventCursor() { |
| if ((mEventCursor == null) || (mEventCursor.getCount() == 0)) { |
| return true; |
| } |
| mEventCursor.moveToFirst(); |
| mVisibility = mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL); |
| mEventId = mEventCursor.getInt(EVENT_INDEX_ID); |
| String rRule = mEventCursor.getString(EVENT_INDEX_RRULE); |
| mIsRepeating = (rRule != null); |
| return false; |
| } |
| |
| private void initAttendeesCursor() { |
| if (mAttendeesCursor != null) { |
| if (mAttendeesCursor.moveToFirst()) { |
| mRelationship = mAttendeesCursor.getInt(ATTENDEES_INDEX_RELATIONSHIP); |
| } |
| } |
| } |
| |
| private void initCalendarsCursor() { |
| if (mCalendarsCursor != null) { |
| mCalendarsCursor.moveToFirst(); |
| } |
| } |
| |
| @Override |
| public void onPause() { |
| super.onPause(); |
| if (!isFinishing()) { |
| return; |
| } |
| ContentResolver cr = getContentResolver(); |
| ArrayList<Integer> reminderMinutes = EditEvent.reminderItemsToMinutes(mReminderItems, |
| mReminderValues); |
| boolean changed = EditEvent.saveReminders(cr, mEventId, reminderMinutes, mOriginalMinutes); |
| changed |= saveResponse(cr); |
| if (changed) { |
| Toast.makeText(this, R.string.saving_event, Toast.LENGTH_SHORT).show(); |
| } |
| } |
| |
| @Override |
| public boolean onCreateOptionsMenu(Menu menu) { |
| MenuItem item; |
| item = menu.add(MENU_GROUP_REMINDER, MENU_ADD_REMINDER, 0, |
| R.string.add_new_reminder); |
| item.setIcon(R.drawable.ic_menu_reminder); |
| item.setAlphabeticShortcut('r'); |
| |
| item = menu.add(MENU_GROUP_EDIT, MENU_EDIT, 0, R.string.edit_event_label); |
| item.setIcon(android.R.drawable.ic_menu_edit); |
| item.setAlphabeticShortcut('e'); |
| |
| item = menu.add(MENU_GROUP_DELETE, MENU_DELETE, 0, R.string.delete_event_label); |
| item.setIcon(android.R.drawable.ic_menu_delete); |
| |
| return super.onCreateOptionsMenu(menu); |
| } |
| |
| @Override |
| public boolean onPrepareOptionsMenu(Menu menu) { |
| // Cannot add reminders to a shared calendar with only free/busy |
| // permissions |
| if (mVisibility >= Calendars.READ_ACCESS && mReminderItems.size() < MAX_REMINDERS) { |
| menu.setGroupVisible(MENU_GROUP_REMINDER, true); |
| menu.setGroupEnabled(MENU_GROUP_REMINDER, true); |
| } else { |
| menu.setGroupVisible(MENU_GROUP_REMINDER, false); |
| menu.setGroupEnabled(MENU_GROUP_REMINDER, false); |
| } |
| |
| if (mVisibility >= Calendars.CONTRIBUTOR_ACCESS && |
| mRelationship >= Attendees.RELATIONSHIP_ORGANIZER) { |
| menu.setGroupVisible(MENU_GROUP_EDIT, true); |
| menu.setGroupEnabled(MENU_GROUP_EDIT, true); |
| menu.setGroupVisible(MENU_GROUP_DELETE, true); |
| menu.setGroupEnabled(MENU_GROUP_DELETE, true); |
| } else { |
| menu.setGroupVisible(MENU_GROUP_EDIT, false); |
| menu.setGroupEnabled(MENU_GROUP_EDIT, false); |
| menu.setGroupVisible(MENU_GROUP_DELETE, false); |
| menu.setGroupEnabled(MENU_GROUP_DELETE, false); |
| } |
| |
| return super.onPrepareOptionsMenu(menu); |
| } |
| |
| private void addReminder() { |
| // TODO: when adding a new reminder, make it different from the |
| // last one in the list (if any). |
| if (mDefaultReminderMinutes == 0) { |
| EditEvent.addReminder(this, this, mReminderItems, |
| mReminderValues, mReminderLabels, 10 /* minutes */); |
| } else { |
| EditEvent.addReminder(this, this, mReminderItems, |
| mReminderValues, mReminderLabels, mDefaultReminderMinutes); |
| } |
| updateRemindersVisibility(); |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| super.onOptionsItemSelected(item); |
| switch (item.getItemId()) { |
| case MENU_ADD_REMINDER: |
| addReminder(); |
| break; |
| case MENU_EDIT: |
| doEdit(); |
| break; |
| case MENU_DELETE: |
| doDelete(); |
| break; |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean onKeyDown(int keyCode, KeyEvent event) { |
| if (keyCode == KeyEvent.KEYCODE_DEL) { |
| doDelete(); |
| return true; |
| } |
| return super.onKeyDown(keyCode, event); |
| } |
| |
| private void updateRemindersVisibility() { |
| if (mReminderItems.size() == 0) { |
| mRemindersContainer.setVisibility(View.GONE); |
| } else { |
| mRemindersContainer.setVisibility(View.VISIBLE); |
| } |
| } |
| |
| /** |
| * Saves the response to an invitation if the user changed the response. |
| * Returns true if the database was updated. |
| * |
| * @param cr the ContentResolver |
| * @return true if the database was changed |
| */ |
| private boolean saveResponse(ContentResolver cr) { |
| if (mAttendeesCursor == null || mEventCursor == null) { |
| return false; |
| } |
| Spinner spinner = (Spinner) findViewById(R.id.response_value); |
| int position = spinner.getSelectedItemPosition() - mResponseOffset; |
| if (position <= 0) { |
| return false; |
| } |
| |
| int status = ATTENDEE_VALUES[position]; |
| |
| // If the status has not changed, then don't update the database |
| if (status == mOriginalAttendeeResponse) { |
| return false; |
| } |
| |
| long attendeeId = mAttendeesCursor.getInt(ATTENDEES_INDEX_ID); |
| if (!mIsRepeating) { |
| // This is a non-repeating event |
| updateResponse(cr, mEventId, attendeeId, status); |
| return true; |
| } |
| |
| // This is a repeating event |
| int whichEvents = mEditResponseHelper.getWhichEvents(); |
| switch (whichEvents) { |
| case -1: |
| return false; |
| case UPDATE_SINGLE: |
| createExceptionResponse(cr, mEventId, attendeeId, status); |
| return true; |
| case UPDATE_ALL: |
| updateResponse(cr, mEventId, attendeeId, status); |
| return true; |
| default: |
| Log.e("Calendar", "Unexpected choice for updating invitation response"); |
| break; |
| } |
| return false; |
| } |
| |
| private void updateResponse(ContentResolver cr, long eventId, long attendeeId, int status) { |
| // Update the "selfAttendeeStatus" field for the event |
| ContentValues values = new ContentValues(); |
| |
| // Will need to add email when MULTIPLE_ATTENDEES_PER_EVENT supported. |
| values.put(Attendees.ATTENDEE_STATUS, status); |
| values.put(Attendees.EVENT_ID, eventId); |
| |
| Uri uri = ContentUris.withAppendedId(Attendees.CONTENT_URI, attendeeId); |
| cr.update(uri, values, null /* where */, null /* selection args */); |
| } |
| |
| private void createExceptionResponse(ContentResolver cr, long eventId, |
| long attendeeId, int status) { |
| // Fetch information about the repeating event. |
| Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId); |
| Cursor cursor = cr.query(uri, EVENT_PROJECTION, null, null, null); |
| if (cursor == null) { |
| return; |
| } |
| |
| try { |
| cursor.moveToFirst(); |
| ContentValues values = new ContentValues(); |
| |
| String title = cursor.getString(EVENT_INDEX_TITLE); |
| String timezone = cursor.getString(EVENT_INDEX_EVENT_TIMEZONE); |
| int calendarId = cursor.getInt(EVENT_INDEX_CALENDAR_ID); |
| boolean allDay = cursor.getInt(EVENT_INDEX_ALL_DAY) != 0; |
| String syncId = cursor.getString(EVENT_INDEX_SYNC_ID); |
| |
| values.put(Events.TITLE, title); |
| values.put(Events.EVENT_TIMEZONE, timezone); |
| values.put(Events.ALL_DAY, allDay ? 1 : 0); |
| values.put(Events.CALENDAR_ID, calendarId); |
| values.put(Events.DTSTART, mStartMillis); |
| values.put(Events.DTEND, mEndMillis); |
| values.put(Events.ORIGINAL_EVENT, syncId); |
| values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis); |
| values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0); |
| values.put(Events.STATUS, Events.STATUS_CONFIRMED); |
| values.put(Events.SELF_ATTENDEE_STATUS, status); |
| |
| // Create a recurrence exception |
| Uri newUri = cr.insert(Events.CONTENT_URI, values); |
| } finally { |
| cursor.close(); |
| } |
| } |
| |
| private int findResponseIndexFor(int response) { |
| int size = ATTENDEE_VALUES.length; |
| for (int index = 0; index < size; index++) { |
| if (ATTENDEE_VALUES[index] == response) { |
| return index; |
| } |
| } |
| return 0; |
| } |
| |
| private void doEdit() { |
| Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId); |
| Intent intent = new Intent(Intent.ACTION_EDIT, uri); |
| intent.putExtra(Calendar.EVENT_BEGIN_TIME, mStartMillis); |
| intent.putExtra(Calendar.EVENT_END_TIME, mEndMillis); |
| intent.setClass(EventInfoActivity.this, EditEvent.class); |
| startActivity(intent); |
| finish(); |
| } |
| |
| private void doDelete() { |
| mDeleteEventHelper.delete(mStartMillis, mEndMillis, mEventCursor, -1); |
| } |
| |
| private void updateView() { |
| if (mEventCursor == null) { |
| return; |
| } |
| Resources res = getResources(); |
| ContentResolver cr = getContentResolver(); |
| |
| String eventName = mEventCursor.getString(EVENT_INDEX_TITLE); |
| if (eventName == null || eventName.length() == 0) { |
| eventName = res.getString(R.string.no_title_label); |
| } |
| |
| boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0; |
| String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION); |
| String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION); |
| String rRule = mEventCursor.getString(EVENT_INDEX_RRULE); |
| boolean hasAlarm = mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) != 0; |
| String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE); |
| int color = mEventCursor.getInt(EVENT_INDEX_COLOR) & 0xbbffffff; |
| |
| View calBackground = findViewById(R.id.cal_background); |
| calBackground.setBackgroundColor(color); |
| |
| TextView title = (TextView) findViewById(R.id.title); |
| title.setTextColor(color); |
| |
| View divider = (View) findViewById(R.id.divider); |
| divider.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN); |
| |
| // What |
| if (eventName != null) { |
| setTextCommon(R.id.title, eventName); |
| } |
| |
| // When |
| String when; |
| int flags; |
| if (allDay) { |
| flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE; |
| } else { |
| flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE; |
| if (DateFormat.is24HourFormat(this)) { |
| flags |= DateUtils.FORMAT_24HOUR; |
| } |
| } |
| when = DateUtils.formatDateRange(this, mStartMillis, mEndMillis, flags); |
| setTextCommon(R.id.when, when); |
| |
| // Show the event timezone if it is different from the local timezone |
| Time time = new Time(); |
| String localTimezone = time.timezone; |
| if (allDay) { |
| localTimezone = Time.TIMEZONE_UTC; |
| } |
| if (eventTimezone != null && !localTimezone.equals(eventTimezone) && !allDay) { |
| setTextCommon(R.id.timezone, localTimezone); |
| } else { |
| setVisibilityCommon(R.id.timezone_container, View.GONE); |
| } |
| |
| // Repeat |
| if (rRule != null) { |
| EventRecurrence eventRecurrence = new EventRecurrence(); |
| eventRecurrence.parse(rRule); |
| Time date = new Time(); |
| if (allDay) { |
| date.timezone = Time.TIMEZONE_UTC; |
| } |
| date.set(mStartMillis); |
| eventRecurrence.setStartDate(date); |
| String repeatString = eventRecurrence.getRepeatString(); |
| setTextCommon(R.id.repeat, repeatString); |
| } else { |
| setVisibilityCommon(R.id.repeat_container, View.GONE); |
| } |
| |
| // Where |
| if (location == null || location.length() == 0) { |
| setVisibilityCommon(R.id.where, View.GONE); |
| } else { |
| setTextCommon(R.id.where, location); |
| } |
| |
| // Description |
| if (description == null || description.length() == 0) { |
| setVisibilityCommon(R.id.description, View.GONE); |
| } else { |
| setTextCommon(R.id.description, description); |
| } |
| |
| // Calendar |
| if (mCalendarsCursor != null) { |
| mCalendarsCursor.moveToFirst(); |
| String calendarName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME); |
| setTextCommon(R.id.calendar, calendarName); |
| } else { |
| setVisibilityCommon(R.id.calendar_container, View.GONE); |
| } |
| |
| // Response |
| updateResponse(); |
| } |
| |
| void updateResponse() { |
| if (mVisibility < Calendars.CONTRIBUTOR_ACCESS || |
| mRelationship != Attendees.RELATIONSHIP_ATTENDEE) { |
| setVisibilityCommon(R.id.response_container, View.GONE); |
| return; |
| } |
| |
| setVisibilityCommon(R.id.response_container, View.VISIBLE); |
| |
| Spinner spinner = (Spinner) findViewById(R.id.response_value); |
| |
| mOriginalAttendeeResponse = ATTENDEE_NO_RESPONSE; |
| if (mAttendeesCursor != null) { |
| mOriginalAttendeeResponse = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS); |
| } |
| mResponseOffset = 0; |
| |
| /* If the user has previously responded to this event |
| * we should not allow them to select no response again. |
| * Switch the entries to a set of entries without the |
| * no response option. |
| */ |
| if ((mOriginalAttendeeResponse != Attendees.ATTENDEE_STATUS_INVITED) |
| && (mOriginalAttendeeResponse != ATTENDEE_NO_RESPONSE) |
| && (mOriginalAttendeeResponse != Attendees.ATTENDEE_STATUS_NONE)) { |
| CharSequence[] entries; |
| entries = getResources().getTextArray(R.array.response_labels2); |
| mResponseOffset = -1; |
| ArrayAdapter<CharSequence> adapter = |
| new ArrayAdapter<CharSequence>(this, |
| android.R.layout.simple_spinner_item, entries); |
| adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
| spinner.setAdapter(adapter); |
| } |
| |
| int index = findResponseIndexFor(mOriginalAttendeeResponse); |
| spinner.setSelection(index + mResponseOffset); |
| spinner.setOnItemSelectedListener(this); |
| } |
| |
| private void setTextCommon(int id, CharSequence text) { |
| TextView textView = (TextView) findViewById(id); |
| if (textView == null) |
| return; |
| textView.setText(text); |
| } |
| |
| private void setVisibilityCommon(int id, int visibility) { |
| View v = findViewById(id); |
| if (v != null) { |
| v.setVisibility(visibility); |
| } |
| return; |
| } |
| } |