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