use of com.android.calendar.CalendarEventModel.ReminderEntry in project Etar-Calendar by Etar-Group.
the class EditEventHelper method saveRemindersWithBackRef.
/**
* Saves the reminders, if they changed. Returns true if operations to
* update the database were added. Uses a reference id since an id isn't
* created until the row is added.
*
* @param ops the array of ContentProviderOperations
* @param eventId the id of the event whose reminders are being updated
* @param reminderMinutes the array of reminders set by the user
* @param originalMinutes the original array of reminders
* @param forceSave if true, then save the reminders even if they didn't change
* @return true if operations to update the database were added
*/
public static boolean saveRemindersWithBackRef(ArrayList<ContentProviderOperation> ops, int eventIdIndex, ArrayList<ReminderEntry> reminders, ArrayList<ReminderEntry> originalReminders, boolean forceSave) {
// If the reminders have not changed, then don't update the database
if (reminders.equals(originalReminders) && !forceSave) {
return false;
}
// Delete all the existing reminders for this event
ContentProviderOperation.Builder b = ContentProviderOperation.newDelete(Reminders.CONTENT_URI);
b.withSelection(Reminders.EVENT_ID + "=?", new String[1]);
b.withSelectionBackReference(0, eventIdIndex);
ops.add(b.build());
ContentValues values = new ContentValues();
int len = reminders.size();
// Insert the new reminders, if any
for (int i = 0; i < len; i++) {
ReminderEntry re = reminders.get(i);
values.clear();
values.put(Reminders.MINUTES, re.getMinutes());
values.put(Reminders.METHOD, re.getMethod());
b = ContentProviderOperation.newInsert(Reminders.CONTENT_URI).withValues(values);
b.withValueBackReference(Reminders.EVENT_ID, eventIdIndex);
ops.add(b.build());
}
return true;
}
use of com.android.calendar.CalendarEventModel.ReminderEntry in project Etar-Calendar by Etar-Group.
the class EditEventHelper method saveEvent.
/**
* Saves the event. Returns true if the event was successfully saved, false
* otherwise.
*
* @param model The event model to save
* @param originalModel A model of the original event if it exists
* @param modifyWhich For recurring events which type of series modification to use
* @return true if the event was successfully queued for saving
*/
public boolean saveEvent(CalendarEventModel model, CalendarEventModel originalModel, int modifyWhich) {
boolean forceSaveReminders = false;
if (DEBUG) {
Log.d(TAG, "Saving event model: " + model);
}
if (!mEventOk) {
if (DEBUG) {
Log.w(TAG, "Event no longer exists. Event was not saved.");
}
return false;
}
// modifying an existing event and we have the wrong original model
if (model == null) {
Log.e(TAG, "Attempted to save null model.");
return false;
}
if (!model.isValid()) {
Log.e(TAG, "Attempted to save invalid model.");
return false;
}
if (originalModel != null && !isSameEvent(model, originalModel)) {
Log.e(TAG, "Attempted to update existing event but models didn't refer to the same " + "event.");
return false;
}
if (originalModel != null && model.isUnchanged(originalModel)) {
return false;
}
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int eventIdIndex = -1;
ContentValues values = getContentValuesFromModel(model);
if (model.mUri != null && originalModel == null) {
Log.e(TAG, "Existing event but no originalModel provided. Aborting save.");
return false;
}
Uri uri = null;
if (model.mUri != null) {
uri = Uri.parse(model.mUri);
}
// Update the "hasAlarm" field for the event
ArrayList<ReminderEntry> reminders = model.mReminders;
int len = reminders.size();
values.put(Events.HAS_ALARM, (len > 0) ? 1 : 0);
if (uri == null) {
// Add hasAttendeeData for a new event
values.put(Events.HAS_ATTENDEE_DATA, 1);
values.put(Events.STATUS, Events.STATUS_CONFIRMED);
eventIdIndex = ops.size();
ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(Events.CONTENT_URI).withValues(values);
ops.add(b.build());
forceSaveReminders = true;
} else if (TextUtils.isEmpty(model.mRrule) && TextUtils.isEmpty(originalModel.mRrule)) {
// Simple update to a non-recurring event
checkTimeDependentFields(originalModel, model, values, modifyWhich);
ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
} else if (TextUtils.isEmpty(originalModel.mRrule)) {
// This event was changed from a non-repeating event to a
// repeating event.
ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
} else if (modifyWhich == MODIFY_SELECTED) {
// Modify contents of the current instance of repeating event
// Create a recurrence exception
long begin = model.mOriginalStart;
values.put(Events.ORIGINAL_SYNC_ID, originalModel.mSyncId);
values.put(Events.ORIGINAL_INSTANCE_TIME, begin);
boolean allDay = originalModel.mAllDay;
values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0);
values.put(Events.STATUS, originalModel.mEventStatus);
eventIdIndex = ops.size();
ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(Events.CONTENT_URI).withValues(values);
ops.add(b.build());
forceSaveReminders = true;
} else if (modifyWhich == MODIFY_ALL_FOLLOWING) {
if (TextUtils.isEmpty(model.mRrule)) {
// to end at the new start time.
if (isFirstEventInSeries(model, originalModel)) {
ops.add(ContentProviderOperation.newDelete(uri).build());
} else {
// Update the current repeating event to end at the new start time. We
// ignore the RRULE returned because the exception event doesn't want one.
updatePastEvents(ops, originalModel, model.mOriginalStart);
}
eventIdIndex = ops.size();
values.put(Events.STATUS, originalModel.mEventStatus);
ops.add(ContentProviderOperation.newInsert(Events.CONTENT_URI).withValues(values).build());
} else {
if (isFirstEventInSeries(model, originalModel)) {
checkTimeDependentFields(originalModel, model, values, modifyWhich);
ContentProviderOperation.Builder b = ContentProviderOperation.newUpdate(uri).withValues(values);
ops.add(b.build());
} else {
// We need to update the existing recurrence to end before the exception
// event starts. If the recurrence rule has a COUNT, we need to adjust
// that in the original and in the exception. This call rewrites the
// original event's recurrence rule (in "ops"), and returns a new rule
// for the exception. If the exception explicitly set a new rule, however,
// we don't want to overwrite it.
String newRrule = updatePastEvents(ops, originalModel, model.mOriginalStart);
if (model.mRrule.equals(originalModel.mRrule)) {
values.put(Events.RRULE, newRrule);
}
// Create a new event with the user-modified fields
eventIdIndex = ops.size();
values.put(Events.STATUS, originalModel.mEventStatus);
ops.add(ContentProviderOperation.newInsert(Events.CONTENT_URI).withValues(values).build());
}
}
forceSaveReminders = true;
} else if (modifyWhich == MODIFY_ALL) {
// Modify all instances of repeating event
if (TextUtils.isEmpty(model.mRrule)) {
// We've changed a recurring event to a non-recurring event.
// Delete the whole series and replace it with a new
// non-recurring event.
ops.add(ContentProviderOperation.newDelete(uri).build());
eventIdIndex = ops.size();
ops.add(ContentProviderOperation.newInsert(Events.CONTENT_URI).withValues(values).build());
forceSaveReminders = true;
} else {
checkTimeDependentFields(originalModel, model, values, modifyWhich);
ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
}
}
// New Event or New Exception to an existing event
boolean newEvent = (eventIdIndex != -1);
ArrayList<ReminderEntry> originalReminders;
if (originalModel != null) {
originalReminders = originalModel.mReminders;
} else {
originalReminders = new ArrayList<ReminderEntry>();
}
if (newEvent) {
saveRemindersWithBackRef(ops, eventIdIndex, reminders, originalReminders, forceSaveReminders);
} else if (uri != null) {
long eventId = ContentUris.parseId(uri);
saveReminders(ops, eventId, reminders, originalReminders, forceSaveReminders);
}
ContentProviderOperation.Builder b;
boolean hasAttendeeData = model.mHasAttendeeData;
if (hasAttendeeData && model.mOwnerAttendeeId == -1) {
// Organizer is not an attendee
String ownerEmail = model.mOwnerAccount;
if (model.mAttendeesList.size() != 0 && Utils.isValidEmail(ownerEmail)) {
// Add organizer as attendee since we got some attendees
values.clear();
values.put(Attendees.ATTENDEE_EMAIL, ownerEmail);
values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ORGANIZER);
values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_ACCEPTED);
if (newEvent) {
b = ContentProviderOperation.newInsert(Attendees.CONTENT_URI).withValues(values);
b.withValueBackReference(Attendees.EVENT_ID, eventIdIndex);
} else {
values.put(Attendees.EVENT_ID, model.mId);
b = ContentProviderOperation.newInsert(Attendees.CONTENT_URI).withValues(values);
}
ops.add(b.build());
}
} else if (hasAttendeeData && model.mSelfAttendeeStatus != originalModel.mSelfAttendeeStatus && model.mOwnerAttendeeId != -1) {
if (DEBUG) {
Log.d(TAG, "Setting attendee status to " + model.mSelfAttendeeStatus);
}
Uri attUri = ContentUris.withAppendedId(Attendees.CONTENT_URI, model.mOwnerAttendeeId);
values.clear();
values.put(Attendees.ATTENDEE_STATUS, model.mSelfAttendeeStatus);
values.put(Attendees.EVENT_ID, model.mId);
b = ContentProviderOperation.newUpdate(attUri).withValues(values);
ops.add(b.build());
}
// a new event or an existing event. or is this a paranoia check?
if (hasAttendeeData && (newEvent || uri != null)) {
String attendees = model.getAttendeesString();
String originalAttendeesString;
if (originalModel != null) {
originalAttendeesString = originalModel.getAttendeesString();
} else {
originalAttendeesString = "";
}
// has changed it
if (newEvent || !TextUtils.equals(originalAttendeesString, attendees)) {
// figure out which attendees need to be added and which ones
// need to be deleted. use a linked hash set, so we maintain
// order (but also remove duplicates).
HashMap<String, Attendee> newAttendees = model.mAttendeesList;
LinkedList<String> removedAttendees = new LinkedList<String>();
// the eventId is only used if eventIdIndex is -1.
// TODO: clean up this code.
long eventId = uri != null ? ContentUris.parseId(uri) : -1;
// have any existing attendees.
if (!newEvent) {
removedAttendees.clear();
HashMap<String, Attendee> originalAttendees = originalModel.mAttendeesList;
for (String originalEmail : originalAttendees.keySet()) {
if (newAttendees.containsKey(originalEmail)) {
// existing attendee. remove from new attendees set.
newAttendees.remove(originalEmail);
} else {
// no longer in attendees. mark as removed.
removedAttendees.add(originalEmail);
}
}
// delete removed attendees if necessary
if (removedAttendees.size() > 0) {
b = ContentProviderOperation.newDelete(Attendees.CONTENT_URI);
String[] args = new String[removedAttendees.size() + 1];
args[0] = Long.toString(eventId);
int i = 1;
StringBuilder deleteWhere = new StringBuilder(ATTENDEES_DELETE_PREFIX);
for (String removedAttendee : removedAttendees) {
if (i > 1) {
deleteWhere.append(",");
}
deleteWhere.append("?");
args[i++] = removedAttendee;
}
deleteWhere.append(")");
b.withSelection(deleteWhere.toString(), args);
ops.add(b.build());
}
}
if (newAttendees.size() > 0) {
// Insert the new attendees
for (Attendee attendee : newAttendees.values()) {
values.clear();
values.put(Attendees.ATTENDEE_NAME, attendee.mName);
values.put(Attendees.ATTENDEE_EMAIL, attendee.mEmail);
values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_NONE);
if (newEvent) {
b = ContentProviderOperation.newInsert(Attendees.CONTENT_URI).withValues(values);
b.withValueBackReference(Attendees.EVENT_ID, eventIdIndex);
} else {
values.put(Attendees.EVENT_ID, eventId);
b = ContentProviderOperation.newInsert(Attendees.CONTENT_URI).withValues(values);
}
ops.add(b.build());
}
}
}
}
mService.startBatch(mService.getNextToken(), null, android.provider.CalendarContract.AUTHORITY, ops, Utils.UNDO_DELAY);
return true;
}
use of com.android.calendar.CalendarEventModel.ReminderEntry in project Etar-Calendar by Etar-Group.
the class EventInfoFragment method onSaveInstanceState.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(BUNDLE_KEY_EVENT_ID, mEventId);
outState.putLong(BUNDLE_KEY_START_MILLIS, mStartMillis);
outState.putLong(BUNDLE_KEY_END_MILLIS, mEndMillis);
outState.putBoolean(BUNDLE_KEY_IS_DIALOG, mIsDialog);
outState.putInt(BUNDLE_KEY_WINDOW_STYLE, mWindowStyle);
outState.putBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE, mDeleteDialogVisible);
outState.putInt(BUNDLE_KEY_CALENDAR_COLOR, mCalendarColor);
outState.putBoolean(BUNDLE_KEY_CALENDAR_COLOR_INIT, mCalendarColorInitialized);
outState.putInt(BUNDLE_KEY_ORIGINAL_COLOR, mOriginalColor);
outState.putBoolean(BUNDLE_KEY_ORIGINAL_COLOR_INIT, mOriginalColorInitialized);
outState.putInt(BUNDLE_KEY_CURRENT_COLOR, mCurrentColor);
outState.putBoolean(BUNDLE_KEY_CURRENT_COLOR_INIT, mCurrentColorInitialized);
outState.putInt(BUNDLE_KEY_CURRENT_COLOR_KEY, mCurrentColorKey);
// We'll need the temporary response for configuration changes.
outState.putInt(BUNDLE_KEY_TENTATIVE_USER_RESPONSE, mTentativeUserSetResponse);
if (mTentativeUserSetResponse != Attendees.ATTENDEE_STATUS_NONE && mEditResponseHelper != null) {
outState.putInt(BUNDLE_KEY_RESPONSE_WHICH_EVENTS, mEditResponseHelper.getWhichEvents());
}
// Save the current response.
int response;
if (mAttendeeResponseFromIntent != Attendees.ATTENDEE_STATUS_NONE) {
response = mAttendeeResponseFromIntent;
} else {
response = mOriginalAttendeeResponse;
}
outState.putInt(BUNDLE_KEY_ATTENDEE_RESPONSE, response);
if (mUserSetResponse != Attendees.ATTENDEE_STATUS_NONE) {
response = mUserSetResponse;
outState.putInt(BUNDLE_KEY_USER_SET_ATTENDEE_RESPONSE, response);
outState.putInt(BUNDLE_KEY_RESPONSE_WHICH_EVENTS, mWhichEvents);
}
// Save the reminders.
mReminders = EventViewUtils.reminderItemsToReminders(mReminderViews, mReminderMinuteValues, mReminderMethodValues);
int numReminders = mReminders.size();
ArrayList<Integer> reminderMinutes = new ArrayList<Integer>(numReminders);
ArrayList<Integer> reminderMethods = new ArrayList<Integer>(numReminders);
for (ReminderEntry reminder : mReminders) {
reminderMinutes.add(reminder.getMinutes());
reminderMethods.add(reminder.getMethod());
}
outState.putIntegerArrayList(BUNDLE_KEY_REMINDER_MINUTES, reminderMinutes);
outState.putIntegerArrayList(BUNDLE_KEY_REMINDER_METHODS, reminderMethods);
}
use of com.android.calendar.CalendarEventModel.ReminderEntry in project Etar-Calendar by Etar-Group.
the class EventInfoFragment method initReminders.
public void initReminders(View view, Cursor cursor) {
// Add reminders
mOriginalReminders.clear();
mUnsupportedReminders.clear();
while (cursor.moveToNext()) {
int minutes = cursor.getInt(EditEventHelper.REMINDERS_INDEX_MINUTES);
int method = cursor.getInt(EditEventHelper.REMINDERS_INDEX_METHOD);
if (method != Reminders.METHOD_DEFAULT && !mReminderMethodValues.contains(method)) {
// Stash unsupported reminder types separately so we don't alter
// them in the UI
mUnsupportedReminders.add(ReminderEntry.valueOf(minutes, method));
} else {
mOriginalReminders.add(ReminderEntry.valueOf(minutes, method));
}
}
// Sort appropriately for display (by time, then type)
Collections.sort(mOriginalReminders);
if (mUserModifiedReminders) {
// shown.
return;
}
LinearLayout parent = (LinearLayout) mScrollView.findViewById(R.id.reminder_items_container);
if (parent != null) {
parent.removeAllViews();
}
if (mReminderViews != null) {
mReminderViews.clear();
}
if (mHasAlarm) {
ArrayList<ReminderEntry> reminders;
// If applicable, use reminders saved in the bundle.
if (mReminders != null) {
reminders = mReminders;
} else {
reminders = mOriginalReminders;
}
// Insert any minute values that aren't represented in the minutes list.
for (ReminderEntry re : reminders) {
EventViewUtils.addMinutesToList(mActivity, mReminderMinuteValues, mReminderMinuteLabels, re.getMinutes());
}
// a new event, we won't have a maxReminders value available.)
for (ReminderEntry re : reminders) {
EventViewUtils.addReminder(mActivity, mScrollView, this, mReminderViews, mReminderMinuteValues, mReminderMinuteLabels, mReminderMethodValues, mReminderMethodLabels, re, Integer.MAX_VALUE, mReminderChangeListener);
}
EventViewUtils.updateAddReminderButton(mView, mReminderViews, mMaxReminders);
// TODO show unsupported reminder types in some fashion.
}
}
use of com.android.calendar.CalendarEventModel.ReminderEntry in project Etar-Calendar by Etar-Group.
the class Utils method readRemindersFromBundle.
/**
* @param bundle The incoming bundle that contains the reminder info.
* @return ArrayList<ReminderEntry> of the reminder minutes and methods.
*/
public static ArrayList<ReminderEntry> readRemindersFromBundle(Bundle bundle) {
ArrayList<ReminderEntry> reminders = null;
ArrayList<Integer> reminderMinutes = bundle.getIntegerArrayList(EventInfoFragment.BUNDLE_KEY_REMINDER_MINUTES);
ArrayList<Integer> reminderMethods = bundle.getIntegerArrayList(EventInfoFragment.BUNDLE_KEY_REMINDER_METHODS);
if (reminderMinutes == null || reminderMethods == null) {
if (reminderMinutes != null || reminderMethods != null) {
String nullList = (reminderMinutes == null ? "reminderMinutes" : "reminderMethods");
Log.d(TAG, String.format("Error resolving reminders: %s was null", nullList));
}
return null;
}
int numReminders = reminderMinutes.size();
if (numReminders == reminderMethods.size()) {
// Only if the size of the reminder minutes we've read in is
// the same as the size of the reminder methods. Otherwise,
// something went wrong with bundling them.
reminders = new ArrayList<ReminderEntry>(numReminders);
for (int reminder_i = 0; reminder_i < numReminders; reminder_i++) {
int minutes = reminderMinutes.get(reminder_i);
int method = reminderMethods.get(reminder_i);
reminders.add(ReminderEntry.valueOf(minutes, method));
}
} else {
Log.d(TAG, String.format("Error resolving reminders." + " Found %d reminderMinutes, but %d reminderMethods.", numReminders, reminderMethods.size()));
}
return reminders;
}
Aggregations