EditEventFragment.java revision c130d9d5e0d178585721428e394df0c8e0a6729f
179f228124de7d98146ca526d743436f6419e2365Erik/* 279f228124de7d98146ca526d743436f6419e2365Erik * Copyright (C) 2010 The Android Open Source Project 379f228124de7d98146ca526d743436f6419e2365Erik * 479f228124de7d98146ca526d743436f6419e2365Erik * Licensed under the Apache License, Version 2.0 (the "License"); 579f228124de7d98146ca526d743436f6419e2365Erik * you may not use this file except in compliance with the License. 679f228124de7d98146ca526d743436f6419e2365Erik * You may obtain a copy of the License at 779f228124de7d98146ca526d743436f6419e2365Erik * 879f228124de7d98146ca526d743436f6419e2365Erik * http://www.apache.org/licenses/LICENSE-2.0 979f228124de7d98146ca526d743436f6419e2365Erik * 1079f228124de7d98146ca526d743436f6419e2365Erik * Unless required by applicable law or agreed to in writing, software 1179f228124de7d98146ca526d743436f6419e2365Erik * distributed under the License is distributed on an "AS IS" BASIS, 1279f228124de7d98146ca526d743436f6419e2365Erik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379f228124de7d98146ca526d743436f6419e2365Erik * See the License for the specific language governing permissions and 1479f228124de7d98146ca526d743436f6419e2365Erik * limitations under the License. 1579f228124de7d98146ca526d743436f6419e2365Erik */ 1679f228124de7d98146ca526d743436f6419e2365Erik 17fbce65e53c7a111955f638db5bf8bee35381e5b7Erikpackage com.android.calendar.event; 1879f228124de7d98146ca526d743436f6419e2365Erik 195f62079ab9daefe95ede87631766e99e8b4a2220Erikimport com.android.calendar.AsyncQueryService; 20dd95df57c8c5a58a85c4c0effad5652dec14f621Erikimport com.android.calendar.CalendarController.EventHandler; 21dd95df57c8c5a58a85c4c0effad5652dec14f621Erikimport com.android.calendar.CalendarController.EventInfo; 22dd95df57c8c5a58a85c4c0effad5652dec14f621Erikimport com.android.calendar.CalendarController.EventType; 23fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.CalendarEventModel; 24d845fbe558d5229102b58cce70a1b29fe6cb6967Erikimport com.android.calendar.CalendarEventModel.Attendee; 25fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.DeleteEventHelper; 26fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.R; 27fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.Utils; 28fbce65e53c7a111955f638db5bf8bee35381e5b7Erik 2979f228124de7d98146ca526d743436f6419e2365Erikimport android.app.Activity; 3079f228124de7d98146ca526d743436f6419e2365Erikimport android.app.AlertDialog; 3179f228124de7d98146ca526d743436f6419e2365Erikimport android.app.Fragment; 3279f228124de7d98146ca526d743436f6419e2365Erikimport android.content.AsyncQueryHandler; 335f62079ab9daefe95ede87631766e99e8b4a2220Erikimport android.content.ContentProviderOperation; 3479f228124de7d98146ca526d743436f6419e2365Erikimport android.content.ContentResolver; 35dd95df57c8c5a58a85c4c0effad5652dec14f621Erikimport android.content.ContentUris; 365f62079ab9daefe95ede87631766e99e8b4a2220Erikimport android.content.ContentValues; 375c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawaimport android.content.Context; 3879f228124de7d98146ca526d743436f6419e2365Erikimport android.content.DialogInterface; 3979f228124de7d98146ca526d743436f6419e2365Erikimport android.content.DialogInterface.OnCancelListener; 4079f228124de7d98146ca526d743436f6419e2365Erikimport android.content.DialogInterface.OnClickListener; 4179f228124de7d98146ca526d743436f6419e2365Erikimport android.database.Cursor; 4279f228124de7d98146ca526d743436f6419e2365Erikimport android.database.MatrixCursor; 4379f228124de7d98146ca526d743436f6419e2365Erikimport android.net.Uri; 4479f228124de7d98146ca526d743436f6419e2365Erikimport android.os.Bundle; 4579f228124de7d98146ca526d743436f6419e2365Erikimport android.provider.Calendar.Attendees; 4679f228124de7d98146ca526d743436f6419e2365Erikimport android.provider.Calendar.Calendars; 47dd95df57c8c5a58a85c4c0effad5652dec14f621Erikimport android.provider.Calendar.Events; 4879f228124de7d98146ca526d743436f6419e2365Erikimport android.provider.Calendar.Reminders; 4979f228124de7d98146ca526d743436f6419e2365Erikimport android.text.TextUtils; 5079f228124de7d98146ca526d743436f6419e2365Erikimport android.util.Log; 5179f228124de7d98146ca526d743436f6419e2365Erikimport android.view.LayoutInflater; 525f62079ab9daefe95ede87631766e99e8b4a2220Erikimport android.view.Menu; 535f62079ab9daefe95ede87631766e99e8b4a2220Erikimport android.view.MenuInflater; 545f62079ab9daefe95ede87631766e99e8b4a2220Erikimport android.view.MenuItem; 5579f228124de7d98146ca526d743436f6419e2365Erikimport android.view.View; 5679f228124de7d98146ca526d743436f6419e2365Erikimport android.view.ViewGroup; 575c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawaimport android.view.inputmethod.InputMethodManager; 5879f228124de7d98146ca526d743436f6419e2365Erikimport android.widget.Toast; 5979f228124de7d98146ca526d743436f6419e2365Erik 60c130d9d5e0d178585721428e394df0c8e0a6729fErikimport java.io.Serializable; 615f62079ab9daefe95ede87631766e99e8b4a2220Erikimport java.util.ArrayList; 625f62079ab9daefe95ede87631766e99e8b4a2220Erik 63dd95df57c8c5a58a85c4c0effad5652dec14f621Erikpublic class EditEventFragment extends Fragment implements EventHandler { 6479f228124de7d98146ca526d743436f6419e2365Erik private static final String TAG = "EditEventActivity"; 6579f228124de7d98146ca526d743436f6419e2365Erik 6659ead671b50514b49749fcd6a1d4186a270239d2Erik private static final String BUNDLE_KEY_MODEL = "key_model"; 6759ead671b50514b49749fcd6a1d4186a270239d2Erik private static final String BUNDLE_KEY_EDIT_STATE = "key_edit_state"; 68c130d9d5e0d178585721428e394df0c8e0a6729fErik private static final String BUNDLE_KEY_EVENT = "key_event"; 6959ead671b50514b49749fcd6a1d4186a270239d2Erik 7079f228124de7d98146ca526d743436f6419e2365Erik private static final boolean DEBUG = false; 7179f228124de7d98146ca526d743436f6419e2365Erik 72352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private static final int TOKEN_EVENT = 1; 73352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private static final int TOKEN_ATTENDEES = 1 << 1; 74352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private static final int TOKEN_REMINDERS = 1 << 2; 75352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private static final int TOKEN_CALENDARS = 1 << 3; 76352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan private static final int TOKEN_ALL = TOKEN_EVENT | TOKEN_ATTENDEES | TOKEN_REMINDERS 77352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan | TOKEN_CALENDARS; 785f62079ab9daefe95ede87631766e99e8b4a2220Erik private static final int TOKEN_UNITIALIZED = 1 << 31; 79352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 80352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan /** 81352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan * A bitfield of TOKEN_* to keep track which query hasn't been completed 82352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan * yet. Once all queries have returned, the model can be applied to the 83352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan * view. 84352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan */ 855f62079ab9daefe95ede87631766e99e8b4a2220Erik private int mOutstandingQueries = TOKEN_UNITIALIZED; 8679f228124de7d98146ca526d743436f6419e2365Erik 8779f228124de7d98146ca526d743436f6419e2365Erik EditEventHelper mHelper; 8879f228124de7d98146ca526d743436f6419e2365Erik CalendarEventModel mModel; 8979f228124de7d98146ca526d743436f6419e2365Erik CalendarEventModel mOriginalModel; 9059ead671b50514b49749fcd6a1d4186a270239d2Erik CalendarEventModel mRestoreModel; 9179f228124de7d98146ca526d743436f6419e2365Erik EditEventView mView; 9279f228124de7d98146ca526d743436f6419e2365Erik QueryHandler mHandler; 9379f228124de7d98146ca526d743436f6419e2365Erik 9479f228124de7d98146ca526d743436f6419e2365Erik private AlertDialog mModifyDialog; 9579f228124de7d98146ca526d743436f6419e2365Erik int mModification = Utils.MODIFY_UNINITIALIZED; 9679f228124de7d98146ca526d743436f6419e2365Erik 97dd95df57c8c5a58a85c4c0effad5652dec14f621Erik private EventInfo mEvent; 98c130d9d5e0d178585721428e394df0c8e0a6729fErik private EventBundle mEventBundle; 9979f228124de7d98146ca526d743436f6419e2365Erik private Uri mUri; 10079f228124de7d98146ca526d743436f6419e2365Erik private long mBegin; 10179f228124de7d98146ca526d743436f6419e2365Erik private long mEnd; 10279f228124de7d98146ca526d743436f6419e2365Erik 10379f228124de7d98146ca526d743436f6419e2365Erik private Activity mContext; 104dd95df57c8c5a58a85c4c0effad5652dec14f621Erik private Done mOnDone = new Done(); 1055f62079ab9daefe95ede87631766e99e8b4a2220Erik private Menu mMenu; 106dd95df57c8c5a58a85c4c0effad5652dec14f621Erik 107dd95df57c8c5a58a85c4c0effad5652dec14f621Erik private boolean mSaveOnDetach = true; 10879f228124de7d98146ca526d743436f6419e2365Erik 1095c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa private InputMethodManager mInputMethodManager; 1105c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa 11179f228124de7d98146ca526d743436f6419e2365Erik private class QueryHandler extends AsyncQueryHandler { 11279f228124de7d98146ca526d743436f6419e2365Erik public QueryHandler(ContentResolver cr) { 11379f228124de7d98146ca526d743436f6419e2365Erik super(cr); 11479f228124de7d98146ca526d743436f6419e2365Erik } 11579f228124de7d98146ca526d743436f6419e2365Erik 11679f228124de7d98146ca526d743436f6419e2365Erik @Override 11779f228124de7d98146ca526d743436f6419e2365Erik protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 11879f228124de7d98146ca526d743436f6419e2365Erik // If the query didn't return a cursor for some reason return 11979f228124de7d98146ca526d743436f6419e2365Erik if (cursor == null) { 12079f228124de7d98146ca526d743436f6419e2365Erik return; 12179f228124de7d98146ca526d743436f6419e2365Erik } 12279f228124de7d98146ca526d743436f6419e2365Erik 12379f228124de7d98146ca526d743436f6419e2365Erik // If the Activity is finishing, then close the cursor. 12479f228124de7d98146ca526d743436f6419e2365Erik // Otherwise, use the new cursor in the adapter. 1256a7878f0cfe2f13e4e33fee74ed9f91eaffc227bMichael Chan final Activity activity = EditEventFragment.this.getActivity(); 1266a7878f0cfe2f13e4e33fee74ed9f91eaffc227bMichael Chan if (activity == null || activity.isFinishing()) { 12779f228124de7d98146ca526d743436f6419e2365Erik cursor.close(); 12879f228124de7d98146ca526d743436f6419e2365Erik return; 12979f228124de7d98146ca526d743436f6419e2365Erik } 13079f228124de7d98146ca526d743436f6419e2365Erik long eventId; 13179f228124de7d98146ca526d743436f6419e2365Erik switch (token) { 13279f228124de7d98146ca526d743436f6419e2365Erik case TOKEN_EVENT: 13379f228124de7d98146ca526d743436f6419e2365Erik if (cursor.getCount() == 0) { 13479f228124de7d98146ca526d743436f6419e2365Erik // The cursor is empty. This can happen if the event 13579f228124de7d98146ca526d743436f6419e2365Erik // was deleted. 13679f228124de7d98146ca526d743436f6419e2365Erik cursor.close(); 137352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOnDone.setDoneCode(Utils.DONE_EXIT); 138352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOnDone.run(); 13979f228124de7d98146ca526d743436f6419e2365Erik return; 14079f228124de7d98146ca526d743436f6419e2365Erik } 14179f228124de7d98146ca526d743436f6419e2365Erik mOriginalModel = new CalendarEventModel(); 14279f228124de7d98146ca526d743436f6419e2365Erik EditEventHelper.setModelFromCursor(mOriginalModel, cursor); 14379f228124de7d98146ca526d743436f6419e2365Erik EditEventHelper.setModelFromCursor(mModel, cursor); 14479f228124de7d98146ca526d743436f6419e2365Erik cursor.close(); 14579f228124de7d98146ca526d743436f6419e2365Erik 14659ead671b50514b49749fcd6a1d4186a270239d2Erik mOriginalModel.mUri = mUri.toString(); 14779f228124de7d98146ca526d743436f6419e2365Erik 14859ead671b50514b49749fcd6a1d4186a270239d2Erik mModel.mUri = mUri.toString(); 14979f228124de7d98146ca526d743436f6419e2365Erik mModel.mOriginalStart = mBegin; 15079f228124de7d98146ca526d743436f6419e2365Erik mModel.mOriginalEnd = mEnd; 15179f228124de7d98146ca526d743436f6419e2365Erik mModel.mIsFirstEventInSeries = mBegin == mOriginalModel.mStart; 15279f228124de7d98146ca526d743436f6419e2365Erik mModel.mStart = mBegin; 15379f228124de7d98146ca526d743436f6419e2365Erik mModel.mEnd = mEnd; 15479f228124de7d98146ca526d743436f6419e2365Erik 15579f228124de7d98146ca526d743436f6419e2365Erik eventId = mModel.mId; 156352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 157352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // TOKEN_ATTENDEES 15879f228124de7d98146ca526d743436f6419e2365Erik if (mModel.mHasAttendeeData && eventId != -1) { 15979f228124de7d98146ca526d743436f6419e2365Erik Uri attUri = Attendees.CONTENT_URI; 16079f228124de7d98146ca526d743436f6419e2365Erik String[] whereArgs = { 16179f228124de7d98146ca526d743436f6419e2365Erik Long.toString(eventId) 16279f228124de7d98146ca526d743436f6419e2365Erik }; 16379f228124de7d98146ca526d743436f6419e2365Erik mHandler.startQuery(TOKEN_ATTENDEES, null, attUri, 16479f228124de7d98146ca526d743436f6419e2365Erik EditEventHelper.ATTENDEES_PROJECTION, 165d845fbe558d5229102b58cce70a1b29fe6cb6967Erik EditEventHelper.ATTENDEES_WHERE /* selection */, 16679f228124de7d98146ca526d743436f6419e2365Erik whereArgs /* selection args */, null /* sort order */); 167352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } else { 168352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan setModelIfDone(TOKEN_ATTENDEES); 169352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 170352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 171352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // TOKEN_REMINDERS 172352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (mModel.mHasAlarm) { 173d845fbe558d5229102b58cce70a1b29fe6cb6967Erik Uri rUri = Reminders.CONTENT_URI; 174d845fbe558d5229102b58cce70a1b29fe6cb6967Erik String[] remArgs = { 175d845fbe558d5229102b58cce70a1b29fe6cb6967Erik Long.toString(eventId), Integer.toString(Reminders.METHOD_ALERT), 176d845fbe558d5229102b58cce70a1b29fe6cb6967Erik Integer.toString(Reminders.METHOD_DEFAULT) 177d845fbe558d5229102b58cce70a1b29fe6cb6967Erik }; 178d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mHandler 179d845fbe558d5229102b58cce70a1b29fe6cb6967Erik .startQuery(TOKEN_REMINDERS, null, rUri, 180d845fbe558d5229102b58cce70a1b29fe6cb6967Erik EditEventHelper.REMINDERS_PROJECTION, 181d845fbe558d5229102b58cce70a1b29fe6cb6967Erik EditEventHelper.REMINDERS_WHERE /* selection */, 182d845fbe558d5229102b58cce70a1b29fe6cb6967Erik remArgs /* selection args */, null /* sort order */); 18379f228124de7d98146ca526d743436f6419e2365Erik } else { 184352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan setModelIfDone(TOKEN_REMINDERS); 18579f228124de7d98146ca526d743436f6419e2365Erik } 186352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 187352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // TOKEN_CALENDARS 188352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan String[] selArgs = { 189352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan Long.toString(mModel.mCalendarId) 190352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan }; 191352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mHandler.startQuery(TOKEN_CALENDARS, null, Calendars.CONTENT_URI, 192352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan EditEventHelper.CALENDARS_PROJECTION, EditEventHelper.CALENDARS_WHERE, 193352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan selArgs /* selection args */, null /* sort order */); 194352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 195352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan setModelIfDone(TOKEN_EVENT); 19679f228124de7d98146ca526d743436f6419e2365Erik break; 19779f228124de7d98146ca526d743436f6419e2365Erik case TOKEN_ATTENDEES: 19879f228124de7d98146ca526d743436f6419e2365Erik try { 19979f228124de7d98146ca526d743436f6419e2365Erik while (cursor.moveToNext()) { 20079f228124de7d98146ca526d743436f6419e2365Erik String name = cursor.getString(EditEventHelper.ATTENDEES_INDEX_NAME); 20179f228124de7d98146ca526d743436f6419e2365Erik String email = cursor.getString(EditEventHelper.ATTENDEES_INDEX_EMAIL); 202d845fbe558d5229102b58cce70a1b29fe6cb6967Erik int status = cursor.getInt(EditEventHelper.ATTENDEES_INDEX_STATUS); 20379f228124de7d98146ca526d743436f6419e2365Erik int relationship = cursor 20479f228124de7d98146ca526d743436f6419e2365Erik .getInt(EditEventHelper.ATTENDEES_INDEX_RELATIONSHIP); 205352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (relationship == Attendees.RELATIONSHIP_ORGANIZER) { 206352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (email != null) { 20779f228124de7d98146ca526d743436f6419e2365Erik mModel.mOrganizer = email; 208352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mModel.mIsOrganizer = mModel.mOwnerAccount 209352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan .equalsIgnoreCase(email); 210352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 211352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 212352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (TextUtils.isEmpty(name)) { 213352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mModel.mOrganizerDisplayName = mModel.mOrganizer; 214352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } else { 215352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mModel.mOrganizerDisplayName = name; 21679f228124de7d98146ca526d743436f6419e2365Erik } 217352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 218352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 219352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (email != null) { 220d845fbe558d5229102b58cce70a1b29fe6cb6967Erik if (mModel.mOwnerAccount != null && 221d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mModel.mOwnerAccount.equalsIgnoreCase(email)) { 222d845fbe558d5229102b58cce70a1b29fe6cb6967Erik int attendeeId = 223d845fbe558d5229102b58cce70a1b29fe6cb6967Erik cursor.getInt(EditEventHelper.ATTENDEES_INDEX_ID); 224d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mModel.mOwnerAttendeeId = attendeeId; 225d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mModel.mSelfAttendeeStatus = status; 226d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mOriginalModel.mOwnerAttendeeId = attendeeId; 227d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mOriginalModel.mSelfAttendeeStatus = status; 228d845fbe558d5229102b58cce70a1b29fe6cb6967Erik continue; 229d845fbe558d5229102b58cce70a1b29fe6cb6967Erik } 23079f228124de7d98146ca526d743436f6419e2365Erik } 231d845fbe558d5229102b58cce70a1b29fe6cb6967Erik Attendee attendee = new Attendee(name, email); 232d845fbe558d5229102b58cce70a1b29fe6cb6967Erik attendee.mStatus = status; 233d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mModel.addAttendee(attendee); 234d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mOriginalModel.addAttendee(attendee); 23579f228124de7d98146ca526d743436f6419e2365Erik } 23679f228124de7d98146ca526d743436f6419e2365Erik } finally { 23779f228124de7d98146ca526d743436f6419e2365Erik cursor.close(); 23879f228124de7d98146ca526d743436f6419e2365Erik } 239352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 240352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan setModelIfDone(TOKEN_ATTENDEES); 24179f228124de7d98146ca526d743436f6419e2365Erik break; 24279f228124de7d98146ca526d743436f6419e2365Erik case TOKEN_REMINDERS: 24379f228124de7d98146ca526d743436f6419e2365Erik try { 244d290a01420234214d73d31b8bfa61652625bb149Erik // Add all reminders to the models 24579f228124de7d98146ca526d743436f6419e2365Erik while (cursor.moveToNext()) { 24679f228124de7d98146ca526d743436f6419e2365Erik int minutes = cursor.getInt(EditEventHelper.REMINDERS_INDEX_MINUTES); 24779f228124de7d98146ca526d743436f6419e2365Erik mModel.mReminderMinutes.add(minutes); 248d290a01420234214d73d31b8bfa61652625bb149Erik mOriginalModel.mReminderMinutes.add(minutes); 24979f228124de7d98146ca526d743436f6419e2365Erik } 25079f228124de7d98146ca526d743436f6419e2365Erik } finally { 25179f228124de7d98146ca526d743436f6419e2365Erik cursor.close(); 25279f228124de7d98146ca526d743436f6419e2365Erik } 253352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 254352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan setModelIfDone(TOKEN_REMINDERS); 25579f228124de7d98146ca526d743436f6419e2365Erik break; 25679f228124de7d98146ca526d743436f6419e2365Erik case TOKEN_CALENDARS: 257352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan try { 258352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (mModel.mCalendarId == -1) { 259352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // Populate Calendar spinner only if no calendar is set e.g. new event 260352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan MatrixCursor matrixCursor = Utils.matrixCursorFromCursor(cursor); 261352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (DEBUG) { 262352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan Log.d(TAG, "onQueryComplete: setting cursor with " 263352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan + matrixCursor.getCount() + " calendars"); 264352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 265352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mView.setCalendarsCursor(matrixCursor, isAdded() && isResumed()); 266352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } else { 267352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan // Populate model for an existing event 268352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan EditEventHelper.setModelFromCalendarCursor(mModel, cursor); 269352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 270352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } finally { 271352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan cursor.close(); 27279f228124de7d98146ca526d743436f6419e2365Erik } 273352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 274352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan setModelIfDone(TOKEN_CALENDARS); 27579f228124de7d98146ca526d743436f6419e2365Erik break; 27679f228124de7d98146ca526d743436f6419e2365Erik } 27779f228124de7d98146ca526d743436f6419e2365Erik } 27879f228124de7d98146ca526d743436f6419e2365Erik } 27979f228124de7d98146ca526d743436f6419e2365Erik 280bdcb9fcc732d52708fafb068f535a2c93ff2356fDaisuke Miyakawa private void setModelIfDone(int queryType) { 281352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan synchronized (this) { 282352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOutstandingQueries &= ~queryType; 283352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan if (mOutstandingQueries == 0) { 28459ead671b50514b49749fcd6a1d4186a270239d2Erik if (mRestoreModel != null) { 28559ead671b50514b49749fcd6a1d4186a270239d2Erik mModel = mRestoreModel; 28659ead671b50514b49749fcd6a1d4186a270239d2Erik } 287352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mView.setModel(mModel); 288c07a57fb7436d807ad505fa7319b9de13f91e741Erik if (mMenu != null) { 2895f62079ab9daefe95ede87631766e99e8b4a2220Erik updateActionBar(); 2905f62079ab9daefe95ede87631766e99e8b4a2220Erik } 291352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 292352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 293352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan } 294352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan 2955f62079ab9daefe95ede87631766e99e8b4a2220Erik private void updateActionBar() { 296c07a57fb7436d807ad505fa7319b9de13f91e741Erik if (mMenu == null) { 297c07a57fb7436d807ad505fa7319b9de13f91e741Erik return; 298c07a57fb7436d807ad505fa7319b9de13f91e741Erik } 2995f62079ab9daefe95ede87631766e99e8b4a2220Erik MenuItem cancelItem = mMenu.findItem(R.id.action_cancel); 3005f62079ab9daefe95ede87631766e99e8b4a2220Erik MenuItem deleteItem = mMenu.findItem(R.id.action_delete); 301c07a57fb7436d807ad505fa7319b9de13f91e741Erik MenuItem editItem = mMenu.findItem(R.id.action_edit); 302c07a57fb7436d807ad505fa7319b9de13f91e741Erik boolean canModifyEvent = EditEventHelper.canModifyEvent(mModel); 30346cde5cff48d6862f492f60c6a6336bfc047ce25Erik boolean canModifyCalendar = EditEventHelper.canModifyCalendar(mModel); 304c07a57fb7436d807ad505fa7319b9de13f91e741Erik 30546cde5cff48d6862f492f60c6a6336bfc047ce25Erik if (canModifyCalendar && mModel.mUri != null) { 30646cde5cff48d6862f492f60c6a6336bfc047ce25Erik deleteItem.setVisible(true); 30746cde5cff48d6862f492f60c6a6336bfc047ce25Erik } else { 30846cde5cff48d6862f492f60c6a6336bfc047ce25Erik deleteItem.setVisible(false); 30946cde5cff48d6862f492f60c6a6336bfc047ce25Erik } 310c07a57fb7436d807ad505fa7319b9de13f91e741Erik if (mModification == Utils.MODIFY_UNINITIALIZED) { 311c07a57fb7436d807ad505fa7319b9de13f91e741Erik cancelItem.setVisible(false); 312c07a57fb7436d807ad505fa7319b9de13f91e741Erik if (canModifyEvent) { 313c07a57fb7436d807ad505fa7319b9de13f91e741Erik editItem.setVisible(true); 314c07a57fb7436d807ad505fa7319b9de13f91e741Erik } else { 315c07a57fb7436d807ad505fa7319b9de13f91e741Erik editItem.setVisible(false); 316c07a57fb7436d807ad505fa7319b9de13f91e741Erik } 317c07a57fb7436d807ad505fa7319b9de13f91e741Erik return; 318c07a57fb7436d807ad505fa7319b9de13f91e741Erik } else { 31946cde5cff48d6862f492f60c6a6336bfc047ce25Erik editItem.setVisible(false); 320c07a57fb7436d807ad505fa7319b9de13f91e741Erik } 321c07a57fb7436d807ad505fa7319b9de13f91e741Erik boolean canRespond = EditEventHelper.canRespond(mModel); 3225f62079ab9daefe95ede87631766e99e8b4a2220Erik 3235f62079ab9daefe95ede87631766e99e8b4a2220Erik if (canRespond || canModifyEvent) { 3245f62079ab9daefe95ede87631766e99e8b4a2220Erik cancelItem.setVisible(true); 3255f62079ab9daefe95ede87631766e99e8b4a2220Erik } else { 3265f62079ab9daefe95ede87631766e99e8b4a2220Erik cancelItem.setVisible(false); 3275f62079ab9daefe95ede87631766e99e8b4a2220Erik } 3285f62079ab9daefe95ede87631766e99e8b4a2220Erik } 3295f62079ab9daefe95ede87631766e99e8b4a2220Erik 330dd95df57c8c5a58a85c4c0effad5652dec14f621Erik public EditEventFragment() { 3315f62079ab9daefe95ede87631766e99e8b4a2220Erik this(null); 332dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 333dd95df57c8c5a58a85c4c0effad5652dec14f621Erik 3345f62079ab9daefe95ede87631766e99e8b4a2220Erik public EditEventFragment(EventInfo event) { 335dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mEvent = event; 3365f62079ab9daefe95ede87631766e99e8b4a2220Erik setHasOptionsMenu(true); 33779f228124de7d98146ca526d743436f6419e2365Erik } 33879f228124de7d98146ca526d743436f6419e2365Erik 33979f228124de7d98146ca526d743436f6419e2365Erik private void startQuery() { 340dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mUri = null; 341dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mBegin = -1; 342dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mEnd = -1; 343dd95df57c8c5a58a85c4c0effad5652dec14f621Erik if (mEvent != null) { 344dd95df57c8c5a58a85c4c0effad5652dec14f621Erik if (mEvent.id != -1) { 345352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mModel.mId = mEvent.id; 346dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mUri = ContentUris.withAppendedId(Events.CONTENT_URI, mEvent.id); 347dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 348dd95df57c8c5a58a85c4c0effad5652dec14f621Erik if (mEvent.startTime != null) { 349dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mBegin = mEvent.startTime.toMillis(true); 350dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 351dd95df57c8c5a58a85c4c0effad5652dec14f621Erik if (mEvent.endTime != null) { 352dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mEnd = mEvent.endTime.toMillis(true); 353dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 354c130d9d5e0d178585721428e394df0c8e0a6729fErik } else if (mEventBundle != null) { 355c130d9d5e0d178585721428e394df0c8e0a6729fErik mModel.mId = mEventBundle.id; 356c130d9d5e0d178585721428e394df0c8e0a6729fErik mUri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventBundle.id); 357c130d9d5e0d178585721428e394df0c8e0a6729fErik mBegin = mEventBundle.start; 358c130d9d5e0d178585721428e394df0c8e0a6729fErik mEnd = mEventBundle.end; 359dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 360e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang 361e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang if (mBegin <= 0) { 362e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang // use a default value instead 363e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang mBegin = mHelper.constructDefaultStartTime(System.currentTimeMillis()); 364e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang } 365e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang if (mEnd < mBegin) { 366e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang // use a default value instead 367e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang mEnd = mHelper.constructDefaultEndTime(mBegin); 368e700c16ec2464cbba86f91f8f757ae59cbed34b0Mason Tang } 36979f228124de7d98146ca526d743436f6419e2365Erik 37079f228124de7d98146ca526d743436f6419e2365Erik // Kick off the query for the event 37179f228124de7d98146ca526d743436f6419e2365Erik boolean newEvent = mUri == null; 37279f228124de7d98146ca526d743436f6419e2365Erik if (!newEvent) { 373c07a57fb7436d807ad505fa7319b9de13f91e741Erik mModel.mCalendarAccessLevel = Calendars.NO_ACCESS; 374352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOutstandingQueries = TOKEN_ALL; 37579f228124de7d98146ca526d743436f6419e2365Erik if (DEBUG) { 376352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan Log.d(TAG, "startQuery: uri for event is " + mUri.toString()); 37779f228124de7d98146ca526d743436f6419e2365Erik } 37879f228124de7d98146ca526d743436f6419e2365Erik mHandler.startQuery(TOKEN_EVENT, null, mUri, EditEventHelper.EVENT_PROJECTION, 37979f228124de7d98146ca526d743436f6419e2365Erik null /* selection */, null /* selection args */, null /* sort order */); 38079f228124de7d98146ca526d743436f6419e2365Erik } else { 381352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan mOutstandingQueries = TOKEN_CALENDARS; 38279f228124de7d98146ca526d743436f6419e2365Erik if (DEBUG) { 383352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan Log.d(TAG, "startQuery: Editing a new event."); 38479f228124de7d98146ca526d743436f6419e2365Erik } 38579f228124de7d98146ca526d743436f6419e2365Erik mModel.mStart = mBegin; 38679f228124de7d98146ca526d743436f6419e2365Erik mModel.mEnd = mEnd; 387d845fbe558d5229102b58cce70a1b29fe6cb6967Erik mModel.mSelfAttendeeStatus = Attendees.ATTENDEE_STATUS_ACCEPTED; 38879f228124de7d98146ca526d743436f6419e2365Erik 38979f228124de7d98146ca526d743436f6419e2365Erik // Start a query in the background to read the list of calendars 39079f228124de7d98146ca526d743436f6419e2365Erik mHandler.startQuery(TOKEN_CALENDARS, null, Calendars.CONTENT_URI, 39179f228124de7d98146ca526d743436f6419e2365Erik EditEventHelper.CALENDARS_PROJECTION, 39279f228124de7d98146ca526d743436f6419e2365Erik EditEventHelper.CALENDARS_WHERE_WRITEABLE_VISIBLE, null /* selection args */, 39379f228124de7d98146ca526d743436f6419e2365Erik null /* sort order */); 394c07a57fb7436d807ad505fa7319b9de13f91e741Erik 395c07a57fb7436d807ad505fa7319b9de13f91e741Erik mModification = Utils.MODIFY_ALL; 396c07a57fb7436d807ad505fa7319b9de13f91e741Erik updateActionBar(); 397c07a57fb7436d807ad505fa7319b9de13f91e741Erik mView.setModification(mModification); 39879f228124de7d98146ca526d743436f6419e2365Erik } 39979f228124de7d98146ca526d743436f6419e2365Erik } 40079f228124de7d98146ca526d743436f6419e2365Erik 40179f228124de7d98146ca526d743436f6419e2365Erik @Override 40279f228124de7d98146ca526d743436f6419e2365Erik public void onAttach(Activity activity) { 40379f228124de7d98146ca526d743436f6419e2365Erik super.onAttach(activity); 40479f228124de7d98146ca526d743436f6419e2365Erik mContext = activity; 40579f228124de7d98146ca526d743436f6419e2365Erik 406dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mHelper = new EditEventHelper(activity, null); 40779f228124de7d98146ca526d743436f6419e2365Erik mHandler = new QueryHandler(activity.getContentResolver()); 408dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mModel = new CalendarEventModel(activity); 4095c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa mInputMethodManager = (InputMethodManager) 4105c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa activity.getSystemService(Context.INPUT_METHOD_SERVICE); 41179f228124de7d98146ca526d743436f6419e2365Erik } 41279f228124de7d98146ca526d743436f6419e2365Erik 41379f228124de7d98146ca526d743436f6419e2365Erik @Override 41479f228124de7d98146ca526d743436f6419e2365Erik public View onCreateView(LayoutInflater inflater, ViewGroup container, 41579f228124de7d98146ca526d743436f6419e2365Erik Bundle savedInstanceState) { 41679f228124de7d98146ca526d743436f6419e2365Erik// mContext.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 41779f228124de7d98146ca526d743436f6419e2365Erik View view = inflater.inflate(R.layout.edit_event, null); 418dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mView = new EditEventView(mContext, view, mOnDone); 41979f228124de7d98146ca526d743436f6419e2365Erik startQuery(); 42079f228124de7d98146ca526d743436f6419e2365Erik return view; 42179f228124de7d98146ca526d743436f6419e2365Erik } 42279f228124de7d98146ca526d743436f6419e2365Erik 42379f228124de7d98146ca526d743436f6419e2365Erik @Override 42479f228124de7d98146ca526d743436f6419e2365Erik public void onCreate(Bundle savedInstanceState) { 42579f228124de7d98146ca526d743436f6419e2365Erik super.onCreate(savedInstanceState); 42659ead671b50514b49749fcd6a1d4186a270239d2Erik if (savedInstanceState != null) { 42759ead671b50514b49749fcd6a1d4186a270239d2Erik if (savedInstanceState.containsKey(BUNDLE_KEY_MODEL)) { 42859ead671b50514b49749fcd6a1d4186a270239d2Erik mRestoreModel = (CalendarEventModel) savedInstanceState.getSerializable( 42959ead671b50514b49749fcd6a1d4186a270239d2Erik BUNDLE_KEY_MODEL); 43059ead671b50514b49749fcd6a1d4186a270239d2Erik } 43159ead671b50514b49749fcd6a1d4186a270239d2Erik if (savedInstanceState.containsKey(BUNDLE_KEY_EDIT_STATE)) { 43259ead671b50514b49749fcd6a1d4186a270239d2Erik mModification = savedInstanceState.getInt(BUNDLE_KEY_EDIT_STATE); 43359ead671b50514b49749fcd6a1d4186a270239d2Erik } 434c130d9d5e0d178585721428e394df0c8e0a6729fErik if (savedInstanceState.containsKey(BUNDLE_KEY_EVENT)) { 435c130d9d5e0d178585721428e394df0c8e0a6729fErik mEventBundle = (EventBundle) savedInstanceState.getSerializable(BUNDLE_KEY_EVENT); 436c130d9d5e0d178585721428e394df0c8e0a6729fErik } 43759ead671b50514b49749fcd6a1d4186a270239d2Erik } 43879f228124de7d98146ca526d743436f6419e2365Erik } 4395f62079ab9daefe95ede87631766e99e8b4a2220Erik 4405f62079ab9daefe95ede87631766e99e8b4a2220Erik 4415f62079ab9daefe95ede87631766e99e8b4a2220Erik @Override 4425f62079ab9daefe95ede87631766e99e8b4a2220Erik public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 4435f62079ab9daefe95ede87631766e99e8b4a2220Erik super.onCreateOptionsMenu(menu, inflater); 4445f62079ab9daefe95ede87631766e99e8b4a2220Erik inflater.inflate(R.menu.edit_event_title_bar, menu); 4455f62079ab9daefe95ede87631766e99e8b4a2220Erik synchronized (this) { 4465f62079ab9daefe95ede87631766e99e8b4a2220Erik mMenu = menu; 447c07a57fb7436d807ad505fa7319b9de13f91e741Erik updateActionBar(); 4485f62079ab9daefe95ede87631766e99e8b4a2220Erik } 4495f62079ab9daefe95ede87631766e99e8b4a2220Erik } 4505f62079ab9daefe95ede87631766e99e8b4a2220Erik 4515f62079ab9daefe95ede87631766e99e8b4a2220Erik @Override 4525f62079ab9daefe95ede87631766e99e8b4a2220Erik public boolean onOptionsItemSelected(MenuItem item) { 4535f62079ab9daefe95ede87631766e99e8b4a2220Erik switch (item.getItemId()) { 4545f62079ab9daefe95ede87631766e99e8b4a2220Erik case R.id.action_done: 4555f62079ab9daefe95ede87631766e99e8b4a2220Erik if (EditEventHelper.canModifyEvent(mModel) || EditEventHelper.canRespond(mModel)) { 4565f62079ab9daefe95ede87631766e99e8b4a2220Erik if (mView != null && mView.prepareForSave()) { 45746cde5cff48d6862f492f60c6a6336bfc047ce25Erik if (mModification == Utils.MODIFY_UNINITIALIZED) { 45846cde5cff48d6862f492f60c6a6336bfc047ce25Erik mModification = Utils.MODIFY_ALL; 45946cde5cff48d6862f492f60c6a6336bfc047ce25Erik } 4605f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.setDoneCode(Utils.DONE_SAVE | Utils.DONE_EXIT); 4615f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.run(); 4625f62079ab9daefe95ede87631766e99e8b4a2220Erik } else { 4635f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.setDoneCode(Utils.DONE_REVERT); 4645f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.run(); 4655f62079ab9daefe95ede87631766e99e8b4a2220Erik } 4665f62079ab9daefe95ede87631766e99e8b4a2220Erik } else if (EditEventHelper.canAddReminders(mModel) && mModel.mId != -1 4675f62079ab9daefe95ede87631766e99e8b4a2220Erik && mOriginalModel != null && mView.prepareForSave()) { 4685f62079ab9daefe95ede87631766e99e8b4a2220Erik saveReminders(); 4695f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.setDoneCode(Utils.DONE_EXIT); 4705f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.run(); 4715f62079ab9daefe95ede87631766e99e8b4a2220Erik } else { 4725f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.setDoneCode(Utils.DONE_REVERT); 4735f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.run(); 4745f62079ab9daefe95ede87631766e99e8b4a2220Erik } 4755f62079ab9daefe95ede87631766e99e8b4a2220Erik break; 4765f62079ab9daefe95ede87631766e99e8b4a2220Erik case R.id.action_cancel: 4775f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.setDoneCode(Utils.DONE_REVERT); 4785f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.run(); 4795f62079ab9daefe95ede87631766e99e8b4a2220Erik break; 4805f62079ab9daefe95ede87631766e99e8b4a2220Erik case R.id.action_delete: 4815f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.setDoneCode(Utils.DONE_DELETE); 4825f62079ab9daefe95ede87631766e99e8b4a2220Erik mOnDone.run(); 4835f62079ab9daefe95ede87631766e99e8b4a2220Erik break; 484c07a57fb7436d807ad505fa7319b9de13f91e741Erik case R.id.action_edit: 485c07a57fb7436d807ad505fa7319b9de13f91e741Erik if (!TextUtils.isEmpty(mModel.mRrule)) { 48646cde5cff48d6862f492f60c6a6336bfc047ce25Erik displayEditWhichDialog(); 487c07a57fb7436d807ad505fa7319b9de13f91e741Erik } else { 488c07a57fb7436d807ad505fa7319b9de13f91e741Erik mModification = Utils.MODIFY_ALL; 489c07a57fb7436d807ad505fa7319b9de13f91e741Erik updateActionBar(); 490c07a57fb7436d807ad505fa7319b9de13f91e741Erik mView.setModification(mModification); 491c07a57fb7436d807ad505fa7319b9de13f91e741Erik } 492c07a57fb7436d807ad505fa7319b9de13f91e741Erik break; 4935f62079ab9daefe95ede87631766e99e8b4a2220Erik } 4945f62079ab9daefe95ede87631766e99e8b4a2220Erik return true; 4955f62079ab9daefe95ede87631766e99e8b4a2220Erik } 4965f62079ab9daefe95ede87631766e99e8b4a2220Erik 4975f62079ab9daefe95ede87631766e99e8b4a2220Erik private void saveReminders() { 4985f62079ab9daefe95ede87631766e99e8b4a2220Erik ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(3); 4995f62079ab9daefe95ede87631766e99e8b4a2220Erik boolean changed = EditEventHelper.saveReminders(ops, mModel.mId, mModel.mReminderMinutes, 5005f62079ab9daefe95ede87631766e99e8b4a2220Erik mOriginalModel.mReminderMinutes, false /* no force save */); 5015f62079ab9daefe95ede87631766e99e8b4a2220Erik 5025f62079ab9daefe95ede87631766e99e8b4a2220Erik if (!changed) { 5035f62079ab9daefe95ede87631766e99e8b4a2220Erik return; 5045f62079ab9daefe95ede87631766e99e8b4a2220Erik } 5055f62079ab9daefe95ede87631766e99e8b4a2220Erik 5065f62079ab9daefe95ede87631766e99e8b4a2220Erik AsyncQueryService service = new AsyncQueryService(getActivity()); 5075f62079ab9daefe95ede87631766e99e8b4a2220Erik service.startBatch(0, null, Calendars.CONTENT_URI.getAuthority(), ops, 0); 5085f62079ab9daefe95ede87631766e99e8b4a2220Erik // Update the "hasAlarm" field for the event 5095f62079ab9daefe95ede87631766e99e8b4a2220Erik Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mModel.mId); 5105f62079ab9daefe95ede87631766e99e8b4a2220Erik int len = mModel.mReminderMinutes.size(); 5115f62079ab9daefe95ede87631766e99e8b4a2220Erik boolean hasAlarm = len > 0; 5125f62079ab9daefe95ede87631766e99e8b4a2220Erik if (hasAlarm != mOriginalModel.mHasAlarm) { 5135f62079ab9daefe95ede87631766e99e8b4a2220Erik ContentValues values = new ContentValues(); 5145f62079ab9daefe95ede87631766e99e8b4a2220Erik values.put(Events.HAS_ALARM, hasAlarm ? 1 : 0); 5155f62079ab9daefe95ede87631766e99e8b4a2220Erik service.startUpdate(0, null, uri, values, null, null, 0); 5165f62079ab9daefe95ede87631766e99e8b4a2220Erik } 5175f62079ab9daefe95ede87631766e99e8b4a2220Erik 5185f62079ab9daefe95ede87631766e99e8b4a2220Erik Toast.makeText(mContext, R.string.saving_event, Toast.LENGTH_SHORT).show(); 5195f62079ab9daefe95ede87631766e99e8b4a2220Erik } 5205f62079ab9daefe95ede87631766e99e8b4a2220Erik 52146cde5cff48d6862f492f60c6a6336bfc047ce25Erik protected void displayEditWhichDialog() { 52279f228124de7d98146ca526d743436f6419e2365Erik if (!TextUtils.isEmpty(mModel.mRrule) && mModification == Utils.MODIFY_UNINITIALIZED) { 5231ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan final boolean notSynced = mModel.mSyncId == null; 52479f228124de7d98146ca526d743436f6419e2365Erik boolean isFirstEventInSeries = mModel.mIsFirstEventInSeries; 52579f228124de7d98146ca526d743436f6419e2365Erik int itemIndex = 0; 52679f228124de7d98146ca526d743436f6419e2365Erik CharSequence[] items; 5271ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan 5281ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan if (notSynced) { 5291ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan // If this event has not been synced, then don't allow deleting 5301ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan // or changing a single instance. 53179f228124de7d98146ca526d743436f6419e2365Erik if (isFirstEventInSeries) { 53279f228124de7d98146ca526d743436f6419e2365Erik // Still display the option so the user knows all events are 53379f228124de7d98146ca526d743436f6419e2365Erik // changing 53479f228124de7d98146ca526d743436f6419e2365Erik items = new CharSequence[1]; 53579f228124de7d98146ca526d743436f6419e2365Erik } else { 53679f228124de7d98146ca526d743436f6419e2365Erik items = new CharSequence[2]; 53779f228124de7d98146ca526d743436f6419e2365Erik } 53879f228124de7d98146ca526d743436f6419e2365Erik } else { 53979f228124de7d98146ca526d743436f6419e2365Erik if (isFirstEventInSeries) { 54079f228124de7d98146ca526d743436f6419e2365Erik items = new CharSequence[2]; 54179f228124de7d98146ca526d743436f6419e2365Erik } else { 54279f228124de7d98146ca526d743436f6419e2365Erik items = new CharSequence[3]; 54379f228124de7d98146ca526d743436f6419e2365Erik } 54479f228124de7d98146ca526d743436f6419e2365Erik items[itemIndex++] = mContext.getText(R.string.modify_event); 54579f228124de7d98146ca526d743436f6419e2365Erik } 54679f228124de7d98146ca526d743436f6419e2365Erik items[itemIndex++] = mContext.getText(R.string.modify_all); 54779f228124de7d98146ca526d743436f6419e2365Erik 54879f228124de7d98146ca526d743436f6419e2365Erik // Do one more check to make sure this remains at the end of the list 54979f228124de7d98146ca526d743436f6419e2365Erik if (!isFirstEventInSeries) { 55079f228124de7d98146ca526d743436f6419e2365Erik items[itemIndex++] = mContext.getText(R.string.modify_all_following); 55179f228124de7d98146ca526d743436f6419e2365Erik } 55279f228124de7d98146ca526d743436f6419e2365Erik 55379f228124de7d98146ca526d743436f6419e2365Erik // Display the modification dialog. 55479f228124de7d98146ca526d743436f6419e2365Erik if (mModifyDialog != null) { 55579f228124de7d98146ca526d743436f6419e2365Erik mModifyDialog.dismiss(); 55679f228124de7d98146ca526d743436f6419e2365Erik mModifyDialog = null; 55779f228124de7d98146ca526d743436f6419e2365Erik } 55879f228124de7d98146ca526d743436f6419e2365Erik mModifyDialog = new AlertDialog.Builder(mContext).setOnCancelListener( 55979f228124de7d98146ca526d743436f6419e2365Erik new OnCancelListener() { 56079f228124de7d98146ca526d743436f6419e2365Erik public void onCancel(DialogInterface dialog) { 56179f228124de7d98146ca526d743436f6419e2365Erik mContext.finish(); 56279f228124de7d98146ca526d743436f6419e2365Erik } 56379f228124de7d98146ca526d743436f6419e2365Erik }).setTitle(R.string.edit_event_label).setItems(items, new OnClickListener() { 56479f228124de7d98146ca526d743436f6419e2365Erik public void onClick(DialogInterface dialog, int which) { 56579f228124de7d98146ca526d743436f6419e2365Erik if (which == 0) { 5661ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan mModification = notSynced ? Utils.MODIFY_ALL : Utils.MODIFY_SELECTED; 567c07a57fb7436d807ad505fa7319b9de13f91e741Erik mModel.mOriginalEvent = notSynced ? null : mModel.mSyncId; 56879f228124de7d98146ca526d743436f6419e2365Erik } else if (which == 1) { 5691ec87639bd05857bcb2c4a0acc189c0ff413a287Michael Chan mModification = notSynced ? Utils.MODIFY_ALL_FOLLOWING : Utils.MODIFY_ALL; 57079f228124de7d98146ca526d743436f6419e2365Erik } else if (which == 2) { 57179f228124de7d98146ca526d743436f6419e2365Erik mModification = Utils.MODIFY_ALL_FOLLOWING; 57279f228124de7d98146ca526d743436f6419e2365Erik } 57379f228124de7d98146ca526d743436f6419e2365Erik 57479f228124de7d98146ca526d743436f6419e2365Erik mView.setModification(mModification); 575c07a57fb7436d807ad505fa7319b9de13f91e741Erik updateActionBar(); 57679f228124de7d98146ca526d743436f6419e2365Erik } 57779f228124de7d98146ca526d743436f6419e2365Erik }).show(); 57879f228124de7d98146ca526d743436f6419e2365Erik } 57979f228124de7d98146ca526d743436f6419e2365Erik } 58079f228124de7d98146ca526d743436f6419e2365Erik 58179f228124de7d98146ca526d743436f6419e2365Erik class Done implements EditEventHelper.EditDoneRunnable { 58279f228124de7d98146ca526d743436f6419e2365Erik private int mCode = -1; 58379f228124de7d98146ca526d743436f6419e2365Erik 58479f228124de7d98146ca526d743436f6419e2365Erik public void setDoneCode(int code) { 58579f228124de7d98146ca526d743436f6419e2365Erik mCode = code; 58679f228124de7d98146ca526d743436f6419e2365Erik } 58779f228124de7d98146ca526d743436f6419e2365Erik 58879f228124de7d98146ca526d743436f6419e2365Erik public void run() { 589dd95df57c8c5a58a85c4c0effad5652dec14f621Erik // We only want this to get called once, either because the user 590dd95df57c8c5a58a85c4c0effad5652dec14f621Erik // pressed back/home or one of the buttons on screen 591dd95df57c8c5a58a85c4c0effad5652dec14f621Erik mSaveOnDetach = false; 5927b92da258a480284dcc15a518ea570072329a31dErik 59318a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan if ((mCode & Utils.DONE_SAVE) != 0 59418a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan && mModel != null 59518a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan && (EditEventHelper.canRespond(mModel) || EditEventHelper 596304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan .canModifyEvent(mModel)) && !mModel.equals(mOriginalModel) 597304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan && mHelper.saveEvent(mModel, mOriginalModel, mModification)) { 598304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan int stringResource; 599304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan if (mModel.mUri != null) { 600304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan stringResource = R.string.saving_event; 601304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan } else { 602304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan stringResource = R.string.creating_event; 6037b92da258a480284dcc15a518ea570072329a31dErik } 604304bf0d244d54c2c8c1799e3d43c54d197a891d8Michael Chan Toast.makeText(mContext, stringResource, Toast.LENGTH_SHORT).show(); 6057b92da258a480284dcc15a518ea570072329a31dErik } 6067b92da258a480284dcc15a518ea570072329a31dErik 60718a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan if ((mCode & Utils.DONE_DELETE) != 0 && mModel != null 60818a3c2e829ded43dc1e238f6a4ac054c0eb04684Michael Chan && EditEventHelper.canModifyCalendar(mModel)) { 6097b92da258a480284dcc15a518ea570072329a31dErik long begin = mModel.mStart; 6107b92da258a480284dcc15a518ea570072329a31dErik long end = mModel.mEnd; 6117b92da258a480284dcc15a518ea570072329a31dErik int which = -1; 6127b92da258a480284dcc15a518ea570072329a31dErik switch (mModification) { 6137b92da258a480284dcc15a518ea570072329a31dErik case Utils.MODIFY_SELECTED: 6147b92da258a480284dcc15a518ea570072329a31dErik which = DeleteEventHelper.DELETE_SELECTED; 6157b92da258a480284dcc15a518ea570072329a31dErik break; 6167b92da258a480284dcc15a518ea570072329a31dErik case Utils.MODIFY_ALL_FOLLOWING: 6177b92da258a480284dcc15a518ea570072329a31dErik which = DeleteEventHelper.DELETE_ALL_FOLLOWING; 6187b92da258a480284dcc15a518ea570072329a31dErik break; 6197b92da258a480284dcc15a518ea570072329a31dErik case Utils.MODIFY_ALL: 6207b92da258a480284dcc15a518ea570072329a31dErik which = DeleteEventHelper.DELETE_ALL; 6217b92da258a480284dcc15a518ea570072329a31dErik break; 6227b92da258a480284dcc15a518ea570072329a31dErik } 6237b92da258a480284dcc15a518ea570072329a31dErik DeleteEventHelper deleteHelper = new DeleteEventHelper(mContext, mContext, 6245f62079ab9daefe95ede87631766e99e8b4a2220Erik true /* exitWhenDone */); 6257b92da258a480284dcc15a518ea570072329a31dErik // TODO update delete helper to use the model instead of the cursor 6267b92da258a480284dcc15a518ea570072329a31dErik deleteHelper.delete(begin, end, mModel, which); 62779f228124de7d98146ca526d743436f6419e2365Erik } 6287b92da258a480284dcc15a518ea570072329a31dErik 6297b92da258a480284dcc15a518ea570072329a31dErik if ((mCode & Utils.DONE_EXIT) != 0) { 6307b92da258a480284dcc15a518ea570072329a31dErik // This will exit the edit event screen, should be called 6317b92da258a480284dcc15a518ea570072329a31dErik // when we want to return to the main calendar views 6325f62079ab9daefe95ede87631766e99e8b4a2220Erik EditEventFragment.this.getActivity().finish(); 6337b92da258a480284dcc15a518ea570072329a31dErik } 6347b92da258a480284dcc15a518ea570072329a31dErik 6355c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa // Hide a software keyboard so that user won't see it even after this Fragment's 6365c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa // disappearing. 6375c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa final View focusedView = mContext.getCurrentFocus(); 6385c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa if (focusedView != null) { 6395c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa mInputMethodManager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0); 6405c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa focusedView.clearFocus(); 6415c0dec1dbf64687e36e1a26dbd9526eefa963848Daisuke Miyakawa } 64279f228124de7d98146ca526d743436f6419e2365Erik } 64379f228124de7d98146ca526d743436f6419e2365Erik } 64479f228124de7d98146ca526d743436f6419e2365Erik 64579f228124de7d98146ca526d743436f6419e2365Erik @Override 64679f228124de7d98146ca526d743436f6419e2365Erik public void onDestroy() { 647ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov if (mView != null) { 648ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov mView.setModel(null); 649ee212201f3b7dd290eb9ca99de5b4d0b9c62acfdDmitri Plotnikov } 65079f228124de7d98146ca526d743436f6419e2365Erik if (mModifyDialog != null) { 65179f228124de7d98146ca526d743436f6419e2365Erik mModifyDialog.dismiss(); 65279f228124de7d98146ca526d743436f6419e2365Erik mModifyDialog = null; 65379f228124de7d98146ca526d743436f6419e2365Erik } 6547b92da258a480284dcc15a518ea570072329a31dErik 6557b92da258a480284dcc15a518ea570072329a31dErik super.onDestroy(); 65679f228124de7d98146ca526d743436f6419e2365Erik } 657dd95df57c8c5a58a85c4c0effad5652dec14f621Erik 658dd95df57c8c5a58a85c4c0effad5652dec14f621Erik @Override 659dd95df57c8c5a58a85c4c0effad5652dec14f621Erik public void eventsChanged() { 660dd95df57c8c5a58a85c4c0effad5652dec14f621Erik // TODO Requery to see if event has changed 661dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 662dd95df57c8c5a58a85c4c0effad5652dec14f621Erik 663dd95df57c8c5a58a85c4c0effad5652dec14f621Erik @Override 66459ead671b50514b49749fcd6a1d4186a270239d2Erik public void onSaveInstanceState(Bundle outState) { 66559ead671b50514b49749fcd6a1d4186a270239d2Erik mView.prepareForSave(); 66659ead671b50514b49749fcd6a1d4186a270239d2Erik outState.putSerializable(BUNDLE_KEY_MODEL, mModel); 66759ead671b50514b49749fcd6a1d4186a270239d2Erik outState.putInt(BUNDLE_KEY_EDIT_STATE, mModification); 668c130d9d5e0d178585721428e394df0c8e0a6729fErik if (mEventBundle == null && mEvent != null) { 669c130d9d5e0d178585721428e394df0c8e0a6729fErik mEventBundle = new EventBundle(); 670c130d9d5e0d178585721428e394df0c8e0a6729fErik mEventBundle.id = mEvent.id; 671c130d9d5e0d178585721428e394df0c8e0a6729fErik if (mEvent.startTime != null) { 672c130d9d5e0d178585721428e394df0c8e0a6729fErik mEventBundle.start = mEvent.startTime.toMillis(true); 673c130d9d5e0d178585721428e394df0c8e0a6729fErik } 674c130d9d5e0d178585721428e394df0c8e0a6729fErik if (mEvent.endTime != null) { 675c130d9d5e0d178585721428e394df0c8e0a6729fErik mEventBundle.end = mEvent.startTime.toMillis(true); 676c130d9d5e0d178585721428e394df0c8e0a6729fErik } 677c130d9d5e0d178585721428e394df0c8e0a6729fErik } 678c130d9d5e0d178585721428e394df0c8e0a6729fErik 679c130d9d5e0d178585721428e394df0c8e0a6729fErik outState.putSerializable(BUNDLE_KEY_EVENT, mEventBundle); 68059ead671b50514b49749fcd6a1d4186a270239d2Erik } 68159ead671b50514b49749fcd6a1d4186a270239d2Erik 68259ead671b50514b49749fcd6a1d4186a270239d2Erik @Override 683dd95df57c8c5a58a85c4c0effad5652dec14f621Erik public long getSupportedEventTypes() { 6847b92da258a480284dcc15a518ea570072329a31dErik return EventType.USER_HOME; 685dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 686dd95df57c8c5a58a85c4c0effad5652dec14f621Erik 687dd95df57c8c5a58a85c4c0effad5652dec14f621Erik @Override 688dd95df57c8c5a58a85c4c0effad5652dec14f621Erik public void handleEvent(EventInfo event) { 6897b92da258a480284dcc15a518ea570072329a31dErik // It's currently unclear if we want to save the event or not when home 6907b92da258a480284dcc15a518ea570072329a31dErik // is pressed. When creating a new event we shouldn't save since we 6917b92da258a480284dcc15a518ea570072329a31dErik // can't get the id of the new event easily. 6927b92da258a480284dcc15a518ea570072329a31dErik if ((false && event.eventType == EventType.USER_HOME) || (event.eventType == EventType.GO_TO 6937b92da258a480284dcc15a518ea570072329a31dErik && mSaveOnDetach)) { 6947b92da258a480284dcc15a518ea570072329a31dErik if (mView != null && mView.prepareForSave()) { 6957b92da258a480284dcc15a518ea570072329a31dErik mOnDone.setDoneCode(Utils.DONE_SAVE); 6967b92da258a480284dcc15a518ea570072329a31dErik mOnDone.run(); 6977b92da258a480284dcc15a518ea570072329a31dErik } 6987b92da258a480284dcc15a518ea570072329a31dErik } 699dd95df57c8c5a58a85c4c0effad5652dec14f621Erik } 700c130d9d5e0d178585721428e394df0c8e0a6729fErik 701c130d9d5e0d178585721428e394df0c8e0a6729fErik private class EventBundle implements Serializable { 702c130d9d5e0d178585721428e394df0c8e0a6729fErik long id = -1; 703c130d9d5e0d178585721428e394df0c8e0a6729fErik long start = -1; 704c130d9d5e0d178585721428e394df0c8e0a6729fErik long end = -1; 705c130d9d5e0d178585721428e394df0c8e0a6729fErik } 70679f228124de7d98146ca526d743436f6419e2365Erik} 707