CalendarController.java 8.05 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.calendar;

Michael Chan's avatar
Michael Chan committed
19 20 21
import android.app.ActionBar;
import android.app.Activity;
import android.text.format.DateUtils;
22
import android.text.format.Time;
Michael Chan's avatar
Michael Chan committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
import android.util.Log;

import java.util.ArrayList;
import java.util.WeakHashMap;

// Go to next/previous [agenda/day/week/month]
// Go to range of days
// Go to [agenda/day/week/month] view centering on time
// Selected time and optionally event_id
//
// Setting
// Select Calendars
//
// View [event id] at x,y
// Edit [event id] at x,y
// Delete [event id]
// New event at [time]
40

Michael Chan's avatar
Michael Chan committed
41

Erik's avatar
Erik committed
42
public class CalendarController {
Michael Chan's avatar
Michael Chan committed
43 44 45 46 47 48
    private static final String TAG = "CalendarController";

    private ArrayList<EventHandler> views = new ArrayList<EventHandler>(5);
    private WeakHashMap<Object, Long> filters = new WeakHashMap<Object, Long>(1);

    private Activity mActivity;
49 50

    /**
Michael Chan's avatar
Michael Chan committed
51
     * One of the event types that are sent to or from the controller
52
     */
Erik's avatar
Erik committed
53
    public interface EventType {
Michael Chan's avatar
Michael Chan committed
54 55 56 57 58 59 60 61 62 63 64
        final long NEW_EVENT = 1L;
        final long VIEW_EVENT = 1L << 1;
        final long EDIT_EVENT = 1L << 2;
        final long DELETE_EVENT = 1L << 3;

        final long SELECT = 1L << 4;
        final long GO_TO = 1L << 5;

        final long LAUNCH_MANAGE_CALENDARS = 1L << 6;
        final long LAUNCH_SETTINGS = 1L << 7;
    }
65 66

    /**
Michael Chan's avatar
Michael Chan committed
67
     * One of the Agenda/Day/Week/Month view types
68
     */
Erik's avatar
Erik committed
69
    public interface ViewType {
Michael Chan's avatar
Michael Chan committed
70 71 72 73 74 75
        final long AGENDA = 1;
        final long DAY = 2;
        final long WEEK = 3;
        final long MONTH = 4;
    }

Erik's avatar
Erik committed
76
    public static class EventInfo {
Michael Chan's avatar
Michael Chan committed
77 78 79 80 81 82 83 84 85
        long eventType; // one of the EventType
        long viewType; // one of the ViewType
        long id; // event id
        Time startTime; // start of a range of time.
        Time endTime; // end of a range of time.
        int x; // x coordinate in the activity space
        int y; // y coordinate in the activity space
    }

Erik's avatar
Erik committed
86
    public interface EventHandler {
Michael Chan's avatar
Michael Chan committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
        long getSupportedEventTypes();
        void handleEvent(EventInfo event);

        /**
         * Returns the time in millis of the selected event in this view.
         * @return the selected time in UTC milliseconds.
         */
        long getSelectedTime();

        /**
         * Changes the view to include the given time.
         * @param time the desired time to view.
         * @animate enable animation
         */
        void goTo(Time time, boolean animate);

        /**
         * Changes the view to include today's date.
         */
        void goToToday();

        /**
         * This is called when the user wants to create a new event and returns
         * true if the new event should default to an all-day event.
         * @return true if the new event should be an all-day event.
         */
        boolean getAllDay();

        /**
         * TODO comment
         */
        void eventsChanged();

    }

    public CalendarController(Activity activity) {
        mActivity = activity;
    }
125 126

    /**
Michael Chan's avatar
Michael Chan committed
127 128 129 130 131 132 133
     * Helper for sending New/View/Edit/Delete events
     *
     * @param sender object of the caller
     * @param eventType one of {@link EventType}
     * @param eventId event id
     * @param x x coordinate in the activity space
     * @param y y coordinate in the activity space
134
     */
Erik's avatar
Erik committed
135
    public void sendEventRelatedEvent(Object sender, long eventType, long eventId, int x, int y) {
Michael Chan's avatar
Michael Chan committed
136 137 138 139 140 141 142
        EventInfo info = new EventInfo();
        info.eventType = eventType;
        info.id = eventId;
        info.x = x;
        info.y = y;
        this.sendEvent(sender, info);
    }
143 144

    /**
Michael Chan's avatar
Michael Chan committed
145 146 147 148 149 150 151 152
     * Helper for sending non-calendar-event events
     *
     * @param sender object of the caller
     * @param eventType one of {@link EventType}
     * @param eventId event id
     * @param start start time
     * @param end end time
     * @param viewType {@link ViewType}
153
     */
Erik's avatar
Erik committed
154
    public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId,
Michael Chan's avatar
Michael Chan committed
155 156 157 158 159 160 161 162 163 164
            long viewType) {
        EventInfo info = new EventInfo();
        info.eventType = eventType;
        info.startTime = start;
        info.endTime = end;
        info.id = eventId;
        info.viewType = viewType;
        this.sendEvent(sender, info);
    }

Erik's avatar
Erik committed
165
    public void sendEvent(Object sender, final EventInfo event) {
Michael Chan's avatar
Michael Chan committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
        // TODO Throw exception on invalid events

        Log.d(TAG, eventInfoToString(event));

        Long filteredTypes = filters.get(sender);
        if (filteredTypes != null && (filteredTypes.longValue() & event.eventType) != 0) {
            // Suppress event per filter
            Log.d(TAG, "Event suppressed");
            return;
        }

        // TODO Move to ActionBar?
        setTitleInActionBar(event);

        // Dispatch to view(s)
        for (EventHandler view : views) {
//            Log.d(TAG, "eventInfo = " + view);
            if (view != null) {
                boolean supportedEvent = (view.getSupportedEventTypes() & event.eventType) != 0;
                if (supportedEvent) {
                    view.handleEvent(event);
                }
            }
        }
    }

Erik's avatar
Erik committed
192
    public void registerView(EventHandler view) {
Michael Chan's avatar
Michael Chan committed
193 194 195
        views.add(view);
    }

Erik's avatar
Erik committed
196
    public void deregisterView(EventHandler view) {
Michael Chan's avatar
Michael Chan committed
197 198 199
        views.remove(view);
    }

Erik's avatar
Erik committed
200
    public void filterBroadcasts(Object sender, long eventTypes) {
Michael Chan's avatar
Michael Chan committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
        filters.put(sender, eventTypes);
    }

    private void setTitleInActionBar(EventInfo event) {
        if (event.eventType != EventType.SELECT && event.eventType != EventType.GO_TO) {
            return;
        }

        long start = event.startTime.toMillis(false /* use isDst */);
        long end = start;

        if (event.endTime != null && !event.startTime.equals(event.endTime)) {
            end = event.endTime.toMillis(false /* use isDst */);
        }
        String msg = DateUtils.formatDateRange(mActivity, start, end, DateUtils.FORMAT_SHOW_DATE
                | DateUtils.FORMAT_ABBREV_MONTH);

        ActionBar ab = mActivity.getActionBar();
        if (ab != null) {
            ab.setTitle(msg);
        }
    }

    private String eventInfoToString(EventInfo eventInfo) {
        String tmp = "Unknown";

        StringBuilder builder = new StringBuilder();
        if ((eventInfo.eventType & EventType.SELECT) != 0) {
            tmp = "Select time/event";
        } else if ((eventInfo.eventType & EventType.GO_TO) != 0) {
            tmp = "Go to time/event";
        } else if ((eventInfo.eventType & EventType.NEW_EVENT) != 0) {
            tmp = "New event";
        } else if ((eventInfo.eventType & EventType.VIEW_EVENT) != 0) {
            tmp = "View event";
        } else if ((eventInfo.eventType & EventType.EDIT_EVENT) != 0) {
            tmp = "Edit event";
        } else if ((eventInfo.eventType & EventType.DELETE_EVENT) != 0) {
            tmp = "Delete event";
        } else if ((eventInfo.eventType & EventType.LAUNCH_MANAGE_CALENDARS) != 0) {
            tmp = "Launch select calendar";
        } else if ((eventInfo.eventType & EventType.LAUNCH_SETTINGS) != 0) {
            tmp = "Launch settings";
        }
        builder.append(tmp);
        builder.append(": id=");
        builder.append(eventInfo.id);
        builder.append(", startTime=");
        builder.append(eventInfo.startTime);
        builder.append(", endTime=");
        builder.append(eventInfo.endTime);
        builder.append(", viewType=");
        builder.append(eventInfo.viewType);
        builder.append(", x=");
        builder.append(eventInfo.x);
        builder.append(", y=");
        builder.append(eventInfo.y);
        return builder.toString();
    }
260
}