1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/* 2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License. 6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at 7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and 14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License. 15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 17146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpackage com.android.calendar; 18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 19fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.event.EditEventHelper; 208a528adbba5d46fe0d566f474bc3be190511198eMichael Chanimport com.android.calendarcommon2.EventRecurrence; 21fbce65e53c7a111955f638db5bf8bee35381e5b7Erik 22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.app.Activity; 23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.app.AlertDialog; 24b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelsonimport android.app.Dialog; 25146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.ContentUris; 26146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.ContentValues; 271251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chanimport android.content.Context; 28146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.DialogInterface; 29e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErikimport android.content.res.Resources; 30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor; 31146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.net.Uri; 32a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract; 33a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events; 3466b2067e0a389180f909eb0a528bea5f6becca23Michael Chanimport android.text.TextUtils; 35146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time; 36e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErikimport android.widget.ArrayAdapter; 37146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.Button; 38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 39e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErikimport java.util.ArrayList; 40e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErikimport java.util.Arrays; 41e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik 42146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/** 43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * A helper class for deleting events. If a normal event is selected for 44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * deletion, then this pops up a confirmation dialog. If the user confirms, 45146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * then the normal event is deleted. 46ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 47146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <p> 48146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * If a repeating event is selected for deletion, then this pops up dialog 49146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * asking if the user wants to delete just this one instance, or all the 50146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * events in the series, or this event plus all following events. The user 51146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * may also cancel the delete. 52146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * </p> 53ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 54146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <p> 55146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * To use this class, create an instance, passing in the parent activity 56146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * and a boolean that determines if the parent activity should exit if the 57146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * event is deleted. Then to use the instance, call one of the 58146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * {@link delete()} methods on this class. 59ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 60146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * An instance of this class may be created once and reused (by calling 61146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * {@link #delete()} multiple times). 62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 63146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class DeleteEventHelper { 64146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private final Activity mParent; 651251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan private Context mContext; 66ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private long mStartMillis; 68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private long mEndMillis; 6988c483a0189cbe7132330cb1b563f07326f3bcf9Erik private CalendarEventModel mModel; 70ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 71146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * If true, then call finish() on the parent activity when done. 73146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private boolean mExitWhenDone; 7589ad0822f104015625f4ca88bfdf5c1d522b6e74Erik // the runnable to execute when the delete is confirmed 7689ad0822f104015625f4ca88bfdf5c1d522b6e74Erik private Runnable mCallback; 77ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 78146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 79146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * These are the corresponding indices into the array of strings 80146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * "R.array.delete_repeating_labels" in the resource file. 81146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 82fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static final int DELETE_SELECTED = 0; 83fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static final int DELETE_ALL_FOLLOWING = 1; 84fbce65e53c7a111955f638db5bf8bee35381e5b7Erik public static final int DELETE_ALL = 2; 85ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 86146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private int mWhichDelete; 87e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik private ArrayList<Integer> mWhichIndex; 88146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private AlertDialog mAlertDialog; 89b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson private Dialog.OnDismissListener mDismissListener; 90146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 91146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private String mSyncId; 92ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 9388c483a0189cbe7132330cb1b563f07326f3bcf9Erik private AsyncQueryService mService; 9488c483a0189cbe7132330cb1b563f07326f3bcf9Erik 95b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson private DeleteNotifyListener mDeleteStartedListener = null; 96b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 97b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson public interface DeleteNotifyListener { 98b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson public void onDeleteStarted(); 99b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson } 100b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 101b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 1021251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan public DeleteEventHelper(Context context, Activity parentActivity, boolean exitWhenDone) { 1031251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan if (exitWhenDone && parentActivity == null) { 1041251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan throw new IllegalArgumentException("parentActivity is required to exit when done"); 1051251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan } 1061251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan 1071251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan mContext = context; 1081251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan mParent = parentActivity; 10988c483a0189cbe7132330cb1b563f07326f3bcf9Erik // TODO move the creation of this service out into the activity. 1101251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan mService = new AsyncQueryService(mContext) { 11188c483a0189cbe7132330cb1b563f07326f3bcf9Erik @Override 11288c483a0189cbe7132330cb1b563f07326f3bcf9Erik protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 11388c483a0189cbe7132330cb1b563f07326f3bcf9Erik if (cursor == null) { 11488c483a0189cbe7132330cb1b563f07326f3bcf9Erik return; 11588c483a0189cbe7132330cb1b563f07326f3bcf9Erik } 11688c483a0189cbe7132330cb1b563f07326f3bcf9Erik cursor.moveToFirst(); 11788c483a0189cbe7132330cb1b563f07326f3bcf9Erik CalendarEventModel mModel = new CalendarEventModel(); 11888c483a0189cbe7132330cb1b563f07326f3bcf9Erik EditEventHelper.setModelFromCursor(mModel, cursor); 11988c483a0189cbe7132330cb1b563f07326f3bcf9Erik cursor.close(); 12088c483a0189cbe7132330cb1b563f07326f3bcf9Erik DeleteEventHelper.this.delete(mStartMillis, mEndMillis, mModel, mWhichDelete); 12188c483a0189cbe7132330cb1b563f07326f3bcf9Erik } 12288c483a0189cbe7132330cb1b563f07326f3bcf9Erik }; 123146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mExitWhenDone = exitWhenDone; 124146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 125ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 126146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setExitWhenDone(boolean exitWhenDone) { 127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mExitWhenDone = exitWhenDone; 128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * This callback is used when a normal event is deleted. 132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 133146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private DialogInterface.OnClickListener mDeleteNormalDialogListener = 134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project new DialogInterface.OnClickListener() { 135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void onClick(DialogInterface dialog, int button) { 136b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson deleteStarted(); 13788c483a0189cbe7132330cb1b563f07326f3bcf9Erik long id = mModel.mId; // mCursor.getInt(mEventIndexId); 138a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id); 13937960c091b5912dd45beb561a85a9064ea42e616Erik mService.startDelete(mService.getNextToken(), null, uri, null, null, Utils.UNDO_DELAY); 14089ad0822f104015625f4ca88bfdf5c1d522b6e74Erik if (mCallback != null) { 14189ad0822f104015625f4ca88bfdf5c1d522b6e74Erik mCallback.run(); 14289ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mExitWhenDone) { 144146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mParent.finish(); 145146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 147146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 148146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 149146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 15083f7ce18540aa5b8ed2402d178d35520cd725deaErik * This callback is used when an exception to an event is deleted 15183f7ce18540aa5b8ed2402d178d35520cd725deaErik */ 15283f7ce18540aa5b8ed2402d178d35520cd725deaErik private DialogInterface.OnClickListener mDeleteExceptionDialogListener = 15383f7ce18540aa5b8ed2402d178d35520cd725deaErik new DialogInterface.OnClickListener() { 15483f7ce18540aa5b8ed2402d178d35520cd725deaErik public void onClick(DialogInterface dialog, int button) { 155b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson deleteStarted(); 15683f7ce18540aa5b8ed2402d178d35520cd725deaErik deleteExceptionEvent(); 15789ad0822f104015625f4ca88bfdf5c1d522b6e74Erik if (mCallback != null) { 15889ad0822f104015625f4ca88bfdf5c1d522b6e74Erik mCallback.run(); 15989ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 16083f7ce18540aa5b8ed2402d178d35520cd725deaErik if (mExitWhenDone) { 16183f7ce18540aa5b8ed2402d178d35520cd725deaErik mParent.finish(); 16283f7ce18540aa5b8ed2402d178d35520cd725deaErik } 16383f7ce18540aa5b8ed2402d178d35520cd725deaErik } 16483f7ce18540aa5b8ed2402d178d35520cd725deaErik }; 16583f7ce18540aa5b8ed2402d178d35520cd725deaErik 16683f7ce18540aa5b8ed2402d178d35520cd725deaErik /** 167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * This callback is used when a list item for a repeating event is selected 168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private DialogInterface.OnClickListener mDeleteListListener = 170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project new DialogInterface.OnClickListener() { 171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void onClick(DialogInterface dialog, int button) { 172e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik // set mWhichDelete to the delete type at that index 173e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik mWhichDelete = mWhichIndex.get(button); 174ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 175146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Enable the "ok" button now that the user has selected which 176146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // events in the series to delete. 177146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Button ok = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE); 178146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ok.setEnabled(true); 179146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * This callback is used when a repeating event is deleted. 184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private DialogInterface.OnClickListener mDeleteRepeatingDialogListener = 186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project new DialogInterface.OnClickListener() { 187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void onClick(DialogInterface dialog, int button) { 188b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson deleteStarted(); 189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mWhichDelete != -1) { 190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project deleteRepeatingEvent(mWhichDelete); 191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 194ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Does the required processing for deleting an event, which includes 197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * first popping up a dialog asking for confirmation (if the event is 198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * a normal event) or a dialog asking which events to delete (if the 199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * event is a repeating event). The "which" parameter is used to check 200146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * the initial selection and is only used for repeating events. Set 201146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * "which" to -1 to have nothing selected initially. 202ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 203146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param begin the begin time of the event, in UTC milliseconds 204146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param end the end time of the event, in UTC milliseconds 205146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param eventId the event id 206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param which one of the values {@link DELETE_SELECTED}, 207146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * {@link DELETE_ALL_FOLLOWING}, {@link DELETE_ALL}, or -1 208146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 209146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void delete(long begin, long end, long eventId, int which) { 210a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId); 21137960c091b5912dd45beb561a85a9064ea42e616Erik mService.startQuery(mService.getNextToken(), null, uri, EditEventHelper.EVENT_PROJECTION, 21237960c091b5912dd45beb561a85a9064ea42e616Erik null, null, null); 21388c483a0189cbe7132330cb1b563f07326f3bcf9Erik mStartMillis = begin; 21488c483a0189cbe7132330cb1b563f07326f3bcf9Erik mEndMillis = end; 21588c483a0189cbe7132330cb1b563f07326f3bcf9Erik mWhichDelete = which; 216146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 217ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 21889ad0822f104015625f4ca88bfdf5c1d522b6e74Erik public void delete(long begin, long end, long eventId, int which, Runnable callback) { 21989ad0822f104015625f4ca88bfdf5c1d522b6e74Erik delete(begin, end, eventId, which); 22089ad0822f104015625f4ca88bfdf5c1d522b6e74Erik mCallback = callback; 22189ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 22289ad0822f104015625f4ca88bfdf5c1d522b6e74Erik 223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Does the required processing for deleting an event. This method 22588c483a0189cbe7132330cb1b563f07326f3bcf9Erik * takes a {@link CalendarEventModel} object, which must have a valid 22688c483a0189cbe7132330cb1b563f07326f3bcf9Erik * uri for referencing the event in the database and have the required 22788c483a0189cbe7132330cb1b563f07326f3bcf9Erik * fields listed below. 228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * The required fields for a normal event are: 229ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 230146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <ul> 231146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events._ID </li> 232146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events.TITLE </li> 233146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events.RRULE </li> 234146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * </ul> 235ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 236146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * The required fields for a repeating event include the above plus the 237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * following fields: 238ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <ul> 240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events.ALL_DAY </li> 241146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events.CALENDAR_ID </li> 242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events.DTSTART </li> 243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events._SYNC_ID </li> 244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * <li> Events.EVENT_TIMEZONE </li> 245146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * </ul> 246ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan * 24788c483a0189cbe7132330cb1b563f07326f3bcf9Erik * If the event no longer exists in the db this will still prompt 24888c483a0189cbe7132330cb1b563f07326f3bcf9Erik * the user but will return without modifying the db after the query 24988c483a0189cbe7132330cb1b563f07326f3bcf9Erik * returns. 25088c483a0189cbe7132330cb1b563f07326f3bcf9Erik * 251146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param begin the begin time of the event, in UTC milliseconds 252146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param end the end time of the event, in UTC milliseconds 253146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param cursor the database cursor containing the required fields 254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param which one of the values {@link DELETE_SELECTED}, 255146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * {@link DELETE_ALL_FOLLOWING}, {@link DELETE_ALL}, or -1 256146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 25788c483a0189cbe7132330cb1b563f07326f3bcf9Erik public void delete(long begin, long end, CalendarEventModel model, int which) { 258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mWhichDelete = which; 259146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mStartMillis = begin; 260146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mEndMillis = end; 26188c483a0189cbe7132330cb1b563f07326f3bcf9Erik mModel = model; 26288c483a0189cbe7132330cb1b563f07326f3bcf9Erik mSyncId = model.mSyncId; 263ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If this is a repeating event, then pop up a dialog asking the 265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // user if they want to delete all of the repeating events or 266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // just some of them. 26788c483a0189cbe7132330cb1b563f07326f3bcf9Erik String rRule = model.mRrule; 26828dab653f55caccbed32f700274f5274abaee089RoboErik String originalEvent = model.mOriginalSyncId; 26966b2067e0a389180f909eb0a528bea5f6becca23Michael Chan if (TextUtils.isEmpty(rRule)) { 27042ecaa327f81f1febf59af1617ddbef5a79b49c5Michael Chan AlertDialog dialog = new AlertDialog.Builder(mContext) 271f6b6fb3204ecd7d5857372b766cbe456585a911aErik .setMessage(R.string.delete_this_event_title) 272f6b6fb3204ecd7d5857372b766cbe456585a911aErik .setIconAttribute(android.R.attr.alertDialogIcon) 273f6b6fb3204ecd7d5857372b766cbe456585a911aErik .setNegativeButton(android.R.string.cancel, null).create(); 27483f7ce18540aa5b8ed2402d178d35520cd725deaErik 27583f7ce18540aa5b8ed2402d178d35520cd725deaErik if (originalEvent == null) { 27683f7ce18540aa5b8ed2402d178d35520cd725deaErik // This is a normal event. Pop up a confirmation dialog. 27783f7ce18540aa5b8ed2402d178d35520cd725deaErik dialog.setButton(DialogInterface.BUTTON_POSITIVE, 2781251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan mContext.getText(android.R.string.ok), 27983f7ce18540aa5b8ed2402d178d35520cd725deaErik mDeleteNormalDialogListener); 28083f7ce18540aa5b8ed2402d178d35520cd725deaErik } else { 28183f7ce18540aa5b8ed2402d178d35520cd725deaErik // This is an exception event. Pop up a confirmation dialog. 28283f7ce18540aa5b8ed2402d178d35520cd725deaErik dialog.setButton(DialogInterface.BUTTON_POSITIVE, 2831251cb05edd5283545bc27652f5c0aaa3d1095a1Michael Chan mContext.getText(android.R.string.ok), 28483f7ce18540aa5b8ed2402d178d35520cd725deaErik mDeleteExceptionDialogListener); 28583f7ce18540aa5b8ed2402d178d35520cd725deaErik } 286b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson dialog.setOnDismissListener(mDismissListener); 28783f7ce18540aa5b8ed2402d178d35520cd725deaErik dialog.show(); 288b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mAlertDialog = dialog; 289146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 290146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // This is a repeating event. Pop up a dialog asking which events 291146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // to delete. 292e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik Resources res = mContext.getResources(); 293e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik ArrayList<String> labelArray = new ArrayList<String>(Arrays.asList(res 294e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik .getStringArray(R.array.delete_repeating_labels))); 295e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik // asList doesn't like int[] so creating it manually. 296e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik int[] labelValues = res.getIntArray(R.array.delete_repeating_values); 297e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik ArrayList<Integer> labelIndex = new ArrayList<Integer>(); 298e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik for (int val : labelValues) { 299e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelIndex.add(val); 300e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik } 301e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik 302146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mSyncId == null) { 303e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik // remove 'Only this event' item 304e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelArray.remove(0); 305e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelIndex.remove(0); 306e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik if (!model.mIsOrganizer) { 307e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik // remove 'This and future events' item 308e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelArray.remove(0); 309e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelIndex.remove(0); 3108d69cd014d912e38d2ab37764aaf4aa7700c078bErik } 311e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik } else if (!model.mIsOrganizer) { 312e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik // remove 'This and future events' item 313e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelArray.remove(1); 314e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik labelIndex.remove(1); 315146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 316e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik if (which != -1) { 317e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik // transform the which to the index in the array 318e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik which = labelIndex.indexOf(which); 319e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik } 320e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik mWhichIndex = labelIndex; 321e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, 322e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik android.R.layout.simple_list_item_single_choice, labelArray); 32342ecaa327f81f1febf59af1617ddbef5a79b49c5Michael Chan AlertDialog dialog = new AlertDialog.Builder(mContext) 324512c8cf6ffeb6f4889feae68ba0fc68bd8bfd7faMindy Pereira .setTitle( 325512c8cf6ffeb6f4889feae68ba0fc68bd8bfd7faMindy Pereira mContext.getString(R.string.delete_recurring_event_title,model.mTitle)) 326f6b6fb3204ecd7d5857372b766cbe456585a911aErik .setIconAttribute(android.R.attr.alertDialogIcon) 327e3e1f555a89a2b4cb859ddae189f57aeb749a852RoboErik .setSingleChoiceItems(adapter, which, mDeleteListListener) 328f6b6fb3204ecd7d5857372b766cbe456585a911aErik .setPositiveButton(android.R.string.ok, mDeleteRepeatingDialogListener) 329f6b6fb3204ecd7d5857372b766cbe456585a911aErik .setNegativeButton(android.R.string.cancel, null).show(); 330b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson dialog.setOnDismissListener(mDismissListener); 331146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mAlertDialog = dialog; 332ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 3333cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project if (which == -1) { 3343cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project // Disable the "Ok" button until the user selects which events 3353cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project // to delete. 3363cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE); 3373cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project ok.setEnabled(false); 3383cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project } 339146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 340146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 341ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 34283f7ce18540aa5b8ed2402d178d35520cd725deaErik private void deleteExceptionEvent() { 34388c483a0189cbe7132330cb1b563f07326f3bcf9Erik long id = mModel.mId; // mCursor.getInt(mEventIndexId); 34483f7ce18540aa5b8ed2402d178d35520cd725deaErik 34583f7ce18540aa5b8ed2402d178d35520cd725deaErik // update a recurrence exception by setting its status to "canceled" 34683f7ce18540aa5b8ed2402d178d35520cd725deaErik ContentValues values = new ContentValues(); 34783f7ce18540aa5b8ed2402d178d35520cd725deaErik values.put(Events.STATUS, Events.STATUS_CANCELED); 34883f7ce18540aa5b8ed2402d178d35520cd725deaErik 349a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id); 35037960c091b5912dd45beb561a85a9064ea42e616Erik mService.startUpdate(mService.getNextToken(), null, uri, values, null, null, 35137960c091b5912dd45beb561a85a9064ea42e616Erik Utils.UNDO_DELAY); 35283f7ce18540aa5b8ed2402d178d35520cd725deaErik } 35383f7ce18540aa5b8ed2402d178d35520cd725deaErik 354146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private void deleteRepeatingEvent(int which) { 35588c483a0189cbe7132330cb1b563f07326f3bcf9Erik String rRule = mModel.mRrule; 35688c483a0189cbe7132330cb1b563f07326f3bcf9Erik boolean allDay = mModel.mAllDay; 35788c483a0189cbe7132330cb1b563f07326f3bcf9Erik long dtstart = mModel.mStart; 35888c483a0189cbe7132330cb1b563f07326f3bcf9Erik long id = mModel.mId; // mCursor.getInt(mEventIndexId); 359146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 360146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project switch (which) { 3618d69cd014d912e38d2ab37764aaf4aa7700c078bErik case DELETE_SELECTED: { 362146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If we are deleting the first event in the series, then 363146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // instead of creating a recurrence exception, just change 364146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the start time of the recurrence. 365146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (dtstart == mStartMillis) { 366146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // TODO 367146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 368ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 369146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Create a recurrence exception by creating a new event 370146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // with the status "cancelled". 371146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ContentValues values = new ContentValues(); 372ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 373146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The title might not be necessary, but it makes it easier 374146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // to find this entry in the database when there is a problem. 37588c483a0189cbe7132330cb1b563f07326f3bcf9Erik String title = mModel.mTitle; 376146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.TITLE, title); 377ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 37888c483a0189cbe7132330cb1b563f07326f3bcf9Erik String timezone = mModel.mTimezone; 37988c483a0189cbe7132330cb1b563f07326f3bcf9Erik long calendarId = mModel.mCalendarId; 380146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.EVENT_TIMEZONE, timezone); 381146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.ALL_DAY, allDay ? 1 : 0); 382fcba1f187b1ee435e67774c792f7ccf8a3b5c357RoboErik values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0); 383146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.CALENDAR_ID, calendarId); 384146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.DTSTART, mStartMillis); 385146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.DTEND, mEndMillis); 3860e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik values.put(Events.ORIGINAL_SYNC_ID, mSyncId); 387e0c5580cbb15738ffdee27526a82cb2a4399ca19RoboErik values.put(Events.ORIGINAL_ID, id); 388146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis); 389146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.STATUS, Events.STATUS_CANCELED); 390ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 39137960c091b5912dd45beb561a85a9064ea42e616Erik mService.startInsert(mService.getNextToken(), null, Events.CONTENT_URI, values, 39237960c091b5912dd45beb561a85a9064ea42e616Erik Utils.UNDO_DELAY); 393146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project break; 394146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 395146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project case DELETE_ALL: { 396a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id); 39737960c091b5912dd45beb561a85a9064ea42e616Erik mService.startDelete(mService.getNextToken(), null, uri, null, null, 39837960c091b5912dd45beb561a85a9064ea42e616Erik Utils.UNDO_DELAY); 399146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project break; 400146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 401146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project case DELETE_ALL_FOLLOWING: { 402146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If we are deleting the first event in the series and all 403146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // following events, then delete them all. 404146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (dtstart == mStartMillis) { 405a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id); 40637960c091b5912dd45beb561a85a9064ea42e616Erik mService.startDelete(mService.getNextToken(), null, uri, null, null, 40737960c091b5912dd45beb561a85a9064ea42e616Erik Utils.UNDO_DELAY); 408146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project break; 409146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 410ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 411146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Modify the repeating event to end just before this event time 412146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project EventRecurrence eventRecurrence = new EventRecurrence(); 413146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project eventRecurrence.parse(rRule); 414146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Time date = new Time(); 415146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (allDay) { 416146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project date.timezone = Time.TIMEZONE_UTC; 417146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 418146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project date.set(mStartMillis); 419146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project date.second--; 420146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project date.normalize(false); 421ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 422146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Google calendar seems to require the UNTIL string to be 423146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // in UTC. 424146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project date.switchTimezone(Time.TIMEZONE_UTC); 425146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project eventRecurrence.until = date.format2445(); 426ad36a3c3cde7a2ec6d3a35d2529d46f03bd8d59dMichael Chan 427146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ContentValues values = new ContentValues(); 428146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.DTSTART, dtstart); 429146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project values.put(Events.RRULE, eventRecurrence.toString()); 430a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id); 43137960c091b5912dd45beb561a85a9064ea42e616Erik mService.startUpdate(mService.getNextToken(), null, uri, values, null, null, 43237960c091b5912dd45beb561a85a9064ea42e616Erik Utils.UNDO_DELAY); 433146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project break; 434146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 435146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 43689ad0822f104015625f4ca88bfdf5c1d522b6e74Erik if (mCallback != null) { 43789ad0822f104015625f4ca88bfdf5c1d522b6e74Erik mCallback.run(); 43889ad0822f104015625f4ca88bfdf5c1d522b6e74Erik } 439146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mExitWhenDone) { 440146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mParent.finish(); 441146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 442146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 443b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 444b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson public void setDeleteNotificationListener(DeleteNotifyListener listener) { 445b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson mDeleteStartedListener = listener; 446b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson } 447b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson 448b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson private void deleteStarted() { 449b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson if (mDeleteStartedListener != null) { 450b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson mDeleteStartedListener.onDeleteStarted(); 451b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson } 452b33cdf41092c79ca3502868d494bc284f4090267Isaac Katzenelson } 453b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson 454b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson public void setOnDismissListener(Dialog.OnDismissListener listener) { 455b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson if (mAlertDialog != null) { 456b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mAlertDialog.setOnDismissListener(listener); 457b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 458b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mDismissListener = listener; 459b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 460b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson 461b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson public void dismissAlertDialog() { 462b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson if (mAlertDialog != null) { 463b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson mAlertDialog.dismiss(); 464b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 465b0a313a3c216e3eeceebd81d3edc6fc60357a055Isaac Katzenelson } 466146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 467