Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 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 | |
| 17 | package com.android.calendar; |
| 18 | |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 19 | import android.app.ActionBar; |
| 20 | import android.app.Activity; |
| 21 | import android.text.format.DateUtils; |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 22 | import android.text.format.Time; |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 23 | import android.util.Log; |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 24 | |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 25 | import java.util.ArrayList; |
| 26 | import java.util.WeakHashMap; |
| 27 | |
| 28 | // Go to next/previous [agenda/day/week/month] |
| 29 | // Go to range of days |
| 30 | // Go to [agenda/day/week/month] view centering on time |
| 31 | // Selected time and optionally event_id |
| 32 | // |
| 33 | // Setting |
| 34 | // Select Calendars |
| 35 | // |
| 36 | // View [event id] at x,y |
| 37 | // Edit [event id] at x,y |
| 38 | // Delete [event id] |
| 39 | // New event at [time] |
| 40 | |
| 41 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 42 | public class CalendarController { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 43 | private static final String TAG = "CalendarController"; |
| 44 | |
| 45 | private ArrayList<EventHandler> views = new ArrayList<EventHandler>(5); |
| 46 | private WeakHashMap<Object, Long> filters = new WeakHashMap<Object, Long>(1); |
| 47 | |
| 48 | private Activity mActivity; |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 49 | |
| 50 | /** |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 51 | * One of the event types that are sent to or from the controller |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 52 | */ |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 53 | public interface EventType { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 54 | final long NEW_EVENT = 1L; |
| 55 | final long VIEW_EVENT = 1L << 1; |
| 56 | final long EDIT_EVENT = 1L << 2; |
| 57 | final long DELETE_EVENT = 1L << 3; |
| 58 | |
| 59 | final long SELECT = 1L << 4; |
| 60 | final long GO_TO = 1L << 5; |
| 61 | |
| 62 | final long LAUNCH_MANAGE_CALENDARS = 1L << 6; |
| 63 | final long LAUNCH_SETTINGS = 1L << 7; |
| 64 | } |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 65 | |
| 66 | /** |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 67 | * One of the Agenda/Day/Week/Month view types |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 68 | */ |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 69 | public interface ViewType { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 70 | final long AGENDA = 1; |
| 71 | final long DAY = 2; |
| 72 | final long WEEK = 3; |
| 73 | final long MONTH = 4; |
| 74 | } |
| 75 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 76 | public static class EventInfo { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 77 | long eventType; // one of the EventType |
| 78 | long viewType; // one of the ViewType |
| 79 | long id; // event id |
| 80 | Time startTime; // start of a range of time. |
| 81 | Time endTime; // end of a range of time. |
| 82 | int x; // x coordinate in the activity space |
| 83 | int y; // y coordinate in the activity space |
| 84 | } |
| 85 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 86 | public interface EventHandler { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 87 | long getSupportedEventTypes(); |
| 88 | void handleEvent(EventInfo event); |
| 89 | |
| 90 | /** |
| 91 | * Returns the time in millis of the selected event in this view. |
| 92 | * @return the selected time in UTC milliseconds. |
| 93 | */ |
| 94 | long getSelectedTime(); |
| 95 | |
| 96 | /** |
| 97 | * Changes the view to include the given time. |
| 98 | * @param time the desired time to view. |
| 99 | * @animate enable animation |
| 100 | */ |
| 101 | void goTo(Time time, boolean animate); |
| 102 | |
| 103 | /** |
| 104 | * Changes the view to include today's date. |
| 105 | */ |
| 106 | void goToToday(); |
| 107 | |
| 108 | /** |
| 109 | * This is called when the user wants to create a new event and returns |
| 110 | * true if the new event should default to an all-day event. |
| 111 | * @return true if the new event should be an all-day event. |
| 112 | */ |
| 113 | boolean getAllDay(); |
| 114 | |
| 115 | /** |
| 116 | * TODO comment |
| 117 | */ |
| 118 | void eventsChanged(); |
| 119 | |
| 120 | } |
| 121 | |
| 122 | public CalendarController(Activity activity) { |
| 123 | mActivity = activity; |
| 124 | } |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 125 | |
| 126 | /** |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 127 | * Helper for sending New/View/Edit/Delete events |
| 128 | * |
| 129 | * @param sender object of the caller |
| 130 | * @param eventType one of {@link EventType} |
| 131 | * @param eventId event id |
| 132 | * @param x x coordinate in the activity space |
| 133 | * @param y y coordinate in the activity space |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 134 | */ |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 135 | public void sendEventRelatedEvent(Object sender, long eventType, long eventId, int x, int y) { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 136 | EventInfo info = new EventInfo(); |
| 137 | info.eventType = eventType; |
| 138 | info.id = eventId; |
| 139 | info.x = x; |
| 140 | info.y = y; |
| 141 | this.sendEvent(sender, info); |
| 142 | } |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 143 | |
| 144 | /** |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 145 | * Helper for sending non-calendar-event events |
| 146 | * |
| 147 | * @param sender object of the caller |
| 148 | * @param eventType one of {@link EventType} |
| 149 | * @param eventId event id |
| 150 | * @param start start time |
| 151 | * @param end end time |
| 152 | * @param viewType {@link ViewType} |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 153 | */ |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 154 | public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId, |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 155 | long viewType) { |
| 156 | EventInfo info = new EventInfo(); |
| 157 | info.eventType = eventType; |
| 158 | info.startTime = start; |
| 159 | info.endTime = end; |
| 160 | info.id = eventId; |
| 161 | info.viewType = viewType; |
| 162 | this.sendEvent(sender, info); |
| 163 | } |
| 164 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 165 | public void sendEvent(Object sender, final EventInfo event) { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 166 | // TODO Throw exception on invalid events |
| 167 | |
| 168 | Log.d(TAG, eventInfoToString(event)); |
| 169 | |
| 170 | Long filteredTypes = filters.get(sender); |
| 171 | if (filteredTypes != null && (filteredTypes.longValue() & event.eventType) != 0) { |
| 172 | // Suppress event per filter |
| 173 | Log.d(TAG, "Event suppressed"); |
| 174 | return; |
| 175 | } |
| 176 | |
| 177 | // TODO Move to ActionBar? |
| 178 | setTitleInActionBar(event); |
| 179 | |
| 180 | // Dispatch to view(s) |
| 181 | for (EventHandler view : views) { |
| 182 | // Log.d(TAG, "eventInfo = " + view); |
| 183 | if (view != null) { |
| 184 | boolean supportedEvent = (view.getSupportedEventTypes() & event.eventType) != 0; |
| 185 | if (supportedEvent) { |
| 186 | view.handleEvent(event); |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 192 | public void registerView(EventHandler view) { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 193 | views.add(view); |
| 194 | } |
| 195 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 196 | public void deregisterView(EventHandler view) { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 197 | views.remove(view); |
| 198 | } |
| 199 | |
Erik | 2525119 | 2010-07-12 15:30:14 -0700 | [diff] [blame^] | 200 | public void filterBroadcasts(Object sender, long eventTypes) { |
Michael Chan | 83b0fe3 | 2010-07-08 16:46:26 -0700 | [diff] [blame] | 201 | filters.put(sender, eventTypes); |
| 202 | } |
| 203 | |
| 204 | private void setTitleInActionBar(EventInfo event) { |
| 205 | if (event.eventType != EventType.SELECT && event.eventType != EventType.GO_TO) { |
| 206 | return; |
| 207 | } |
| 208 | |
| 209 | long start = event.startTime.toMillis(false /* use isDst */); |
| 210 | long end = start; |
| 211 | |
| 212 | if (event.endTime != null && !event.startTime.equals(event.endTime)) { |
| 213 | end = event.endTime.toMillis(false /* use isDst */); |
| 214 | } |
| 215 | String msg = DateUtils.formatDateRange(mActivity, start, end, DateUtils.FORMAT_SHOW_DATE |
| 216 | | DateUtils.FORMAT_ABBREV_MONTH); |
| 217 | |
| 218 | ActionBar ab = mActivity.getActionBar(); |
| 219 | if (ab != null) { |
| 220 | ab.setTitle(msg); |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | private String eventInfoToString(EventInfo eventInfo) { |
| 225 | String tmp = "Unknown"; |
| 226 | |
| 227 | StringBuilder builder = new StringBuilder(); |
| 228 | if ((eventInfo.eventType & EventType.SELECT) != 0) { |
| 229 | tmp = "Select time/event"; |
| 230 | } else if ((eventInfo.eventType & EventType.GO_TO) != 0) { |
| 231 | tmp = "Go to time/event"; |
| 232 | } else if ((eventInfo.eventType & EventType.NEW_EVENT) != 0) { |
| 233 | tmp = "New event"; |
| 234 | } else if ((eventInfo.eventType & EventType.VIEW_EVENT) != 0) { |
| 235 | tmp = "View event"; |
| 236 | } else if ((eventInfo.eventType & EventType.EDIT_EVENT) != 0) { |
| 237 | tmp = "Edit event"; |
| 238 | } else if ((eventInfo.eventType & EventType.DELETE_EVENT) != 0) { |
| 239 | tmp = "Delete event"; |
| 240 | } else if ((eventInfo.eventType & EventType.LAUNCH_MANAGE_CALENDARS) != 0) { |
| 241 | tmp = "Launch select calendar"; |
| 242 | } else if ((eventInfo.eventType & EventType.LAUNCH_SETTINGS) != 0) { |
| 243 | tmp = "Launch settings"; |
| 244 | } |
| 245 | builder.append(tmp); |
| 246 | builder.append(": id="); |
| 247 | builder.append(eventInfo.id); |
| 248 | builder.append(", startTime="); |
| 249 | builder.append(eventInfo.startTime); |
| 250 | builder.append(", endTime="); |
| 251 | builder.append(eventInfo.endTime); |
| 252 | builder.append(", viewType="); |
| 253 | builder.append(eventInfo.viewType); |
| 254 | builder.append(", x="); |
| 255 | builder.append(eventInfo.x); |
| 256 | builder.append(", y="); |
| 257 | builder.append(eventInfo.y); |
| 258 | return builder.toString(); |
| 259 | } |
Michael Chan | 4970159 | 2010-06-30 11:04:03 -0700 | [diff] [blame] | 260 | } |