Event.java revision 25996100d6ea61888ebe54d7708a9a371bb12a55
1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/*
2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2007 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
19a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.content.ContentResolver;
20a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.content.ContentUris;
21146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context;
22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.SharedPreferences;
23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.res.Resources;
24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor;
2525996100d6ea61888ebe54d7708a9a371bb12a55RoboErikimport android.graphics.Color;
26a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.net.Uri;
27146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.os.Debug;
28a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.provider.CalendarContract;
29a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees;
30a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.provider.CalendarContract.Calendars;
31a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events;
32a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Instances;
33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.TextUtils;
34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateUtils;
35146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time;
36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.util.Log;
37146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.ArrayList;
39a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport java.util.Arrays;
40146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.Iterator;
41146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger;
42146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project// TODO: should Event be Parcelable so it can be passed via Intents?
441d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErikpublic class Event implements Cloneable {
45146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
46981874e61ecf29a96a77601a3172b2503b6537eeErik    private static final String TAG = "CalEvent";
47146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final boolean PROFILE = false;
48146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
492fda24534978f55711526dbde747aa50d68dec40RoboErik    /**
502fda24534978f55711526dbde747aa50d68dec40RoboErik     * The sort order is:
51ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * 1) events with an earlier start (begin for normal events, startday for allday)
52ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * 2) events with a later end (end for normal events, endday for allday)
53ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * 3) the title (unnecessary, but nice)
542fda24534978f55711526dbde747aa50d68dec40RoboErik     *
552fda24534978f55711526dbde747aa50d68dec40RoboErik     * The start and end day is sorted first so that all day events are
562fda24534978f55711526dbde747aa50d68dec40RoboErik     * sorted correctly with respect to events that are >24 hours (and
572fda24534978f55711526dbde747aa50d68dec40RoboErik     * therefore show up in the allday area).
582fda24534978f55711526dbde747aa50d68dec40RoboErik     */
592fda24534978f55711526dbde747aa50d68dec40RoboErik    private static final String SORT_EVENTS_BY =
60ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            "begin ASC, end DESC, title ASC";
61ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static final String SORT_ALLDAY_BY =
62ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            "startDay ASC, endDay DESC, title ASC";
63ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static final String DISPLAY_AS_ALLDAY = "dispAllday";
64ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik
65ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static final String EVENTS_WHERE = DISPLAY_AS_ALLDAY + "=0";
66ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static final String ALLDAY_WHERE = DISPLAY_AS_ALLDAY + "=1";
672fda24534978f55711526dbde747aa50d68dec40RoboErik
68981874e61ecf29a96a77601a3172b2503b6537eeErik    // The projection to use when querying instances to build a list of events
69981874e61ecf29a96a77601a3172b2503b6537eeErik    public static final String[] EVENT_PROJECTION = new String[] {
70146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.TITLE,                 // 0
71146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.EVENT_LOCATION,        // 1
72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.ALL_DAY,               // 2
730e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik            Instances.CALENDAR_COLOR,        // 3
74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.EVENT_TIMEZONE,        // 4
75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.EVENT_ID,              // 5
76146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.BEGIN,                 // 6
77146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.END,                   // 7
78146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances._ID,                   // 8
79146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.START_DAY,             // 9
80146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.END_DAY,               // 10
81146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.START_MINUTE,          // 11
82146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.END_MINUTE,            // 12
83146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.HAS_ALARM,             // 13
84146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.RRULE,                 // 14
85146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.RDATE,                 // 15
86146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.SELF_ATTENDEE_STATUS,  // 16
876d34cec523930368976bc8d358d0a6de1da3462cMichael Chan            Events.ORGANIZER,                // 17
886d34cec523930368976bc8d358d0a6de1da3462cMichael Chan            Events.GUESTS_CAN_MODIFY,        // 18
89ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            Instances.ALL_DAY + "=1 OR (" + Instances.END + "-" + Instances.BEGIN + ")>="
90ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                    + DateUtils.DAY_IN_MILLIS + " AS " + DISPLAY_AS_ALLDAY, // 19
91146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    };
92146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
93146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // The indices for the projection array above.
94146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_TITLE_INDEX = 0;
95146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_LOCATION_INDEX = 1;
96146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_ALL_DAY_INDEX = 2;
97146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_COLOR_INDEX = 3;
98146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_TIMEZONE_INDEX = 4;
99146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_EVENT_ID_INDEX = 5;
100146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_BEGIN_INDEX = 6;
101146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_END_INDEX = 7;
102146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_START_DAY_INDEX = 9;
103146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_END_DAY_INDEX = 10;
104146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_START_MINUTE_INDEX = 11;
105146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_END_MINUTE_INDEX = 12;
106146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_HAS_ALARM_INDEX = 13;
107146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_RRULE_INDEX = 14;
108146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_RDATE_INDEX = 15;
109146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_SELF_ATTENDEE_STATUS_INDEX = 16;
1106d34cec523930368976bc8d358d0a6de1da3462cMichael Chan    private static final int PROJECTION_ORGANIZER_INDEX = 17;
1116d34cec523930368976bc8d358d0a6de1da3462cMichael Chan    private static final int PROJECTION_GUESTS_CAN_INVITE_OTHERS_INDEX = 18;
112ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static final int PROJECTION_DISPLAY_AS_ALLDAY = 19;
113ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik
11425996100d6ea61888ebe54d7708a9a371bb12a55RoboErik    private static final float SATURATION_ADJUST = 0.3f;
115ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static String mNoTitleString;
116ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static int mNoColorColor;
117146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
118146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long id;
119146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int color;
120146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public CharSequence title;
121146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public CharSequence location;
122146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean allDay;
1236d34cec523930368976bc8d358d0a6de1da3462cMichael Chan    public String organizer;
1246d34cec523930368976bc8d358d0a6de1da3462cMichael Chan    public boolean guestsCanModify;
125146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
126146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int startDay;       // start Julian day
127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int endDay;         // end Julian day
128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int startTime;      // Start and end time are in minutes since midnight
129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int endTime;
130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long startMillis;   // UTC milliseconds since the epoch
132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long endMillis;     // UTC milliseconds since the epoch
133146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private int mColumn;
134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private int mMaxColumns;
135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
136146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean hasAlarm;
137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean isRepeating;
138981874e61ecf29a96a77601a3172b2503b6537eeErik
139146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int selfAttendeeStatus;
140146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
141146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // The coordinates of the event rectangle drawn on the screen.
142146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float left;
143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float right;
144146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float top;
145146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float bottom;
146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
147146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // These 4 fields are used for navigating among events within the selected
148146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // hour in the Day and Week view.
149146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextRight;
150146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextLeft;
151146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextUp;
152146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextDown;
153146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
154146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
15598ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan    public final Object clone() throws CloneNotSupportedException {
15698ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan        super.clone();
157146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Event e = new Event();
158146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
159146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.title = title;
160146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.color = color;
161146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.location = location;
162146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.allDay = allDay;
163146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startDay = startDay;
164146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endDay = endDay;
165146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startTime = startTime;
166146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endTime = endTime;
167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startMillis = startMillis;
168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endMillis = endMillis;
169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.hasAlarm = hasAlarm;
170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.isRepeating = isRepeating;
171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.selfAttendeeStatus = selfAttendeeStatus;
1726d34cec523930368976bc8d358d0a6de1da3462cMichael Chan        e.organizer = organizer;
1736d34cec523930368976bc8d358d0a6de1da3462cMichael Chan        e.guestsCanModify = guestsCanModify;
174146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
175146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return e;
176146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
177146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
178146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final void copyTo(Event dest) {
179146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.id = id;
180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.title = title;
181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.color = color;
182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.location = location;
183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.allDay = allDay;
184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.startDay = startDay;
185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.endDay = endDay;
186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.startTime = startTime;
187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.endTime = endTime;
188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.startMillis = startMillis;
189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.endMillis = endMillis;
190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.hasAlarm = hasAlarm;
191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.isRepeating = isRepeating;
192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.selfAttendeeStatus = selfAttendeeStatus;
1936d34cec523930368976bc8d358d0a6de1da3462cMichael Chan        dest.organizer = organizer;
1946d34cec523930368976bc8d358d0a6de1da3462cMichael Chan        dest.guestsCanModify = guestsCanModify;
195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static final Event newInstance() {
198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Event e = new Event();
199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
200146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.id = 0;
201146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.title = null;
202146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.color = 0;
203146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.location = null;
204146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.allDay = false;
205146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startDay = 0;
206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endDay = 0;
207146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startTime = 0;
208146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endTime = 0;
209146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startMillis = 0;
210146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endMillis = 0;
211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.hasAlarm = false;
212146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.isRepeating = false;
213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.selfAttendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
214146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
215146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return e;
216146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
217146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
218146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
219146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Loads <i>days</i> days worth of instances starting at <i>start</i>.
220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
221146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static void loadEvents(Context context, ArrayList<Event> events,
222146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            long start, int days, int requestId, AtomicInteger sequenceNumber) {
223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (PROFILE) {
225146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Debug.startMethodTracing("loadEvents");
226146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
228ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        Cursor cEvents = null;
229ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        Cursor cAllday = null;
230146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
231146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        events.clear();
232146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        try {
233146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Time local = new Time();
234146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
235146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            local.set(start);
236146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int startDay = Time.getJulianDay(start, local.gmtoff);
237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int endDay = startDay + days;
238146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            local.monthDay += days;
240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            long end = local.normalize(true /* ignore isDst */);
241146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Widen the time range that we query by one day on each end
243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // so that we can catch all-day events.  All-day events are
244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // stored starting at midnight in UTC but should be included
245146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // in the list of events starting at midnight local time.
246146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // This may fetch more events than we actually want, so we
247146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // filter them out below.
248146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            //
249146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // The sort order is: events with an earlier start time occur
250146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // first and if the start times are the same, then events with
251146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // a later end time occur first. The later end time is ordered
252146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // first so that long rectangles in the calendar views appear on
253146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the left side.  If the start and end times of two events are
254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the same then we sort alphabetically on the title.  This isn't
255146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // required for correctness, it just adds a nice touch.
256146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Respect the preference to show/hide declined events
2584b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa            SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context);
2594b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa            boolean hideDeclined = prefs.getBoolean(GeneralPreferences.KEY_HIDE_DECLINED,
260146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    false);
261146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
262ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            String where = EVENTS_WHERE;
263ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            String whereAllday = ALLDAY_WHERE;
264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (hideDeclined) {
265ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                String hideString = " AND " + Instances.SELF_ATTENDEE_STATUS + "!="
266ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                        + Attendees.ATTENDEE_STATUS_DECLINED;
267ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                where += hideString;
268ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                whereAllday += hideString;
269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
271a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            cEvents = instancesQuery(context.getContentResolver(), EVENT_PROJECTION,
272ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                    start - DateUtils.DAY_IN_MILLIS, end + DateUtils.DAY_IN_MILLIS, where,
27362e59a8145c5cd32e08e4453f68bbc69d9775a64RoboErik                    null, SORT_EVENTS_BY);
274a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            cAllday = instancesQuery(context.getContentResolver(), EVENT_PROJECTION,
275ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                    start - DateUtils.DAY_IN_MILLIS, end + DateUtils.DAY_IN_MILLIS, whereAllday,
27662e59a8145c5cd32e08e4453f68bbc69d9775a64RoboErik                    null, SORT_ALLDAY_BY);
277146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
278146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Check if we should return early because there are more recent
279146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // load requests waiting.
280146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (requestId != sequenceNumber.get()) {
281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return;
282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
284ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            buildEventsFromCursor(events, cEvents, context, startDay, endDay);
285ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            buildEventsFromCursor(events, cAllday, context, startDay, endDay);
286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
287146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } finally {
288ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            if (cEvents != null) {
289ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                cEvents.close();
290ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            }
291ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            if (cAllday != null) {
292ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik                cAllday.close();
293146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
294146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (PROFILE) {
295146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Debug.stopMethodTracing();
296146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
297146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
298146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
299146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
300ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    /**
301a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * Performs a query to return all visible instances in the given range
302a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * that match the given selection. This is a blocking function and
303a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * should not be done on the UI thread. This will cause an expansion of
304a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * recurring events to fill this time range if they are not already
305a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * expanded and will slow down for larger time ranges with many
306a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * recurring events.
307a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     *
308a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param cr The ContentResolver to use for the query
309a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param projection The columns to return
310a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param begin The start of the time range to query in UTC millis since
311a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     *            epoch
312a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param end The end of the time range to query in UTC millis since
313a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     *            epoch
314a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param selection Filter on the query as an SQL WHERE statement
315a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param selectionArgs Args to replace any '?'s in the selection
316a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @param orderBy How to order the rows as an SQL ORDER BY statement
317a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     * @return A Cursor of instances matching the selection
318a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik     */
319a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik    private static final Cursor instancesQuery(ContentResolver cr, String[] projection, long begin,
320a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            long end, String selection, String[] selectionArgs, String orderBy) {
321a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        String WHERE_CALENDARS_SELECTED = Calendars.VISIBLE + "=?";
322a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        String[] WHERE_CALENDARS_ARGS = {"1"};
323a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        String DEFAULT_SORT_ORDER = "begin ASC";
324a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik
325a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
326a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        ContentUris.appendId(builder, begin);
327a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        ContentUris.appendId(builder, end);
328a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        if (TextUtils.isEmpty(selection)) {
329a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            selection = WHERE_CALENDARS_SELECTED;
330a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            selectionArgs = WHERE_CALENDARS_ARGS;
331a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        } else {
332a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            selection = "(" + selection + ") AND " + WHERE_CALENDARS_SELECTED;
333a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            if (selectionArgs != null && selectionArgs.length > 0) {
334a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik                selectionArgs = Arrays.copyOf(selectionArgs, selectionArgs.length + 1);
335a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik                selectionArgs[selectionArgs.length - 1] = WHERE_CALENDARS_ARGS[0];
336a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            } else {
337a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik                selectionArgs = WHERE_CALENDARS_ARGS;
338a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik            }
339a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        }
340a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        return cr.query(builder.build(), projection, selection, selectionArgs,
341a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik                orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
342a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik    }
343a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik
344a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik    /**
345ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * Adds all the events from the cursors to the events list.
346ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     *
347ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param events The list of events
348ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param cEvents Events to add to the list
349ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param context
350ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param startDay
351ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param endDay
352ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     */
353ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    public static void buildEventsFromCursor(
354ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            ArrayList<Event> events, Cursor cEvents, Context context, int startDay, int endDay) {
355ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        if (cEvents == null || events == null) {
356981874e61ecf29a96a77601a3172b2503b6537eeErik            Log.e(TAG, "buildEventsFromCursor: null cursor or null events list!");
357981874e61ecf29a96a77601a3172b2503b6537eeErik            return;
358981874e61ecf29a96a77601a3172b2503b6537eeErik        }
359981874e61ecf29a96a77601a3172b2503b6537eeErik
360ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        int count = cEvents.getCount();
361981874e61ecf29a96a77601a3172b2503b6537eeErik
362981874e61ecf29a96a77601a3172b2503b6537eeErik        if (count == 0) {
363981874e61ecf29a96a77601a3172b2503b6537eeErik            return;
364981874e61ecf29a96a77601a3172b2503b6537eeErik        }
365981874e61ecf29a96a77601a3172b2503b6537eeErik
366981874e61ecf29a96a77601a3172b2503b6537eeErik        Resources res = context.getResources();
367ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        mNoTitleString = res.getString(R.string.no_title_label);
368ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        mNoColorColor = res.getColor(R.color.event_center);
369ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        // Sort events in two passes so we ensure the allday and standard events
370ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        // get sorted in the correct order
371ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        while (cEvents.moveToNext()) {
372ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            Event e = generateEventFromCursor(cEvents, startDay, endDay);
373ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            events.add(e);
374ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        }
375ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    }
376981874e61ecf29a96a77601a3172b2503b6537eeErik
377ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    /**
378ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param cEvents Cursor pointing at event
379ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param startDay First day of queried range
380ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @param endDay Last day of queried range
381ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     * @return An event created from the cursor
382ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik     */
383ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik    private static Event generateEventFromCursor(Cursor cEvents, int startDay, int endDay) {
384ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        Event e = new Event();
385981874e61ecf29a96a77601a3172b2503b6537eeErik
386ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.id = cEvents.getLong(PROJECTION_EVENT_ID_INDEX);
387ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.title = cEvents.getString(PROJECTION_TITLE_INDEX);
388ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.location = cEvents.getString(PROJECTION_LOCATION_INDEX);
389ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.allDay = cEvents.getInt(PROJECTION_ALL_DAY_INDEX) != 0;
390ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.organizer = cEvents.getString(PROJECTION_ORGANIZER_INDEX);
391ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.guestsCanModify = cEvents.getInt(PROJECTION_GUESTS_CAN_INVITE_OTHERS_INDEX) != 0;
392981874e61ecf29a96a77601a3172b2503b6537eeErik
393ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        if (e.title == null || e.title.length() == 0) {
394ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            e.title = mNoTitleString;
395ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        }
396981874e61ecf29a96a77601a3172b2503b6537eeErik
397ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        if (!cEvents.isNull(PROJECTION_COLOR_INDEX)) {
398ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            // Read the color from the database
399ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            e.color = cEvents.getInt(PROJECTION_COLOR_INDEX);
40025996100d6ea61888ebe54d7708a9a371bb12a55RoboErik            float[] hsv = new float[3];
40125996100d6ea61888ebe54d7708a9a371bb12a55RoboErik            Color.colorToHSV(e.color, hsv);
40225996100d6ea61888ebe54d7708a9a371bb12a55RoboErik            hsv[1] = Math.max(hsv[1] - SATURATION_ADJUST, 0.0f);
40325996100d6ea61888ebe54d7708a9a371bb12a55RoboErik            e.color = Color.HSVToColor(hsv);
404ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        } else {
405ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            e.color = mNoColorColor;
406ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        }
407981874e61ecf29a96a77601a3172b2503b6537eeErik
408ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        long eStart = cEvents.getLong(PROJECTION_BEGIN_INDEX);
409ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        long eEnd = cEvents.getLong(PROJECTION_END_INDEX);
410981874e61ecf29a96a77601a3172b2503b6537eeErik
411ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.startMillis = eStart;
412ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.startTime = cEvents.getInt(PROJECTION_START_MINUTE_INDEX);
413ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.startDay = cEvents.getInt(PROJECTION_START_DAY_INDEX);
414981874e61ecf29a96a77601a3172b2503b6537eeErik
415ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.endMillis = eEnd;
416ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.endTime = cEvents.getInt(PROJECTION_END_MINUTE_INDEX);
417ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.endDay = cEvents.getInt(PROJECTION_END_DAY_INDEX);
418981874e61ecf29a96a77601a3172b2503b6537eeErik
419ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        if (e.startDay > endDay || e.endDay < startDay) {
420ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            // continue;
421ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        }
422981874e61ecf29a96a77601a3172b2503b6537eeErik
423ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.hasAlarm = cEvents.getInt(PROJECTION_HAS_ALARM_INDEX) != 0;
424981874e61ecf29a96a77601a3172b2503b6537eeErik
425ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        // Check if this is a repeating event
426ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        String rrule = cEvents.getString(PROJECTION_RRULE_INDEX);
427ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        String rdate = cEvents.getString(PROJECTION_RDATE_INDEX);
428ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        if (!TextUtils.isEmpty(rrule) || !TextUtils.isEmpty(rdate)) {
429ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            e.isRepeating = true;
430ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        } else {
431ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik            e.isRepeating = false;
432981874e61ecf29a96a77601a3172b2503b6537eeErik        }
433ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik
434ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        e.selfAttendeeStatus = cEvents.getInt(PROJECTION_SELF_ATTENDEE_STATUS_INDEX);
435ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik        return e;
436981874e61ecf29a96a77601a3172b2503b6537eeErik    }
437981874e61ecf29a96a77601a3172b2503b6537eeErik
438146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
439146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Computes a position for each event.  Each event is displayed
440146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * as a non-overlapping rectangle.  For normal events, these rectangles
441146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * are displayed in separate columns in the week view and day view.  For
442146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * all-day events, these rectangles are displayed in separate rows along
443146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * the top.  In both cases, each event is assigned two numbers: N, and
444146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Max, that specify that this event is the Nth event of Max number of
445146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * events that are displayed in a group. The width and position of each
446146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * rectangle depend on the maximum number of rectangles that occur at
447146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * the same time.
448146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
449146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param eventsList the list of events, sorted into increasing time order
45046b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa     * @param minimumDurationMillis minimum duration acceptable as cell height of each event
45146b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa     * rectangle in millisecond. Should be 0 when it is not determined.
452146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
45346b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa    /* package */ static void computePositions(ArrayList<Event> eventsList,
45427d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa            long minimumDurationMillis) {
45546b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        if (eventsList == null) {
456146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return;
45746b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        }
458146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
459146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Compute the column positions separately for the all-day events
46046b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        doComputePositions(eventsList, minimumDurationMillis, false);
46146b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        doComputePositions(eventsList, minimumDurationMillis, true);
462146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
463146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
464146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static void doComputePositions(ArrayList<Event> eventsList,
46568655b5af2b7e5f872a103858ec58a19042123ceRoboErik            long minimumDurationMillis, boolean doAlldayEvents) {
46646b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        final ArrayList<Event> activeList = new ArrayList<Event>();
46746b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        final ArrayList<Event> groupList = new ArrayList<Event>();
46846b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa
46927d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa        if (minimumDurationMillis < 0) {
47027d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa            minimumDurationMillis = 0;
47146b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa        }
472146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
473146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        long colMask = 0;
474146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int maxCols = 0;
475146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (Event event : eventsList) {
476146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Process all-day events separately
47768655b5af2b7e5f872a103858ec58a19042123ceRoboErik            if (event.drawAsAllday() != doAlldayEvents)
478146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                continue;
479146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
48068655b5af2b7e5f872a103858ec58a19042123ceRoboErik           if (!doAlldayEvents) {
48168655b5af2b7e5f872a103858ec58a19042123ceRoboErik                colMask = removeNonAlldayActiveEvents(
48268655b5af2b7e5f872a103858ec58a19042123ceRoboErik                        event, activeList.iterator(), minimumDurationMillis, colMask);
48368655b5af2b7e5f872a103858ec58a19042123ceRoboErik            } else {
48468655b5af2b7e5f872a103858ec58a19042123ceRoboErik                colMask = removeAlldayActiveEvents(event, activeList.iterator(), colMask);
485146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
486146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
487146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // If the active list is empty, then reset the max columns, clear
488146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the column bit mask, and empty the groupList.
489146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (activeList.isEmpty()) {
490146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                for (Event ev : groupList) {
491146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    ev.setMaxColumns(maxCols);
492146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
493146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                maxCols = 0;
494146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                colMask = 0;
495146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                groupList.clear();
496146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
497146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
498146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Find the first empty column.  Empty columns are represented by
499146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // zero bits in the column mask "colMask".
500146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int col = findFirstZeroBit(colMask);
501146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (col == 64)
502146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                col = 63;
503146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            colMask |= (1L << col);
504146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            event.setColumn(col);
505146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            activeList.add(event);
506146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            groupList.add(event);
507146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int len = activeList.size();
508146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (maxCols < len)
509146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                maxCols = len;
510146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
511146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (Event ev : groupList) {
512146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            ev.setMaxColumns(maxCols);
513146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
514146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
515146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
51668655b5af2b7e5f872a103858ec58a19042123ceRoboErik    private static long removeAlldayActiveEvents(Event event, Iterator<Event> iter, long colMask) {
51768655b5af2b7e5f872a103858ec58a19042123ceRoboErik        // Remove the inactive allday events. An event on the active list
51868655b5af2b7e5f872a103858ec58a19042123ceRoboErik        // becomes inactive when the end day is less than the current event's
51968655b5af2b7e5f872a103858ec58a19042123ceRoboErik        // start day.
52068655b5af2b7e5f872a103858ec58a19042123ceRoboErik        while (iter.hasNext()) {
52168655b5af2b7e5f872a103858ec58a19042123ceRoboErik            final Event active = iter.next();
52268655b5af2b7e5f872a103858ec58a19042123ceRoboErik            if (active.endDay < event.startDay) {
52368655b5af2b7e5f872a103858ec58a19042123ceRoboErik                colMask &= ~(1L << active.getColumn());
52468655b5af2b7e5f872a103858ec58a19042123ceRoboErik                iter.remove();
52568655b5af2b7e5f872a103858ec58a19042123ceRoboErik            }
52668655b5af2b7e5f872a103858ec58a19042123ceRoboErik        }
52768655b5af2b7e5f872a103858ec58a19042123ceRoboErik        return colMask;
52868655b5af2b7e5f872a103858ec58a19042123ceRoboErik    }
52968655b5af2b7e5f872a103858ec58a19042123ceRoboErik
53068655b5af2b7e5f872a103858ec58a19042123ceRoboErik    private static long removeNonAlldayActiveEvents(
53168655b5af2b7e5f872a103858ec58a19042123ceRoboErik            Event event, Iterator<Event> iter, long minDurationMillis, long colMask) {
53268655b5af2b7e5f872a103858ec58a19042123ceRoboErik        long start = event.getStartMillis();
53368655b5af2b7e5f872a103858ec58a19042123ceRoboErik        // Remove the inactive events. An event on the active list
53468655b5af2b7e5f872a103858ec58a19042123ceRoboErik        // becomes inactive when its end time is less than or equal to
53568655b5af2b7e5f872a103858ec58a19042123ceRoboErik        // the current event's start time.
53668655b5af2b7e5f872a103858ec58a19042123ceRoboErik        while (iter.hasNext()) {
53768655b5af2b7e5f872a103858ec58a19042123ceRoboErik            final Event active = iter.next();
53868655b5af2b7e5f872a103858ec58a19042123ceRoboErik
53968655b5af2b7e5f872a103858ec58a19042123ceRoboErik            final long duration = Math.max(
54068655b5af2b7e5f872a103858ec58a19042123ceRoboErik                    active.getEndMillis() - active.getStartMillis(), minDurationMillis);
54168655b5af2b7e5f872a103858ec58a19042123ceRoboErik            if ((active.getStartMillis() + duration) <= start) {
54268655b5af2b7e5f872a103858ec58a19042123ceRoboErik                colMask &= ~(1L << active.getColumn());
54368655b5af2b7e5f872a103858ec58a19042123ceRoboErik                iter.remove();
54468655b5af2b7e5f872a103858ec58a19042123ceRoboErik            }
54568655b5af2b7e5f872a103858ec58a19042123ceRoboErik        }
54668655b5af2b7e5f872a103858ec58a19042123ceRoboErik        return colMask;
54768655b5af2b7e5f872a103858ec58a19042123ceRoboErik    }
54868655b5af2b7e5f872a103858ec58a19042123ceRoboErik
549146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static int findFirstZeroBit(long val) {
550146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (int ii = 0; ii < 64; ++ii) {
551146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if ((val & (1L << ii)) == 0)
552146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return ii;
553146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
554146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return 64;
555146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
556146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
557146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final void dump() {
558146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+-----------------------------------------+");
559146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+        id = " + id);
560146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+     color = " + color);
561146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+     title = " + title);
562146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+  location = " + location);
563146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+    allDay = " + allDay);
564146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+  startDay = " + startDay);
565146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+    endDay = " + endDay);
566146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+ startTime = " + startTime);
567146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+   endTime = " + endTime);
5686d34cec523930368976bc8d358d0a6de1da3462cMichael Chan        Log.e("Cal", "+ organizer = " + organizer);
5696d34cec523930368976bc8d358d0a6de1da3462cMichael Chan        Log.e("Cal", "+  guestwrt = " + guestsCanModify);
570146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
571146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
572146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final boolean intersects(int julianDay, int startMinute,
573146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int endMinute) {
574146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endDay < julianDay) {
575146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return false;
576146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
577146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
578146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startDay > julianDay) {
579146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return false;
580146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
581146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
582146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endDay == julianDay) {
583146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (endTime < startMinute) {
584146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return false;
585146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
586146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // An event that ends at the start minute should not be considered
587146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // as intersecting the given time span, but don't exclude
588146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // zero-length (or very short) events.
589146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (endTime == startMinute
590146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    && (startTime != endTime || startDay != endDay)) {
591146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return false;
592146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
593146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
594146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
595146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startDay == julianDay && startTime > endMinute) {
596146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return false;
597146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
598146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
599146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return true;
600146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
601146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
602146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
603146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Returns the event title and location separated by a comma.  If the
604146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * location is already part of the title (at the end of the title), then
605146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * just the title is returned.
606146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
607146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @return the event title and location as a String
608146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
609146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public String getTitleAndLocation() {
610146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        String text = title.toString();
611146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
612146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Append the location to the title, unless the title ends with the
613146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // location (for example, "meeting in building 42" ends with the
614146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // location).
615146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (location != null) {
616146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            String locationString = location.toString();
617146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (!text.endsWith(locationString)) {
618146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                text += ", " + locationString;
619146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
620146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
621146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return text;
622146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
623146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
624146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setColumn(int column) {
625146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mColumn = column;
626146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
627146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
628146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getColumn() {
629146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mColumn;
630146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
631146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
632146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setMaxColumns(int maxColumns) {
633146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mMaxColumns = maxColumns;
634146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
635146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
636146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getMaxColumns() {
637146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mMaxColumns;
638146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
639146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
640146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setStartMillis(long startMillis) {
641146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        this.startMillis = startMillis;
642146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
643146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
644146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long getStartMillis() {
645146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return startMillis;
646146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
647146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
648146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setEndMillis(long endMillis) {
649146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        this.endMillis = endMillis;
650146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
651146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
652146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long getEndMillis() {
653146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return endMillis;
654146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
655d031419da7900dab91ac9f512374d7e59bb74dceErik
65668655b5af2b7e5f872a103858ec58a19042123ceRoboErik    public boolean drawAsAllday() {
6571d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErik        // Use >= so we'll pick up Exchange allday events
6581d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErik        return allDay || endMillis - startMillis >= DateUtils.DAY_IN_MILLIS;
659d031419da7900dab91ac9f512374d7e59bb74dceErik    }
660146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project}
661