Event.java revision b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1
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 /** 219b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik * Loads <i>days</i> days worth of instances starting at <i>startDay</i>. 220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 221b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik public static void loadEvents(Context context, ArrayList<Event> events, int startDay, int days, 222b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik 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 { 233b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik int endDay = startDay + days - 1; 234b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik 235b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik // We use the byDay instances query to get a list of all events for 236b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik // the days we're interested in. 237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The sort order is: events with an earlier start time occur 238146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // first and if the start times are the same, then events with 239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // a later end time occur first. The later end time is ordered 240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // first so that long rectangles in the calendar views appear on 241146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the left side. If the start and end times of two events are 242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the same then we sort alphabetically on the title. This isn't 243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // required for correctness, it just adds a nice touch. 244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 245146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Respect the preference to show/hide declined events 2464b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); 2474b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa boolean hideDeclined = prefs.getBoolean(GeneralPreferences.KEY_HIDE_DECLINED, 248146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project false); 249146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 250ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String where = EVENTS_WHERE; 251ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String whereAllday = ALLDAY_WHERE; 252146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (hideDeclined) { 253ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String hideString = " AND " + Instances.SELF_ATTENDEE_STATUS + "!=" 254ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik + Attendees.ATTENDEE_STATUS_DECLINED; 255ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik where += hideString; 256ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik whereAllday += hideString; 257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 259b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik cEvents = instancesQuery(context.getContentResolver(), EVENT_PROJECTION, startDay, 260b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik endDay, where, null, SORT_EVENTS_BY); 261b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik cAllday = instancesQuery(context.getContentResolver(), EVENT_PROJECTION, startDay, 262b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik endDay, whereAllday, null, SORT_ALLDAY_BY); 263146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Check if we should return early because there are more recent 265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // load requests waiting. 266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (requestId != sequenceNumber.get()) { 267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return; 268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 270ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik buildEventsFromCursor(events, cEvents, context, startDay, endDay); 271ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik buildEventsFromCursor(events, cAllday, context, startDay, endDay); 272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 273146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } finally { 274ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (cEvents != null) { 275ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik cEvents.close(); 276ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 277ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (cAllday != null) { 278ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik cAllday.close(); 279146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 280146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (PROFILE) { 281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Debug.stopMethodTracing(); 282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 284146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 285146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 286ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik /** 287a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * Performs a query to return all visible instances in the given range 288a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * that match the given selection. This is a blocking function and 289a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * should not be done on the UI thread. This will cause an expansion of 290a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * recurring events to fill this time range if they are not already 291a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * expanded and will slow down for larger time ranges with many 292a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * recurring events. 293a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * 294a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param cr The ContentResolver to use for the query 295a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param projection The columns to return 296a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param begin The start of the time range to query in UTC millis since 297a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * epoch 298a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param end The end of the time range to query in UTC millis since 299a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * epoch 300a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param selection Filter on the query as an SQL WHERE statement 301a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param selectionArgs Args to replace any '?'s in the selection 302a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param orderBy How to order the rows as an SQL ORDER BY statement 303a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @return A Cursor of instances matching the selection 304a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik */ 305b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik private static final Cursor instancesQuery(ContentResolver cr, String[] projection, 306b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik int startDay, int endDay, String selection, String[] selectionArgs, String orderBy) { 307a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik String WHERE_CALENDARS_SELECTED = Calendars.VISIBLE + "=?"; 308a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik String[] WHERE_CALENDARS_ARGS = {"1"}; 309a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik String DEFAULT_SORT_ORDER = "begin ASC"; 310a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik 311b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik Uri.Builder builder = Instances.CONTENT_BY_DAY_URI.buildUpon(); 312b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik ContentUris.appendId(builder, startDay); 313b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik ContentUris.appendId(builder, endDay); 314a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik if (TextUtils.isEmpty(selection)) { 315a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selection = WHERE_CALENDARS_SELECTED; 316a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs = WHERE_CALENDARS_ARGS; 317a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } else { 318a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selection = "(" + selection + ") AND " + WHERE_CALENDARS_SELECTED; 319a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik if (selectionArgs != null && selectionArgs.length > 0) { 320a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs = Arrays.copyOf(selectionArgs, selectionArgs.length + 1); 321a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs[selectionArgs.length - 1] = WHERE_CALENDARS_ARGS[0]; 322a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } else { 323a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs = WHERE_CALENDARS_ARGS; 324a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } 325a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } 326a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik return cr.query(builder.build(), projection, selection, selectionArgs, 327a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik orderBy == null ? DEFAULT_SORT_ORDER : orderBy); 328a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } 329a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik 330a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik /** 331ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * Adds all the events from the cursors to the events list. 332ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * 333ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param events The list of events 334ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param cEvents Events to add to the list 335ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param context 336ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param startDay 337ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param endDay 338ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik */ 339ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik public static void buildEventsFromCursor( 340ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik ArrayList<Event> events, Cursor cEvents, Context context, int startDay, int endDay) { 341ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (cEvents == null || events == null) { 342981874e61ecf29a96a77601a3172b2503b6537eeErik Log.e(TAG, "buildEventsFromCursor: null cursor or null events list!"); 343981874e61ecf29a96a77601a3172b2503b6537eeErik return; 344981874e61ecf29a96a77601a3172b2503b6537eeErik } 345981874e61ecf29a96a77601a3172b2503b6537eeErik 346ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik int count = cEvents.getCount(); 347981874e61ecf29a96a77601a3172b2503b6537eeErik 348981874e61ecf29a96a77601a3172b2503b6537eeErik if (count == 0) { 349981874e61ecf29a96a77601a3172b2503b6537eeErik return; 350981874e61ecf29a96a77601a3172b2503b6537eeErik } 351981874e61ecf29a96a77601a3172b2503b6537eeErik 352981874e61ecf29a96a77601a3172b2503b6537eeErik Resources res = context.getResources(); 353ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik mNoTitleString = res.getString(R.string.no_title_label); 354ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik mNoColorColor = res.getColor(R.color.event_center); 355ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // Sort events in two passes so we ensure the allday and standard events 356ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // get sorted in the correct order 357ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik while (cEvents.moveToNext()) { 358b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik Event e = generateEventFromCursor(cEvents); 359b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik if (e.startDay > endDay || e.endDay < startDay) { 360b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik continue; 361b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik } 362ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik events.add(e); 363ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 364ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 365981874e61ecf29a96a77601a3172b2503b6537eeErik 366ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik /** 367ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param cEvents Cursor pointing at event 368ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @return An event created from the cursor 369ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik */ 370b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik private static Event generateEventFromCursor(Cursor cEvents) { 371ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik Event e = new Event(); 372981874e61ecf29a96a77601a3172b2503b6537eeErik 373ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.id = cEvents.getLong(PROJECTION_EVENT_ID_INDEX); 374ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.title = cEvents.getString(PROJECTION_TITLE_INDEX); 375ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.location = cEvents.getString(PROJECTION_LOCATION_INDEX); 376ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.allDay = cEvents.getInt(PROJECTION_ALL_DAY_INDEX) != 0; 377ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.organizer = cEvents.getString(PROJECTION_ORGANIZER_INDEX); 378ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.guestsCanModify = cEvents.getInt(PROJECTION_GUESTS_CAN_INVITE_OTHERS_INDEX) != 0; 379981874e61ecf29a96a77601a3172b2503b6537eeErik 380ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (e.title == null || e.title.length() == 0) { 381ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.title = mNoTitleString; 382ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 383981874e61ecf29a96a77601a3172b2503b6537eeErik 384ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (!cEvents.isNull(PROJECTION_COLOR_INDEX)) { 385ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // Read the color from the database 386ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.color = cEvents.getInt(PROJECTION_COLOR_INDEX); 38725996100d6ea61888ebe54d7708a9a371bb12a55RoboErik float[] hsv = new float[3]; 38825996100d6ea61888ebe54d7708a9a371bb12a55RoboErik Color.colorToHSV(e.color, hsv); 38925996100d6ea61888ebe54d7708a9a371bb12a55RoboErik hsv[1] = Math.max(hsv[1] - SATURATION_ADJUST, 0.0f); 39025996100d6ea61888ebe54d7708a9a371bb12a55RoboErik e.color = Color.HSVToColor(hsv); 391ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } else { 392ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.color = mNoColorColor; 393ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 394981874e61ecf29a96a77601a3172b2503b6537eeErik 395ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik long eStart = cEvents.getLong(PROJECTION_BEGIN_INDEX); 396ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik long eEnd = cEvents.getLong(PROJECTION_END_INDEX); 397981874e61ecf29a96a77601a3172b2503b6537eeErik 398ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.startMillis = eStart; 399ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.startTime = cEvents.getInt(PROJECTION_START_MINUTE_INDEX); 400ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.startDay = cEvents.getInt(PROJECTION_START_DAY_INDEX); 401981874e61ecf29a96a77601a3172b2503b6537eeErik 402ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.endMillis = eEnd; 403ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.endTime = cEvents.getInt(PROJECTION_END_MINUTE_INDEX); 404ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.endDay = cEvents.getInt(PROJECTION_END_DAY_INDEX); 405981874e61ecf29a96a77601a3172b2503b6537eeErik 406ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.hasAlarm = cEvents.getInt(PROJECTION_HAS_ALARM_INDEX) != 0; 407981874e61ecf29a96a77601a3172b2503b6537eeErik 408ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // Check if this is a repeating event 409ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String rrule = cEvents.getString(PROJECTION_RRULE_INDEX); 410ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String rdate = cEvents.getString(PROJECTION_RDATE_INDEX); 411ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (!TextUtils.isEmpty(rrule) || !TextUtils.isEmpty(rdate)) { 412ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.isRepeating = true; 413ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } else { 414ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.isRepeating = false; 415981874e61ecf29a96a77601a3172b2503b6537eeErik } 416ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik 417ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.selfAttendeeStatus = cEvents.getInt(PROJECTION_SELF_ATTENDEE_STATUS_INDEX); 418ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik return e; 419981874e61ecf29a96a77601a3172b2503b6537eeErik } 420981874e61ecf29a96a77601a3172b2503b6537eeErik 421146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 422146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Computes a position for each event. Each event is displayed 423146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * as a non-overlapping rectangle. For normal events, these rectangles 424146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * are displayed in separate columns in the week view and day view. For 425146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * all-day events, these rectangles are displayed in separate rows along 426146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * the top. In both cases, each event is assigned two numbers: N, and 427146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Max, that specify that this event is the Nth event of Max number of 428146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * events that are displayed in a group. The width and position of each 429146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * rectangle depend on the maximum number of rectangles that occur at 430146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * the same time. 431146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 432146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param eventsList the list of events, sorted into increasing time order 43346b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa * @param minimumDurationMillis minimum duration acceptable as cell height of each event 43446b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa * rectangle in millisecond. Should be 0 when it is not determined. 435146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 43646b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa /* package */ static void computePositions(ArrayList<Event> eventsList, 43727d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa long minimumDurationMillis) { 43846b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa if (eventsList == null) { 439146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return; 44046b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa } 441146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 442146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Compute the column positions separately for the all-day events 44346b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa doComputePositions(eventsList, minimumDurationMillis, false); 44446b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa doComputePositions(eventsList, minimumDurationMillis, true); 445146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 446146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 447146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static void doComputePositions(ArrayList<Event> eventsList, 44868655b5af2b7e5f872a103858ec58a19042123ceRoboErik long minimumDurationMillis, boolean doAlldayEvents) { 44946b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa final ArrayList<Event> activeList = new ArrayList<Event>(); 45046b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa final ArrayList<Event> groupList = new ArrayList<Event>(); 45146b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa 45227d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa if (minimumDurationMillis < 0) { 45327d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa minimumDurationMillis = 0; 45446b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa } 455146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 456146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long colMask = 0; 457146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int maxCols = 0; 458146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (Event event : eventsList) { 459146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Process all-day events separately 46068655b5af2b7e5f872a103858ec58a19042123ceRoboErik if (event.drawAsAllday() != doAlldayEvents) 461146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project continue; 462146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 46368655b5af2b7e5f872a103858ec58a19042123ceRoboErik if (!doAlldayEvents) { 46468655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask = removeNonAlldayActiveEvents( 46568655b5af2b7e5f872a103858ec58a19042123ceRoboErik event, activeList.iterator(), minimumDurationMillis, colMask); 46668655b5af2b7e5f872a103858ec58a19042123ceRoboErik } else { 46768655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask = removeAlldayActiveEvents(event, activeList.iterator(), colMask); 468146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 469146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 470146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the active list is empty, then reset the max columns, clear 471146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the column bit mask, and empty the groupList. 472146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (activeList.isEmpty()) { 473146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (Event ev : groupList) { 474146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ev.setMaxColumns(maxCols); 475146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 476146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project maxCols = 0; 477146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project colMask = 0; 478146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project groupList.clear(); 479146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 480146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 481146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Find the first empty column. Empty columns are represented by 482146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // zero bits in the column mask "colMask". 483146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int col = findFirstZeroBit(colMask); 484146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (col == 64) 485146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project col = 63; 486146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project colMask |= (1L << col); 487146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project event.setColumn(col); 488146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project activeList.add(event); 489146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project groupList.add(event); 490146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int len = activeList.size(); 491146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (maxCols < len) 492146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project maxCols = len; 493146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 494146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (Event ev : groupList) { 495146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ev.setMaxColumns(maxCols); 496146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 497146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 498146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 49968655b5af2b7e5f872a103858ec58a19042123ceRoboErik private static long removeAlldayActiveEvents(Event event, Iterator<Event> iter, long colMask) { 50068655b5af2b7e5f872a103858ec58a19042123ceRoboErik // Remove the inactive allday events. An event on the active list 50168655b5af2b7e5f872a103858ec58a19042123ceRoboErik // becomes inactive when the end day is less than the current event's 50268655b5af2b7e5f872a103858ec58a19042123ceRoboErik // start day. 50368655b5af2b7e5f872a103858ec58a19042123ceRoboErik while (iter.hasNext()) { 50468655b5af2b7e5f872a103858ec58a19042123ceRoboErik final Event active = iter.next(); 50568655b5af2b7e5f872a103858ec58a19042123ceRoboErik if (active.endDay < event.startDay) { 50668655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask &= ~(1L << active.getColumn()); 50768655b5af2b7e5f872a103858ec58a19042123ceRoboErik iter.remove(); 50868655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 50968655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 51068655b5af2b7e5f872a103858ec58a19042123ceRoboErik return colMask; 51168655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 51268655b5af2b7e5f872a103858ec58a19042123ceRoboErik 51368655b5af2b7e5f872a103858ec58a19042123ceRoboErik private static long removeNonAlldayActiveEvents( 51468655b5af2b7e5f872a103858ec58a19042123ceRoboErik Event event, Iterator<Event> iter, long minDurationMillis, long colMask) { 51568655b5af2b7e5f872a103858ec58a19042123ceRoboErik long start = event.getStartMillis(); 51668655b5af2b7e5f872a103858ec58a19042123ceRoboErik // Remove the inactive events. An event on the active list 51768655b5af2b7e5f872a103858ec58a19042123ceRoboErik // becomes inactive when its end time is less than or equal to 51868655b5af2b7e5f872a103858ec58a19042123ceRoboErik // the current event's start time. 51968655b5af2b7e5f872a103858ec58a19042123ceRoboErik while (iter.hasNext()) { 52068655b5af2b7e5f872a103858ec58a19042123ceRoboErik final Event active = iter.next(); 52168655b5af2b7e5f872a103858ec58a19042123ceRoboErik 52268655b5af2b7e5f872a103858ec58a19042123ceRoboErik final long duration = Math.max( 52368655b5af2b7e5f872a103858ec58a19042123ceRoboErik active.getEndMillis() - active.getStartMillis(), minDurationMillis); 52468655b5af2b7e5f872a103858ec58a19042123ceRoboErik if ((active.getStartMillis() + duration) <= start) { 52568655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask &= ~(1L << active.getColumn()); 52668655b5af2b7e5f872a103858ec58a19042123ceRoboErik iter.remove(); 52768655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 52868655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 52968655b5af2b7e5f872a103858ec58a19042123ceRoboErik return colMask; 53068655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 53168655b5af2b7e5f872a103858ec58a19042123ceRoboErik 532146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static int findFirstZeroBit(long val) { 533146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (int ii = 0; ii < 64; ++ii) { 534146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if ((val & (1L << ii)) == 0) 535146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return ii; 536146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 537146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return 64; 538146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 539146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 540146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public final void dump() { 541146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+-----------------------------------------+"); 542146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ id = " + id); 543146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ color = " + color); 544146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ title = " + title); 545146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ location = " + location); 546146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ allDay = " + allDay); 547146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ startDay = " + startDay); 548146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ endDay = " + endDay); 549146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ startTime = " + startTime); 550146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ endTime = " + endTime); 5516d34cec523930368976bc8d358d0a6de1da3462cMichael Chan Log.e("Cal", "+ organizer = " + organizer); 5526d34cec523930368976bc8d358d0a6de1da3462cMichael Chan Log.e("Cal", "+ guestwrt = " + guestsCanModify); 553146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 554146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 555146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public final boolean intersects(int julianDay, int startMinute, 556146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int endMinute) { 557146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endDay < julianDay) { 558146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 559146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 560146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 561146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (startDay > julianDay) { 562146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 563146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 564146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 565146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endDay == julianDay) { 566146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endTime < startMinute) { 567146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 568146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 569146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // An event that ends at the start minute should not be considered 570146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // as intersecting the given time span, but don't exclude 571146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // zero-length (or very short) events. 572146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endTime == startMinute 573146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project && (startTime != endTime || startDay != endDay)) { 574146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 575146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 576146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 577146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 578146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (startDay == julianDay && startTime > endMinute) { 579146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 580146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 581146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 582146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return true; 583146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 584146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 585146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 586146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Returns the event title and location separated by a comma. If the 587146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * location is already part of the title (at the end of the title), then 588146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * just the title is returned. 589146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 590146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the event title and location as a String 591146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 592146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public String getTitleAndLocation() { 593146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project String text = title.toString(); 594146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 595146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Append the location to the title, unless the title ends with the 596146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // location (for example, "meeting in building 42" ends with the 597146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // location). 598146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (location != null) { 599146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project String locationString = location.toString(); 600146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (!text.endsWith(locationString)) { 601146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project text += ", " + locationString; 602146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 603146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 604146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return text; 605146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 606146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 607146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setColumn(int column) { 608146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mColumn = column; 609146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 610146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 611146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getColumn() { 612146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mColumn; 613146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 614146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 615146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setMaxColumns(int maxColumns) { 616146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mMaxColumns = maxColumns; 617146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 618146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 619146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getMaxColumns() { 620146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mMaxColumns; 621146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 622146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 623146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setStartMillis(long startMillis) { 624146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project this.startMillis = startMillis; 625146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 626146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 627146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long getStartMillis() { 628146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return startMillis; 629146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 630146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 631146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setEndMillis(long endMillis) { 632146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project this.endMillis = endMillis; 633146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 634146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 635146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long getEndMillis() { 636146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return endMillis; 637146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 638d031419da7900dab91ac9f512374d7e59bb74dceErik 63968655b5af2b7e5f872a103858ec58a19042123ceRoboErik public boolean drawAsAllday() { 6401d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErik // Use >= so we'll pick up Exchange allday events 6411d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErik return allDay || endMillis - startMillis >= DateUtils.DAY_IN_MILLIS; 642d031419da7900dab91ac9f512374d7e59bb74dceErik } 643146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 644