Search in sources :

Example 1 with ReminderEntry

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;
}
Also used : ContentValues(android.content.ContentValues) ContentProviderOperation(android.content.ContentProviderOperation) ReminderEntry(com.android.calendar.CalendarEventModel.ReminderEntry)

Example 2 with ReminderEntry

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;
}
Also used : ContentValues(android.content.ContentValues) ContentProviderOperation(android.content.ContentProviderOperation) ArrayList(java.util.ArrayList) ReminderEntry(com.android.calendar.CalendarEventModel.ReminderEntry) Uri(android.net.Uri) Attendee(com.android.calendar.CalendarEventModel.Attendee) LinkedList(java.util.LinkedList)

Example 3 with ReminderEntry

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);
}
Also used : ArrayList(java.util.ArrayList) ReminderEntry(com.android.calendar.CalendarEventModel.ReminderEntry)

Example 4 with ReminderEntry

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.
    }
}
Also used : ReminderEntry(com.android.calendar.CalendarEventModel.ReminderEntry) LinearLayout(android.widget.LinearLayout)

Example 5 with ReminderEntry

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;
}
Also used : ReminderEntry(com.android.calendar.CalendarEventModel.ReminderEntry) SpannableString(android.text.SpannableString)

Aggregations

ReminderEntry (com.android.calendar.CalendarEventModel.ReminderEntry)9 ArrayList (java.util.ArrayList)4 ContentProviderOperation (android.content.ContentProviderOperation)3 ContentValues (android.content.ContentValues)3 Resources (android.content.res.Resources)2 Uri (android.net.Uri)2 LinearLayout (android.widget.LinearLayout)2 FragmentManager (android.app.FragmentManager)1 FragmentTransaction (android.app.FragmentTransaction)1 Intent (android.content.Intent)1 ActionBar (android.support.v7.app.ActionBar)1 SpannableString (android.text.SpannableString)1 Spinner (android.widget.Spinner)1 CalendarEventModel (com.android.calendar.CalendarEventModel)1 Attendee (com.android.calendar.CalendarEventModel.Attendee)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1