CalendarController.java revision 9e89dca0902d13fe27fd2680cc15cbb470e40288
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.calendar; 18 19import static android.provider.Calendar.EVENT_BEGIN_TIME; 20import static android.provider.Calendar.EVENT_END_TIME; 21 22import android.app.ActionBar; 23import android.app.Activity; 24import android.content.ContentUris; 25import android.content.Intent; 26import android.net.Uri; 27import android.provider.Calendar.Events; 28import android.text.format.DateUtils; 29import android.text.format.Time; 30import android.util.Log; 31 32import java.util.ArrayList; 33import java.util.WeakHashMap; 34 35// Go to next/previous [agenda/day/week/month] 36// Go to range of days 37// Go to [agenda/day/week/month] view centering on time 38// Selected time and optionally event_id 39// 40// Setting 41// Select Calendars 42// 43// View [event id] at x,y 44// Edit [event id] at x,y 45// Delete [event id] 46// New event at [time] 47 48 49public class CalendarController { 50 private static final String TAG = "CalendarController"; 51 52 private ArrayList<EventHandler> views = new ArrayList<EventHandler>(5); 53 private WeakHashMap<Object, Long> filters = new WeakHashMap<Object, Long>(1); 54 55 private Activity mActivity; 56 57 /** 58 * One of the event types that are sent to or from the controller 59 */ 60 public interface EventType { 61 final long CREATE_EVENT = 1L; 62 final long VIEW_EVENT = 1L << 1; 63 final long EDIT_EVENT = 1L << 2; 64 final long DELETE_EVENT = 1L << 3; 65 66 final long SELECT = 1L << 4; 67 final long GO_TO = 1L << 5; 68 69 final long LAUNCH_MANAGE_CALENDARS = 1L << 6; 70 final long LAUNCH_SETTINGS = 1L << 7; 71 } 72 73 /** 74 * One of the Agenda/Day/Week/Month view types 75 */ 76 public interface ViewType { 77 final long AGENDA = 1; 78 final long DAY = 2; 79 final long WEEK = 3; 80 final long MONTH = 4; 81 } 82 83 public static class EventInfo { 84 long eventType; // one of the EventType 85 long viewType; // one of the ViewType 86 long id; // event id 87 Time startTime; // start of a range of time. 88 Time endTime; // end of a range of time. 89 int x; // x coordinate in the activity space 90 int y; // y coordinate in the activity space 91 } 92 93 public interface EventHandler { 94 long getSupportedEventTypes(); 95 void handleEvent(EventInfo event); 96 97 /** 98 * Returns the time in millis of the selected event in this view. 99 * @return the selected time in UTC milliseconds. 100 */ 101 long getSelectedTime(); 102 103 /** 104 * Changes the view to include the given time. 105 * @param time the desired time to view. 106 * @animate enable animation 107 */ 108 void goTo(Time time, boolean animate); 109 110 /** 111 * Changes the view to include today's date. 112 */ 113 void goToToday(); 114 115 /** 116 * This is called when the user wants to create a new event and returns 117 * true if the new event should default to an all-day event. 118 * @return true if the new event should be an all-day event. 119 */ 120 boolean getAllDay(); 121 122 /** 123 * TODO comment 124 */ 125 void eventsChanged(); 126 127 } 128 129 public CalendarController(Activity activity) { 130 mActivity = activity; 131 } 132 133 /** 134 * Helper for sending New/View/Edit/Delete events 135 * 136 * @param sender object of the caller 137 * @param eventType one of {@link EventType} 138 * @param eventId event id 139 * @param start start time 140 * @param end end time 141 * @param x x coordinate in the activity space 142 * @param y y coordinate in the activity space 143 */ 144 public void sendEventRelatedEvent(Object sender, long eventType, long eventId, long startMillis, 145 long endMillis, int x, int y) { 146 EventInfo info = new EventInfo(); 147 info.eventType = eventType; 148 info.id = eventId; 149 info.startTime = new Time(); 150 info.startTime.set(startMillis); 151 info.endTime = new Time(); 152 info.endTime.set(endMillis); 153 info.x = x; 154 info.y = y; 155 this.sendEvent(sender, info); 156 } 157 158 /** 159 * Helper for sending non-calendar-event events 160 * 161 * @param sender object of the caller 162 * @param eventType one of {@link EventType} 163 * @param eventId event id 164 * @param start start time 165 * @param end end time 166 * @param viewType {@link ViewType} 167 */ 168 public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId, 169 long viewType) { 170 EventInfo info = new EventInfo(); 171 info.eventType = eventType; 172 info.startTime = start; 173 info.endTime = end; 174 info.id = eventId; 175 info.viewType = viewType; 176 this.sendEvent(sender, info); 177 } 178 179 public void sendEvent(Object sender, final EventInfo event) { 180 // TODO Throw exception on invalid events 181 182 Log.d(TAG, eventInfoToString(event)); 183 184 Long filteredTypes = filters.get(sender); 185 if (filteredTypes != null && (filteredTypes.longValue() & event.eventType) != 0) { 186 // Suppress event per filter 187 Log.d(TAG, "Event suppressed"); 188 return; 189 } 190 191 // Create/View/Edit/Delete Event, Calendars, and Settings 192 long endTime = (event.endTime == null) ? -1 : event.endTime.toMillis(false); 193 if (event.eventType == EventType.CREATE_EVENT) { 194 launchCreateEvent(event.startTime.toMillis(false), endTime); 195 return; 196 } else if (event.eventType == EventType.VIEW_EVENT) { 197 launchViewEvent(event.id, event.startTime.toMillis(false), endTime); 198 return; 199 } else if (event.eventType == EventType.EDIT_EVENT) { 200 launchEditEvent(event.id, event.startTime.toMillis(false), endTime); 201 return; 202 } else if (event.eventType == EventType.DELETE_EVENT) { 203 launchDeleteEvent(event.id, event.startTime.toMillis(false), endTime); 204 return; 205 } else if (event.eventType == EventType.LAUNCH_MANAGE_CALENDARS) { 206 launchManageCalendars(); 207 return; 208 } else if (event.eventType == EventType.LAUNCH_SETTINGS) { 209 launchSettings(); 210 return; 211 } 212 213 // TODO Move to ActionBar? 214 setTitleInActionBar(event); 215 216 // Dispatch to view(s) 217 for (EventHandler view : views) { 218 if (view != null) { 219 boolean supportedEvent = (view.getSupportedEventTypes() & event.eventType) != 0; 220 if (supportedEvent) { 221 view.handleEvent(event); 222 } 223 } 224 } 225 } 226 227 public void registerView(EventHandler view) { 228 views.add(view); 229 } 230 231 public void deregisterView(EventHandler view) { 232 views.remove(view); 233 } 234 235 public void filterBroadcasts(Object sender, long eventTypes) { 236 filters.put(sender, eventTypes); 237 } 238 239 private void setTitleInActionBar(EventInfo event) { 240 if (event.eventType != EventType.SELECT && event.eventType != EventType.GO_TO) { 241 return; 242 } 243 244 long start = event.startTime.toMillis(false /* use isDst */); 245 long end = start; 246 247 if (event.endTime != null && !event.startTime.equals(event.endTime)) { 248 end = event.endTime.toMillis(false /* use isDst */); 249 } 250 String msg = DateUtils.formatDateRange(mActivity, start, end, DateUtils.FORMAT_SHOW_DATE); 251 252 ActionBar ab = mActivity.getActionBar(); 253 if (ab != null) { 254 ab.setTitle(msg); 255 } 256 } 257 258 private String eventInfoToString(EventInfo eventInfo) { 259 String tmp = "Unknown"; 260 261 StringBuilder builder = new StringBuilder(); 262 if ((eventInfo.eventType & EventType.SELECT) != 0) { 263 tmp = "Select time/event"; 264 } else if ((eventInfo.eventType & EventType.GO_TO) != 0) { 265 tmp = "Go to time/event"; 266 } else if ((eventInfo.eventType & EventType.CREATE_EVENT) != 0) { 267 tmp = "New event"; 268 } else if ((eventInfo.eventType & EventType.VIEW_EVENT) != 0) { 269 tmp = "View event"; 270 } else if ((eventInfo.eventType & EventType.EDIT_EVENT) != 0) { 271 tmp = "Edit event"; 272 } else if ((eventInfo.eventType & EventType.DELETE_EVENT) != 0) { 273 tmp = "Delete event"; 274 } else if ((eventInfo.eventType & EventType.LAUNCH_MANAGE_CALENDARS) != 0) { 275 tmp = "Launch select calendar"; 276 } else if ((eventInfo.eventType & EventType.LAUNCH_SETTINGS) != 0) { 277 tmp = "Launch settings"; 278 } 279 builder.append(tmp); 280 builder.append(": id="); 281 builder.append(eventInfo.id); 282 builder.append(", startTime="); 283 builder.append(eventInfo.startTime); 284 builder.append(", endTime="); 285 builder.append(eventInfo.endTime); 286 builder.append(", viewType="); 287 builder.append(eventInfo.viewType); 288 builder.append(", x="); 289 builder.append(eventInfo.x); 290 builder.append(", y="); 291 builder.append(eventInfo.y); 292 return builder.toString(); 293 } 294 295 private void launchManageCalendars() { 296 Intent intent = new Intent(Intent.ACTION_VIEW); 297 intent.setClass(mActivity, SelectCalendarsActivity.class); 298 intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 299 mActivity.startActivity(intent); 300 } 301 302 private void launchSettings() { 303 Intent intent = new Intent(Intent.ACTION_VIEW); 304 intent.setClassName(mActivity, CalendarPreferenceActivity.class.getName()); 305 intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 306 mActivity.startActivity(intent); 307 } 308 309 private void launchCreateEvent(long startMillis, long endMillis) { 310 Intent intent = new Intent(Intent.ACTION_VIEW); 311 intent.setClassName(mActivity, EditEventActivity.class.getName()); 312 intent.putExtra(EVENT_BEGIN_TIME, startMillis); 313 intent.putExtra(EVENT_END_TIME, endMillis); 314 mActivity.startActivity(intent); 315 } 316 317 private void launchViewEvent(long eventId, long startMillis, long endMillis) { 318 Intent intent = new Intent(Intent.ACTION_VIEW); 319 Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId); 320 intent.setData(eventUri); 321 intent.setClassName(mActivity, EventInfoActivity.class.getName()); 322 intent.putExtra(EVENT_BEGIN_TIME, startMillis); 323 intent.putExtra(EVENT_END_TIME, endMillis); 324 mActivity.startActivity(intent); 325 } 326 327 private void launchEditEvent(long eventId, long startMillis, long endMillis) { 328 Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId); 329 Intent intent = new Intent(Intent.ACTION_EDIT, uri); 330 intent.putExtra(EVENT_BEGIN_TIME, startMillis); 331 intent.putExtra(EVENT_END_TIME, endMillis); 332 intent.setClass(mActivity, EditEventActivity.class); 333 mActivity.startActivity(intent); 334 } 335 336 private void launchDeleteEvent(long eventId, long startMillis, long endMillis) { 337 launchDeleteEventAndFinish(null, eventId, startMillis, endMillis, -1); 338 } 339 340 private void launchDeleteEventAndFinish(Activity parentActivity, long eventId, long startMillis, 341 long endMillis, int deleteWhich) { 342 DeleteEventHelper deleteEventHelper = new DeleteEventHelper(mActivity, parentActivity, 343 parentActivity != null /* exit when done */); 344 deleteEventHelper.delete(startMillis, endMillis, eventId, deleteWhich); 345 } 346} 347