blob: c436f5a1bcc03bd3a2afa4eaa181e4c8de28a548 [file] [log] [blame]
The Android Open Source Project146de362009-03-03 19:32:18 -08001/*
2 * Copyright (C) 2008 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
17package com.android.calendar;
18
Erikfbce65e2010-08-16 12:43:13 -070019import com.android.calendar.event.EditEventHelper;
Michael Chan8a528ad2012-06-26 17:44:34 -070020import com.android.calendarcommon2.EventRecurrence;
Erikfbce65e2010-08-16 12:43:13 -070021
The Android Open Source Project146de362009-03-03 19:32:18 -080022import android.app.Activity;
23import android.app.AlertDialog;
Isaac Katzenelsonb0a313a2011-10-24 11:41:56 -070024import android.app.Dialog;
The Android Open Source Project146de362009-03-03 19:32:18 -080025import android.content.ContentUris;
26import android.content.ContentValues;
Michael Chan1251cb02010-07-01 14:50:50 -070027import android.content.Context;
The Android Open Source Project146de362009-03-03 19:32:18 -080028import android.content.DialogInterface;
RoboErike3e1f552011-09-27 13:33:50 -070029import android.content.res.Resources;
The Android Open Source Project146de362009-03-03 19:32:18 -080030import android.database.Cursor;
31import android.net.Uri;
RoboErika7c03902011-06-14 11:06:44 -070032import android.provider.CalendarContract;
33import android.provider.CalendarContract.Events;
Michael Chan66b20672010-12-20 13:50:28 -080034import android.text.TextUtils;
The Android Open Source Project146de362009-03-03 19:32:18 -080035import android.text.format.Time;
RoboErike3e1f552011-09-27 13:33:50 -070036import android.widget.ArrayAdapter;
The Android Open Source Project146de362009-03-03 19:32:18 -080037import android.widget.Button;
38
RoboErike3e1f552011-09-27 13:33:50 -070039import java.util.ArrayList;
40import java.util.Arrays;
41
The Android Open Source Project146de362009-03-03 19:32:18 -080042/**
43 * A helper class for deleting events. If a normal event is selected for
44 * deletion, then this pops up a confirmation dialog. If the user confirms,
45 * then the normal event is deleted.
Michael Chanad36a3c2010-01-27 18:03:25 -080046 *
The Android Open Source Project146de362009-03-03 19:32:18 -080047 * <p>
48 * If a repeating event is selected for deletion, then this pops up dialog
49 * asking if the user wants to delete just this one instance, or all the
50 * events in the series, or this event plus all following events. The user
51 * may also cancel the delete.
52 * </p>
Michael Chanad36a3c2010-01-27 18:03:25 -080053 *
The Android Open Source Project146de362009-03-03 19:32:18 -080054 * <p>
55 * To use this class, create an instance, passing in the parent activity
56 * and a boolean that determines if the parent activity should exit if the
57 * event is deleted. Then to use the instance, call one of the
58 * {@link delete()} methods on this class.
Michael Chanad36a3c2010-01-27 18:03:25 -080059 *
The Android Open Source Project146de362009-03-03 19:32:18 -080060 * An instance of this class may be created once and reused (by calling
61 * {@link #delete()} multiple times).
62 */
63public class DeleteEventHelper {
The Android Open Source Project146de362009-03-03 19:32:18 -080064 private final Activity mParent;
Michael Chan1251cb02010-07-01 14:50:50 -070065 private Context mContext;
Michael Chanad36a3c2010-01-27 18:03:25 -080066
The Android Open Source Project146de362009-03-03 19:32:18 -080067 private long mStartMillis;
68 private long mEndMillis;
Erik88c483a2010-06-21 11:27:38 -070069 private CalendarEventModel mModel;
Michael Chanad36a3c2010-01-27 18:03:25 -080070
The Android Open Source Project146de362009-03-03 19:32:18 -080071 /**
72 * If true, then call finish() on the parent activity when done.
73 */
74 private boolean mExitWhenDone;
Erik89ad0822011-01-18 15:55:17 -080075 // the runnable to execute when the delete is confirmed
76 private Runnable mCallback;
Michael Chanad36a3c2010-01-27 18:03:25 -080077
The Android Open Source Project146de362009-03-03 19:32:18 -080078 /**
79 * These are the corresponding indices into the array of strings
80 * "R.array.delete_repeating_labels" in the resource file.
81 */
Erikfbce65e2010-08-16 12:43:13 -070082 public static final int DELETE_SELECTED = 0;
83 public static final int DELETE_ALL_FOLLOWING = 1;
84 public static final int DELETE_ALL = 2;
Michael Chanad36a3c2010-01-27 18:03:25 -080085
The Android Open Source Project146de362009-03-03 19:32:18 -080086 private int mWhichDelete;
RoboErike3e1f552011-09-27 13:33:50 -070087 private ArrayList<Integer> mWhichIndex;
The Android Open Source Project146de362009-03-03 19:32:18 -080088 private AlertDialog mAlertDialog;
Isaac Katzenelsonb0a313a2011-10-24 11:41:56 -070089 private Dialog.OnDismissListener mDismissListener;
The Android Open Source Project146de362009-03-03 19:32:18 -080090
The Android Open Source Project146de362009-03-03 19:32:18 -080091 private String mSyncId;
Michael Chanad36a3c2010-01-27 18:03:25 -080092
Erik88c483a2010-06-21 11:27:38 -070093 private AsyncQueryService mService;
94
Isaac Katzenelsonb33cdf42011-10-14 18:15:18 -070095 private DeleteNotifyListener mDeleteStartedListener = null;
96
97 public interface DeleteNotifyListener {
98 public void onDeleteStarted();
99 }
100
101
Michael Chan1251cb02010-07-01 14:50:50 -0700102 public DeleteEventHelper(Context context, Activity parentActivity, boolean exitWhenDone) {
103 if (exitWhenDone && parentActivity == null) {
104 throw new IllegalArgumentException("parentActivity is required to exit when done");
105 }
106
107 mContext = context;
108 mParent = parentActivity;
Erik88c483a2010-06-21 11:27:38 -0700109 // TODO move the creation of this service out into the activity.
Michael Chan1251cb02010-07-01 14:50:50 -0700110 mService = new AsyncQueryService(mContext) {
Erik88c483a2010-06-21 11:27:38 -0700111 @Override
112 protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
113 if (cursor == null) {
114 return;
115 }
116 cursor.moveToFirst();
117 CalendarEventModel mModel = new CalendarEventModel();
118 EditEventHelper.setModelFromCursor(mModel, cursor);
119 cursor.close();
120 DeleteEventHelper.this.delete(mStartMillis, mEndMillis, mModel, mWhichDelete);
121 }
122 };
The Android Open Source Project146de362009-03-03 19:32:18 -0800123 mExitWhenDone = exitWhenDone;
124 }
Michael Chanad36a3c2010-01-27 18:03:25 -0800125
The Android Open Source Project146de362009-03-03 19:32:18 -0800126 public void setExitWhenDone(boolean exitWhenDone) {
127 mExitWhenDone = exitWhenDone;
128 }
129
130 /**
131 * This callback is used when a normal event is deleted.
132 */
133 private DialogInterface.OnClickListener mDeleteNormalDialogListener =
134 new DialogInterface.OnClickListener() {
135 public void onClick(DialogInterface dialog, int button) {
Isaac Katzenelsonb33cdf42011-10-14 18:15:18 -0700136 deleteStarted();
Erik88c483a2010-06-21 11:27:38 -0700137 long id = mModel.mId; // mCursor.getInt(mEventIndexId);
RoboErika7c03902011-06-14 11:06:44 -0700138 Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
Erik37960c02010-06-22 13:40:18 -0700139 mService.startDelete(mService.getNextToken(), null, uri, null, null, Utils.UNDO_DELAY);
Erik89ad0822011-01-18 15:55:17 -0800140 if (mCallback != null) {
141 mCallback.run();
142 }
The Android Open Source Project146de362009-03-03 19:32:18 -0800143 if (mExitWhenDone) {
144 mParent.finish();
145 }
146 }
147 };
148
149 /**
Erik83f7ce12010-04-27 10:06:41 -0700150 * This callback is used when an exception to an event is deleted
151 */
152 private DialogInterface.OnClickListener mDeleteExceptionDialogListener =
153 new DialogInterface.OnClickListener() {
154 public void onClick(DialogInterface dialog, int button) {
Isaac Katzenelsonb33cdf42011-10-14 18:15:18 -0700155 deleteStarted();
Erik83f7ce12010-04-27 10:06:41 -0700156 deleteExceptionEvent();
Erik89ad0822011-01-18 15:55:17 -0800157 if (mCallback != null) {
158 mCallback.run();
159 }
Erik83f7ce12010-04-27 10:06:41 -0700160 if (mExitWhenDone) {
161 mParent.finish();
162 }
163 }
164 };
165
166 /**
The Android Open Source Project146de362009-03-03 19:32:18 -0800167 * This callback is used when a list item for a repeating event is selected
168 */
169 private DialogInterface.OnClickListener mDeleteListListener =
170 new DialogInterface.OnClickListener() {
171 public void onClick(DialogInterface dialog, int button) {
RoboErike3e1f552011-09-27 13:33:50 -0700172 // set mWhichDelete to the delete type at that index
173 mWhichDelete = mWhichIndex.get(button);
Michael Chanad36a3c2010-01-27 18:03:25 -0800174
The Android Open Source Project146de362009-03-03 19:32:18 -0800175 // Enable the "ok" button now that the user has selected which
176 // events in the series to delete.
177 Button ok = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
178 ok.setEnabled(true);
179 }
180 };
181
182 /**
183 * This callback is used when a repeating event is deleted.
184 */
185 private DialogInterface.OnClickListener mDeleteRepeatingDialogListener =
186 new DialogInterface.OnClickListener() {
187 public void onClick(DialogInterface dialog, int button) {
Isaac Katzenelsonb33cdf42011-10-14 18:15:18 -0700188 deleteStarted();
The Android Open Source Project146de362009-03-03 19:32:18 -0800189 if (mWhichDelete != -1) {
190 deleteRepeatingEvent(mWhichDelete);
191 }
192 }
193 };
Michael Chanad36a3c2010-01-27 18:03:25 -0800194
The Android Open Source Project146de362009-03-03 19:32:18 -0800195 /**
196 * Does the required processing for deleting an event, which includes
197 * first popping up a dialog asking for confirmation (if the event is
198 * a normal event) or a dialog asking which events to delete (if the
199 * event is a repeating event). The "which" parameter is used to check
200 * the initial selection and is only used for repeating events. Set
201 * "which" to -1 to have nothing selected initially.
Michael Chanad36a3c2010-01-27 18:03:25 -0800202 *
The Android Open Source Project146de362009-03-03 19:32:18 -0800203 * @param begin the begin time of the event, in UTC milliseconds
204 * @param end the end time of the event, in UTC milliseconds
205 * @param eventId the event id
206 * @param which one of the values {@link DELETE_SELECTED},
207 * {@link DELETE_ALL_FOLLOWING}, {@link DELETE_ALL}, or -1
208 */
209 public void delete(long begin, long end, long eventId, int which) {
RoboErika7c03902011-06-14 11:06:44 -0700210 Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
Erik37960c02010-06-22 13:40:18 -0700211 mService.startQuery(mService.getNextToken(), null, uri, EditEventHelper.EVENT_PROJECTION,
212 null, null, null);
Erik88c483a2010-06-21 11:27:38 -0700213 mStartMillis = begin;
214 mEndMillis = end;
215 mWhichDelete = which;
The Android Open Source Project146de362009-03-03 19:32:18 -0800216 }
Michael Chanad36a3c2010-01-27 18:03:25 -0800217
Erik89ad0822011-01-18 15:55:17 -0800218 public void delete(long begin, long end, long eventId, int which, Runnable callback) {
219 delete(begin, end, eventId, which);
220 mCallback = callback;
221 }
222
The Android Open Source Project146de362009-03-03 19:32:18 -0800223 /**
224 * Does the required processing for deleting an event. This method
Erik88c483a2010-06-21 11:27:38 -0700225 * takes a {@link CalendarEventModel} object, which must have a valid
226 * uri for referencing the event in the database and have the required
227 * fields listed below.
The Android Open Source Project146de362009-03-03 19:32:18 -0800228 * The required fields for a normal event are:
Michael Chanad36a3c2010-01-27 18:03:25 -0800229 *
The Android Open Source Project146de362009-03-03 19:32:18 -0800230 * <ul>
231 * <li> Events._ID </li>
232 * <li> Events.TITLE </li>
233 * <li> Events.RRULE </li>
234 * </ul>
Michael Chanad36a3c2010-01-27 18:03:25 -0800235 *
The Android Open Source Project146de362009-03-03 19:32:18 -0800236 * The required fields for a repeating event include the above plus the
237 * following fields:
Michael Chanad36a3c2010-01-27 18:03:25 -0800238 *
The Android Open Source Project146de362009-03-03 19:32:18 -0800239 * <ul>
240 * <li> Events.ALL_DAY </li>
241 * <li> Events.CALENDAR_ID </li>
242 * <li> Events.DTSTART </li>
243 * <li> Events._SYNC_ID </li>
244 * <li> Events.EVENT_TIMEZONE </li>
245 * </ul>
Michael Chanad36a3c2010-01-27 18:03:25 -0800246 *
Erik88c483a2010-06-21 11:27:38 -0700247 * If the event no longer exists in the db this will still prompt
248 * the user but will return without modifying the db after the query
249 * returns.
250 *
The Android Open Source Project146de362009-03-03 19:32:18 -0800251 * @param begin the begin time of the event, in UTC milliseconds
252 * @param end the end time of the event, in UTC milliseconds
253 * @param cursor the database cursor containing the required fields
254 * @param which one of the values {@link DELETE_SELECTED},
255 * {@link DELETE_ALL_FOLLOWING}, {@link DELETE_ALL}, or -1
256 */
Erik88c483a2010-06-21 11:27:38 -0700257 public void delete(long begin, long end, CalendarEventModel model, int which) {
The Android Open Source Project146de362009-03-03 19:32:18 -0800258 mWhichDelete = which;
259 mStartMillis = begin;
260 mEndMillis = end;
Erik88c483a2010-06-21 11:27:38 -0700261 mModel = model;
262 mSyncId = model.mSyncId;
Michael Chanad36a3c2010-01-27 18:03:25 -0800263
The Android Open Source Project146de362009-03-03 19:32:18 -0800264 // If this is a repeating event, then pop up a dialog asking the
265 // user if they want to delete all of the repeating events or
266 // just some of them.
Erik88c483a2010-06-21 11:27:38 -0700267 String rRule = model.mRrule;
RoboErik28dab652011-07-21 15:08:39 -0700268 String originalEvent = model.mOriginalSyncId;
Michael Chan66b20672010-12-20 13:50:28 -0800269 if (TextUtils.isEmpty(rRule)) {
Michael Chan42ecaa32011-10-13 11:07:25 -0700270 AlertDialog dialog = new AlertDialog.Builder(mContext)
Erikf6b6fb32011-01-18 11:54:50 -0800271 .setMessage(R.string.delete_this_event_title)
272 .setIconAttribute(android.R.attr.alertDialogIcon)
273 .setNegativeButton(android.R.string.cancel, null).create();
Erik83f7ce12010-04-27 10:06:41 -0700274
275 if (originalEvent == null) {
276 // This is a normal event. Pop up a confirmation dialog.
277 dialog.setButton(DialogInterface.BUTTON_POSITIVE,
Michael Chan1251cb02010-07-01 14:50:50 -0700278 mContext.getText(android.R.string.ok),
Erik83f7ce12010-04-27 10:06:41 -0700279 mDeleteNormalDialogListener);
280 } else {
281 // This is an exception event. Pop up a confirmation dialog.
282 dialog.setButton(DialogInterface.BUTTON_POSITIVE,
Michael Chan1251cb02010-07-01 14:50:50 -0700283 mContext.getText(android.R.string.ok),
Erik83f7ce12010-04-27 10:06:41 -0700284 mDeleteExceptionDialogListener);
285 }
Isaac Katzenelsonb0a313a2011-10-24 11:41:56 -0700286 dialog.setOnDismissListener(mDismissListener);
Erik83f7ce12010-04-27 10:06:41 -0700287 dialog.show();
Isaac Katzenelsonb0a313a2011-10-24 11:41:56 -0700288 mAlertDialog = dialog;
The Android Open Source Project146de362009-03-03 19:32:18 -0800289 } else {
290 // This is a repeating event. Pop up a dialog asking which events
291 // to delete.
RoboErike3e1f552011-09-27 13:33:50 -0700292 Resources res = mContext.getResources();
293 ArrayList<String> labelArray = new ArrayList<String>(Arrays.asList(res
294 .getStringArray(R.array.delete_repeating_labels)));
295 // asList doesn't like int[] so creating it manually.
296 int[] labelValues = res.getIntArray(R.array.delete_repeating_values);
297 ArrayList<Integer> labelIndex = new ArrayList<Integer>();
298 for (int val : labelValues) {
299 labelIndex.add(val);
The Android Open Source Project146de362009-03-03 19:32:18 -0800300 }
RoboErike3e1f552011-09-27 13:33:50 -0700301
302 if (mSyncId == null) {
303 // remove 'Only this event' item
304 labelArray.remove(0);
305 labelIndex.remove(0);
306 if (!model.mIsOrganizer) {
307 // remove 'This and future events' item
308 labelArray.remove(0);
309 labelIndex.remove(0);
310 }
311 } else if (!model.mIsOrganizer) {
312 // remove 'This and future events' item
313 labelArray.remove(1);
314 labelIndex.remove(1);
315 }
316 if (which != -1) {
317 // transform the which to the index in the array
318 which = labelIndex.indexOf(which);
319 }
320 mWhichIndex = labelIndex;
321 ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,
322 android.R.layout.simple_list_item_single_choice, labelArray);
Michael Chan42ecaa32011-10-13 11:07:25 -0700323 AlertDialog dialog = new AlertDialog.Builder(mContext)
Mindy Pereira512c8cf2012-05-10 10:35:29 -0700324 .setTitle(
325 mContext.getString(R.string.delete_recurring_event_title,model.mTitle))
Erikf6b6fb32011-01-18 11:54:50 -0800326 .setIconAttribute(android.R.attr.alertDialogIcon)
RoboErike3e1f552011-09-27 13:33:50 -0700327 .setSingleChoiceItems(adapter, which, mDeleteListListener)
Erikf6b6fb32011-01-18 11:54:50 -0800328 .setPositiveButton(android.R.string.ok, mDeleteRepeatingDialogListener)
329 .setNegativeButton(android.R.string.cancel, null).show();
Isaac Katzenelsonb0a313a2011-10-24 11:41:56 -0700330 dialog.setOnDismissListener(mDismissListener);
The Android Open Source Project146de362009-03-03 19:32:18 -0800331 mAlertDialog = dialog;
Michael Chanad36a3c2010-01-27 18:03:25 -0800332
The Android Open Source Project3cfe2e52009-03-13 13:04:24 -0700333 if (which == -1) {
334 // Disable the "Ok" button until the user selects which events
335 // to delete.
336 Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
337 ok.setEnabled(false);
338 }
The Android Open Source Project146de362009-03-03 19:32:18 -0800339 }
340 }
Michael Chanad36a3c2010-01-27 18:03:25 -0800341
Erik83f7ce12010-04-27 10:06:41 -0700342 private void deleteExceptionEvent() {
Erik88c483a2010-06-21 11:27:38 -0700343 long id = mModel.mId; // mCursor.getInt(mEventIndexId);
Erik83f7ce12010-04-27 10:06:41 -0700344
345 // update a recurrence exception by setting its status to "canceled"
346 ContentValues values = new ContentValues();
347 values.put(Events.STATUS, Events.STATUS_CANCELED);
348
RoboErika7c03902011-06-14 11:06:44 -0700349 Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
Erik37960c02010-06-22 13:40:18 -0700350 mService.startUpdate(mService.getNextToken(), null, uri, values, null, null,
351 Utils.UNDO_DELAY);
Erik83f7ce12010-04-27 10:06:41 -0700352 }
353
The Android Open Source Project146de362009-03-03 19:32:18 -0800354 private void deleteRepeatingEvent(int which) {
Erik88c483a2010-06-21 11:27:38 -0700355 String rRule = mModel.mRrule;
356 boolean allDay = mModel.mAllDay;
357 long dtstart = mModel.mStart;
358 long id = mModel.mId; // mCursor.getInt(mEventIndexId);
The Android Open Source Project146de362009-03-03 19:32:18 -0800359
The Android Open Source Project146de362009-03-03 19:32:18 -0800360 switch (which) {
Erik8d69cd02010-06-23 17:32:51 -0700361 case DELETE_SELECTED: {
The Android Open Source Project146de362009-03-03 19:32:18 -0800362 // If we are deleting the first event in the series, then
363 // instead of creating a recurrence exception, just change
364 // the start time of the recurrence.
365 if (dtstart == mStartMillis) {
366 // TODO
367 }
Michael Chanad36a3c2010-01-27 18:03:25 -0800368
The Android Open Source Project146de362009-03-03 19:32:18 -0800369 // Create a recurrence exception by creating a new event
370 // with the status "cancelled".
371 ContentValues values = new ContentValues();
Michael Chanad36a3c2010-01-27 18:03:25 -0800372
The Android Open Source Project146de362009-03-03 19:32:18 -0800373 // The title might not be necessary, but it makes it easier
374 // to find this entry in the database when there is a problem.
Erik88c483a2010-06-21 11:27:38 -0700375 String title = mModel.mTitle;
The Android Open Source Project146de362009-03-03 19:32:18 -0800376 values.put(Events.TITLE, title);
Michael Chanad36a3c2010-01-27 18:03:25 -0800377
Erik88c483a2010-06-21 11:27:38 -0700378 String timezone = mModel.mTimezone;
379 long calendarId = mModel.mCalendarId;
The Android Open Source Project146de362009-03-03 19:32:18 -0800380 values.put(Events.EVENT_TIMEZONE, timezone);
381 values.put(Events.ALL_DAY, allDay ? 1 : 0);
RoboErikfcba1f12011-04-08 11:43:47 -0700382 values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0);
The Android Open Source Project146de362009-03-03 19:32:18 -0800383 values.put(Events.CALENDAR_ID, calendarId);
384 values.put(Events.DTSTART, mStartMillis);
385 values.put(Events.DTEND, mEndMillis);
RoboErik0e1e6242011-05-05 15:25:02 -0700386 values.put(Events.ORIGINAL_SYNC_ID, mSyncId);
RoboErike0c55802011-08-09 16:34:31 -0700387 values.put(Events.ORIGINAL_ID, id);
The Android Open Source Project146de362009-03-03 19:32:18 -0800388 values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis);
389 values.put(Events.STATUS, Events.STATUS_CANCELED);
Michael Chanad36a3c2010-01-27 18:03:25 -0800390
Erik37960c02010-06-22 13:40:18 -0700391 mService.startInsert(mService.getNextToken(), null, Events.CONTENT_URI, values,
392 Utils.UNDO_DELAY);
The Android Open Source Project146de362009-03-03 19:32:18 -0800393 break;
394 }
395 case DELETE_ALL: {
RoboErika7c03902011-06-14 11:06:44 -0700396 Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
Erik37960c02010-06-22 13:40:18 -0700397 mService.startDelete(mService.getNextToken(), null, uri, null, null,
398 Utils.UNDO_DELAY);
The Android Open Source Project146de362009-03-03 19:32:18 -0800399 break;
400 }
401 case DELETE_ALL_FOLLOWING: {
402 // If we are deleting the first event in the series and all
403 // following events, then delete them all.
404 if (dtstart == mStartMillis) {
RoboErika7c03902011-06-14 11:06:44 -0700405 Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
Erik37960c02010-06-22 13:40:18 -0700406 mService.startDelete(mService.getNextToken(), null, uri, null, null,
407 Utils.UNDO_DELAY);
The Android Open Source Project146de362009-03-03 19:32:18 -0800408 break;
409 }
Michael Chanad36a3c2010-01-27 18:03:25 -0800410
The Android Open Source Project146de362009-03-03 19:32:18 -0800411 // Modify the repeating event to end just before this event time
412 EventRecurrence eventRecurrence = new EventRecurrence();
413 eventRecurrence.parse(rRule);
414 Time date = new Time();
415 if (allDay) {
416 date.timezone = Time.TIMEZONE_UTC;
417 }
418 date.set(mStartMillis);
419 date.second--;
420 date.normalize(false);
Michael Chanad36a3c2010-01-27 18:03:25 -0800421
The Android Open Source Project146de362009-03-03 19:32:18 -0800422 // Google calendar seems to require the UNTIL string to be
423 // in UTC.
424 date.switchTimezone(Time.TIMEZONE_UTC);
425 eventRecurrence.until = date.format2445();
Michael Chanad36a3c2010-01-27 18:03:25 -0800426
The Android Open Source Project146de362009-03-03 19:32:18 -0800427 ContentValues values = new ContentValues();
428 values.put(Events.DTSTART, dtstart);
429 values.put(Events.RRULE, eventRecurrence.toString());
RoboErika7c03902011-06-14 11:06:44 -0700430 Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
Erik37960c02010-06-22 13:40:18 -0700431 mService.startUpdate(mService.getNextToken(), null, uri, values, null, null,
432 Utils.UNDO_DELAY);
The Android Open Source Project146de362009-03-03 19:32:18 -0800433 break;
434 }
435 }
Erik89ad0822011-01-18 15:55:17 -0800436 if (mCallback != null) {
437 mCallback.run();
438 }
The Android Open Source Project146de362009-03-03 19:32:18 -0800439 if (mExitWhenDone) {
440 mParent.finish();
441 }
442 }
Isaac Katzenelsonb33cdf42011-10-14 18:15:18 -0700443
444 public void setDeleteNotificationListener(DeleteNotifyListener listener) {
445 mDeleteStartedListener = listener;
446 }
447
448 private void deleteStarted() {
449 if (mDeleteStartedListener != null) {
450 mDeleteStartedListener.onDeleteStarted();
451 }
452 }
Isaac Katzenelsonb0a313a2011-10-24 11:41:56 -0700453
454 public void setOnDismissListener(Dialog.OnDismissListener listener) {
455 if (mAlertDialog != null) {
456 mAlertDialog.setOnDismissListener(listener);
457 }
458 mDismissListener = listener;
459 }
460
461 public void dismissAlertDialog() {
462 if (mAlertDialog != null) {
463 mAlertDialog.dismiss();
464 }
465 }
The Android Open Source Project146de362009-03-03 19:32:18 -0800466}