Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 09a250c5 authored by Jonas Häusler's avatar Jonas Häusler Committed by Michael Bestas
Browse files

allow editing calendar on existing events

Change-Id: I79a02dfa71447c79dba060a29f455ec319d26239
parent a041991f
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -111,9 +111,6 @@ public class CalendarEventModel implements Serializable {
    public boolean mOrganizerCanRespond = false;
    public int mCalendarAccessLevel = Calendars.CAL_ACCESS_CONTRIBUTOR;
    public int mEventStatus = Events.STATUS_CONFIRMED;
    // The model can't be updated with a calendar cursor until it has been
    // updated with an event cursor.
    public boolean mModelUpdatedWithEventCursor;
    public int mAccessLevel = 0;
    public ArrayList<ReminderEntry> mReminders;
    public ArrayList<ReminderEntry> mDefaultReminders;
@@ -291,7 +288,6 @@ public class CalendarEventModel implements Serializable {
        mEventStatus = Events.STATUS_CONFIRMED;
        mOrganizerCanRespond = false;
        mCalendarAccessLevel = Calendars.CAL_ACCESS_CONTRIBUTOR;
        mModelUpdatedWithEventCursor = false;
        mCalendarAllowedReminders = null;
        mCalendarAllowedAttendeeTypes = null;
        mCalendarAllowedAvailability = null;
@@ -350,7 +346,6 @@ public class CalendarEventModel implements Serializable {
        result = prime * result + (mGuestsCanModify ? 1231 : 1237);
        result = prime * result + (mGuestsCanSeeGuests ? 1231 : 1237);
        result = prime * result + (mOrganizerCanRespond ? 1231 : 1237);
        result = prime * result + (mModelUpdatedWithEventCursor ? 1231 : 1237);
        result = prime * result + mCalendarAccessLevel;
        result = prime * result + (mHasAlarm ? 1231 : 1237);
        result = prime * result + (mHasAttendeeData ? 1231 : 1237);
@@ -615,9 +610,6 @@ public class CalendarEventModel implements Serializable {
        if (mCalendarAccessLevel != originalModel.mCalendarAccessLevel) {
            return false;
        }
        if (mModelUpdatedWithEventCursor != originalModel.mModelUpdatedWithEventCursor) {
            return false;
        }
        if (mHasAlarm != originalModel.mHasAlarm) {
            return false;
        }
+52 −21
Original line number Diff line number Diff line
@@ -99,25 +99,7 @@ public class DeleteEventHelper {
            new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int button) {
            deleteStarted();
            long id = mModel.mId; // mCursor.getInt(mEventIndexId);

            // If this event is part of a local calendar, really remove it from the database
            //
            // "There are two versions of delete: as an app and as a sync adapter.
            // An app delete will set the deleted column on an event and remove all instances of that event.
            // A sync adapter delete will remove the event from the database and all associated data."
            // from https://developer.android.com/reference/android/provider/CalendarContract.Events
            boolean isLocal = mModel.mSyncAccountType.equals(CalendarContract.ACCOUNT_TYPE_LOCAL);
            Uri deleteContentUri = isLocal ? CalendarRepository.asLocalCalendarSyncAdapter(mModel.mSyncAccountName, Events.CONTENT_URI) : Events.CONTENT_URI;

            Uri uri = ContentUris.withAppendedId(deleteContentUri, id);
            mService.startDelete(mService.getNextToken(), null, uri, null, null, Utils.UNDO_DELAY);
            if (mCallback != null) {
                mCallback.run();
            }
            if (mExitWhenDone) {
                mParent.finish();
            }
            deleteNormalEvent();
        }
    };
    /**
@@ -164,7 +146,7 @@ public class DeleteEventHelper {
        }
    };

    public DeleteEventHelper(Context context, Activity parentActivity, boolean exitWhenDone) {
    public DeleteEventHelper(Context context, Activity parentActivity, boolean exitWhenDone, boolean prompt) {
        if (exitWhenDone && parentActivity == null) {
            throw new IllegalArgumentException("parentActivity is required to exit when done");
        }
@@ -182,12 +164,20 @@ public class DeleteEventHelper {
                CalendarEventModel mModel = new CalendarEventModel();
                EditEventHelper.setModelFromCursor(mModel, cursor, mContext);
                cursor.close();
                DeleteEventHelper.this.delete(mStartMillis, mEndMillis, mModel, mWhichDelete);
                if (prompt) {
                    delete(mStartMillis, mEndMillis, mModel, mWhichDelete);
                } else {
                    deleteUnprompted(mStartMillis, mEndMillis, mModel, mWhichDelete);
                }
            }
        };
        mExitWhenDone = exitWhenDone;
    }

    public DeleteEventHelper(Context context, Activity parentActivity, boolean exitWhenDone) {
        this(context, parentActivity, exitWhenDone, true);
    }

    public void setExitWhenDone(boolean exitWhenDone) {
        mExitWhenDone = exitWhenDone;
    }
@@ -339,6 +329,47 @@ public class DeleteEventHelper {
        }
    }

    private void deleteUnprompted(long begin, long end, CalendarEventModel model, int which) {
        mWhichDelete = which;
        mStartMillis = begin;
        mEndMillis = end;
        mModel = model;
        mSyncId = model.mSyncId;

        if (TextUtils.isEmpty(model.mRrule)) {
            String originalEvent = model.mOriginalSyncId;
            if (originalEvent == null) {
                deleteNormalEvent();
            } else {
                deleteExceptionEvent();
            }
        } else {
            deleteRepeatingEvent(which);
        }
    }

    private void deleteNormalEvent() {
        long id = mModel.mId; // mCursor.getInt(mEventIndexId);

        // If this event is part of a local calendar, really remove it from the database
        //
        // "There are two versions of delete: as an app and as a sync adapter.
        // An app delete will set the deleted column on an event and remove all instances of that event.
        // A sync adapter delete will remove the event from the database and all associated data."
        // from https://developer.android.com/reference/android/provider/CalendarContract.Events
        boolean isLocal = mModel.mSyncAccountType.equals(CalendarContract.ACCOUNT_TYPE_LOCAL);
        Uri deleteContentUri = isLocal ? CalendarRepository.asLocalCalendarSyncAdapter(mModel.mSyncAccountName, Events.CONTENT_URI) : Events.CONTENT_URI;

        Uri uri = ContentUris.withAppendedId(deleteContentUri, id);
        mService.startDelete(mService.getNextToken(), null, uri, null, null, Utils.UNDO_DELAY);
        if (mCallback != null) {
            mCallback.run();
        }
        if (mExitWhenDone) {
            mParent.finish();
        }
    }

    private void deleteExceptionEvent() {
        long id = mModel.mId; // mCursor.getInt(mEventIndexId);

+33 −49
Original line number Diff line number Diff line
@@ -308,7 +308,7 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
        super.onAttach(activity);
        mActivity = (AppCompatActivity) activity;

        mHelper = new EditEventHelper(activity, null);
        mHelper = new EditEventHelper(activity);
        mHandler = new QueryHandler(activity.getContentResolver());
        mModel = new CalendarEventModel(activity, mIntent);
        mInputMethodManager = (InputMethodManager)
@@ -753,12 +753,10 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
                    }

                    // TOKEN_CALENDARS
                    String[] selArgs = {
                            Long.toString(mModel.mCalendarId)
                    };
                    mHandler.startQuery(TOKEN_CALENDARS, null, Calendars.CONTENT_URI,
                            EditEventHelper.CALENDARS_PROJECTION, EditEventHelper.CALENDARS_WHERE,
                            selArgs /* selection args */, null /* sort order */);
                            EditEventHelper.CALENDARS_PROJECTION,
                            EditEventHelper.CALENDARS_WHERE_WRITEABLE_VISIBLE,
                            null /* selection args */, null /* sort order */);

                    // TOKEN_COLORS
                    mHandler.startQuery(TOKEN_COLORS, null, Colors.CONTENT_URI,
@@ -770,9 +768,7 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
                            mModel.mCalendarAccountName,
                            mModel.mCalendarAccountType
                    );
                    selArgs = new String[]{
                            Long.toString(eventId)
                    };
                    String[] selArgs = new String[]{ Long.toString(eventId) };
                    mHandler.startQuery(TOKEN_EXTENDED, null, extendedPropUri,
                            EditEventHelper.EXTENDED_PROJECTION,
                            EditEventHelper.EXTENDED_WHERE_EVENT, selArgs, null);
@@ -780,7 +776,7 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
                    setModelIfDone(TOKEN_EVENT);
                    break;
                case TOKEN_ATTENDEES:
                    try {
                    try (cursor) {
                        while (cursor.moveToNext()) {
                            String name = cursor.getString(EditEventHelper.ATTENDEES_INDEX_NAME);
                            String email = cursor.getString(EditEventHelper.ATTENDEES_INDEX_EMAIL);
@@ -824,14 +820,12 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
                            mModel.addAttendee(attendee);
                            mOriginalModel.addAttendee(attendee);
                        }
                    } finally {
                        cursor.close();
                    }

                    setModelIfDone(TOKEN_ATTENDEES);
                    break;
                case TOKEN_REMINDERS:
                    try {
                    try (cursor) {
                        // Add all reminders to the models
                        while (cursor.moveToNext()) {
                            int minutes = cursor.getInt(EditEventHelper.REMINDERS_INDEX_MINUTES);
@@ -844,34 +838,27 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
                        // Sort appropriately for display
                        Collections.sort(mModel.mReminders);
                        Collections.sort(mOriginalModel.mReminders);
                    } finally {
                        cursor.close();
                    }

                    setModelIfDone(TOKEN_REMINDERS);
                    break;
                case TOKEN_CALENDARS:
                    try {
                        if (mModel.mId == -1) {
                            // Populate Calendar spinner only if no event id is set.
                    try (cursor) {
                        MatrixCursor matrixCursor = Utils.matrixCursorFromCursor(cursor);
                        if (DEBUG) {
                                Log.d(TAG, "onQueryComplete: setting cursor with "
                                        + matrixCursor.getCount() + " calendars");
                            Log.d(TAG, "onQueryComplete: setting cursor with " + matrixCursor.getCount() + " calendars");
                        }
                            mView.setCalendarsCursor(matrixCursor, isAdded() && isResumed(),
                                    mCalendarId);
                        } else {
                        if (mModel.mId != -1) {
                            // Populate model for an existing event
                            EditEventHelper.setModelFromCalendarCursor(mModel, cursor, activity);
                            EditEventHelper.setModelFromCalendarCursor(mOriginalModel, cursor, activity);
                        }
                    } finally {
                        cursor.close();
                        mView.setCalendarsCursor(matrixCursor, isAdded() && isResumed(), mModel.mCalendarId);
                    }
                    setModelIfDone(TOKEN_CALENDARS);
                    break;
                case TOKEN_COLORS:
                    try (cursor) {
                        if (cursor.moveToFirst()) {
                            EventColorCache cache = new EventColorCache();
                            do {
@@ -888,11 +875,8 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor
                            cache.sortPalettes(new HsvColorComparator());

                            mModel.mEventColorCache = cache;
                        mView.mColorPickerNewEvent.setOnClickListener(mOnColorPickerClicked);
                        mView.mColorPickerExistingEvent.setOnClickListener(mOnColorPickerClicked);
                            mView.mColorPicker.setOnClickListener(mOnColorPickerClicked);
                        }
                    if (cursor != null) {
                        cursor.close();
                    }

                    // If the account name/type is null, the calendar event colors cannot be
+21 −47
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import com.android.calendar.AsyncQueryService;
import com.android.calendar.CalendarEventModel;
import com.android.calendar.CalendarEventModel.Attendee;
import com.android.calendar.CalendarEventModel.ReminderEntry;
import com.android.calendar.DeleteEventHelper;
import com.android.calendar.Utils;
import com.android.calendarcommon2.DateException;
import com.android.calendarcommon2.EventRecurrence;
@@ -157,6 +158,8 @@ public class EditEventHelper {

    private final AsyncQueryService mService;

    private final DeleteEventHelper deleteEventHelper;

    // This allows us to flag the event if something is wrong with it, right now
    // if an uri is provided for an event that doesn't exist in the db.
    protected boolean mEventOk = true;
@@ -266,11 +269,7 @@ public class EditEventHelper {

    public EditEventHelper(Context context) {
        mService = ((AbstractCalendarActivity)context).getAsyncQueryService();
    }

    public EditEventHelper(Context context, CalendarEventModel model) {
        this(context);
        // TODO: Remove unnecessary constructor.
        deleteEventHelper = new DeleteEventHelper(context, null, false, false);
    }

    /**
@@ -307,7 +306,7 @@ public class EditEventHelper {
            Log.e(TAG, "Attempted to save invalid model.");
            return false;
        }
        if (originalModel != null && !isSameEvent(model, originalModel)) {
        if (originalModel != null && originalModel.mId != model.mId) {
            Log.e(TAG, "Attempted to update existing event but models didn't refer to the same "
                    + "event.");
            return false;
@@ -316,6 +315,19 @@ public class EditEventHelper {
            return false;
        }

        // check if the event calendar changed
        if (originalModel != null && originalModel.mCalendarId != model.mCalendarId) {
            // delete event from original calendar and recreate in new calendar with new id
            deleteEventHelper.delete(model.mStart, model.mEnd, model.mId, modifyWhich);

            model.mId = -1;
            model.mUri = null;
            model.mSyncId = null;
            model.mOriginalSyncId = null;
            model.mSyncAccountName = null;
            model.mSyncAccountType = null;
        }

        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        int eventIdIndex = -1;

@@ -447,7 +459,7 @@ public class EditEventHelper {
        if (newEvent) {
            saveRemindersWithBackRef(ops, eventIdIndex, reminders, originalReminders,
                    forceSaveReminders);
        } else if (uri != null) {
        } else {
            long eventId = ContentUris.parseId(uri);
            saveReminders(ops, eventId, reminders, originalReminders, forceSaveReminders);
        }
@@ -503,9 +515,7 @@ public class EditEventHelper {
                }
                ops.add(b.build());
            }
        } else if (hasAttendeeData &&
                model.mSelfAttendeeStatus != originalModel.mSelfAttendeeStatus &&
                model.mOwnerAttendeeId != -1) {
        } else if (hasAttendeeData && model.mSelfAttendeeStatus != originalModel.mSelfAttendeeStatus) {
            if (DEBUG) {
                Log.d(TAG, "Setting attendee status to " + model.mSelfAttendeeStatus);
            }
@@ -518,9 +528,7 @@ public class EditEventHelper {
            ops.add(b.build());
        }

        // TODO: is this the right test? this currently checks if this is
        // a new event or an existing event. or is this a paranoia check?
        if (hasAttendeeData && (newEvent || uri != null)) {
        if (hasAttendeeData) {
            String attendees = model.getAttendeesString();
            String originalAttendeesString;
            if (originalModel != null) {
@@ -545,7 +553,6 @@ public class EditEventHelper {
                // new events (being inserted into the Events table) won't
                // have any existing attendees.
                if (!newEvent) {
                    removedAttendees.clear();
                    HashMap<String, Attendee> originalAttendees = originalModel.mAttendeesList;
                    for (String originalEmail : originalAttendees.keySet()) {
                        if (newAttendees.containsKey(originalEmail)) {
@@ -604,7 +611,6 @@ public class EditEventHelper {
            }
        }


        mService.startBatch(mService.getNextToken(), null, android.provider.CalendarContract.AUTHORITY, ops,
                Utils.UNDO_DELAY);

@@ -826,30 +832,6 @@ public class EditEventHelper {
        return newRrule;
    }

    /**
     * Compares two models to ensure that they refer to the same event. This is
     * a safety check to make sure an updated event model refers to the same
     * event as the original model. If the original model is null then this is a
     * new event or we're forcing an overwrite so we return true in that case.
     * The important identifiers are the Calendar Id and the Event Id.
     *
     * @return
     */
    public static boolean isSameEvent(CalendarEventModel model, CalendarEventModel originalModel) {
        if (originalModel == null) {
            return true;
        }

        if (model.mCalendarId != originalModel.mCalendarId) {
            return false;
        }
        if (model.mId != originalModel.mId) {
            return false;
        }

        return true;
    }

    /**
     * Saves the reminders, if they changed. Returns true if operations to
     * update the database were added.
@@ -1137,8 +1119,6 @@ public class EditEventHelper {
        } else {
            model.mEnd = cursor.getLong(EVENT_INDEX_DTEND);
        }

        model.mModelUpdatedWithEventCursor = true;
    }

    /**
@@ -1160,12 +1140,6 @@ public class EditEventHelper {
            return false;
        }

        if (!model.mModelUpdatedWithEventCursor) {
            Log.wtf(TAG,
                    "Can't update model with a Calendar cursor until it has seen an Event cursor.");
            return false;
        }

        cursor.moveToPosition(-1);
        while (cursor.moveToNext()) {
            if (model.mCalendarId != cursor.getInt(CALENDARS_INDEX_ID)) {
+21 −88

File changed.

Preview size limit exceeded, changes collapsed.

Loading