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; 25a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.net.Uri; 26146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.os.Debug; 27a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees; 28a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport android.provider.CalendarContract.Calendars; 29a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events; 30a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Instances; 31146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.TextUtils; 32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateUtils; 33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.util.Log; 34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 35146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.ArrayList; 36a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport java.util.Arrays; 37146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.Iterator; 38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger; 39146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 40146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project// TODO: should Event be Parcelable so it can be passed via Intents? 411d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErikpublic class Event implements Cloneable { 42146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 43981874e61ecf29a96a77601a3172b2503b6537eeErik private static final String TAG = "CalEvent"; 44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final boolean PROFILE = false; 45146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 462fda24534978f55711526dbde747aa50d68dec40RoboErik /** 472fda24534978f55711526dbde747aa50d68dec40RoboErik * The sort order is: 48ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * 1) events with an earlier start (begin for normal events, startday for allday) 49ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * 2) events with a later end (end for normal events, endday for allday) 50ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * 3) the title (unnecessary, but nice) 512fda24534978f55711526dbde747aa50d68dec40RoboErik * 522fda24534978f55711526dbde747aa50d68dec40RoboErik * The start and end day is sorted first so that all day events are 532fda24534978f55711526dbde747aa50d68dec40RoboErik * sorted correctly with respect to events that are >24 hours (and 542fda24534978f55711526dbde747aa50d68dec40RoboErik * therefore show up in the allday area). 552fda24534978f55711526dbde747aa50d68dec40RoboErik */ 562fda24534978f55711526dbde747aa50d68dec40RoboErik private static final String SORT_EVENTS_BY = 57ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik "begin ASC, end DESC, title ASC"; 58ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static final String SORT_ALLDAY_BY = 59ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik "startDay ASC, endDay DESC, title ASC"; 60ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static final String DISPLAY_AS_ALLDAY = "dispAllday"; 61ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik 62ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static final String EVENTS_WHERE = DISPLAY_AS_ALLDAY + "=0"; 63ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static final String ALLDAY_WHERE = DISPLAY_AS_ALLDAY + "=1"; 642fda24534978f55711526dbde747aa50d68dec40RoboErik 65981874e61ecf29a96a77601a3172b2503b6537eeErik // The projection to use when querying instances to build a list of events 66981874e61ecf29a96a77601a3172b2503b6537eeErik public static final String[] EVENT_PROJECTION = new String[] { 67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.TITLE, // 0 68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.EVENT_LOCATION, // 1 69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.ALL_DAY, // 2 70693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan Instances.DISPLAY_COLOR, // 3 If SDK < 16, set to Instances.CALENDAR_COLOR. 71146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.EVENT_TIMEZONE, // 4 72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.EVENT_ID, // 5 73146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.BEGIN, // 6 74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.END, // 7 75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances._ID, // 8 76146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.START_DAY, // 9 77146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.END_DAY, // 10 78146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.START_MINUTE, // 11 79146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.END_MINUTE, // 12 80146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.HAS_ALARM, // 13 81146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.RRULE, // 14 82146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.RDATE, // 15 83146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Instances.SELF_ATTENDEE_STATUS, // 16 846d34cec523930368976bc8d358d0a6de1da3462cMichael Chan Events.ORGANIZER, // 17 856d34cec523930368976bc8d358d0a6de1da3462cMichael Chan Events.GUESTS_CAN_MODIFY, // 18 86ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik Instances.ALL_DAY + "=1 OR (" + Instances.END + "-" + Instances.BEGIN + ")>=" 87ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik + DateUtils.DAY_IN_MILLIS + " AS " + DISPLAY_AS_ALLDAY, // 19 88146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 89146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 90146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The indices for the projection array above. 91146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_TITLE_INDEX = 0; 92146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_LOCATION_INDEX = 1; 93146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_ALL_DAY_INDEX = 2; 94146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_COLOR_INDEX = 3; 95146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_TIMEZONE_INDEX = 4; 96146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_EVENT_ID_INDEX = 5; 97146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_BEGIN_INDEX = 6; 98146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_END_INDEX = 7; 99146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_START_DAY_INDEX = 9; 100146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_END_DAY_INDEX = 10; 101146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_START_MINUTE_INDEX = 11; 102146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_END_MINUTE_INDEX = 12; 103146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_HAS_ALARM_INDEX = 13; 104146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_RRULE_INDEX = 14; 105146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_RDATE_INDEX = 15; 106146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int PROJECTION_SELF_ATTENDEE_STATUS_INDEX = 16; 1076d34cec523930368976bc8d358d0a6de1da3462cMichael Chan private static final int PROJECTION_ORGANIZER_INDEX = 17; 1086d34cec523930368976bc8d358d0a6de1da3462cMichael Chan private static final int PROJECTION_GUESTS_CAN_INVITE_OTHERS_INDEX = 18; 109ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static final int PROJECTION_DISPLAY_AS_ALLDAY = 19; 110ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik 111693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan static { 112fac2d1594f7ecae8e50dc7790ce67de0c9b70d22Sara Ting if (!Utils.isJellybeanOrLater()) { 113693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan EVENT_PROJECTION[PROJECTION_COLOR_INDEX] = Instances.CALENDAR_COLOR; 114693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 115693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 116693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan 117ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static String mNoTitleString; 118ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik private static int mNoColorColor; 119146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 120146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long id; 121146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int color; 122146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public CharSequence title; 123146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public CharSequence location; 124146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public boolean allDay; 1256d34cec523930368976bc8d358d0a6de1da3462cMichael Chan public String organizer; 1266d34cec523930368976bc8d358d0a6de1da3462cMichael Chan public boolean guestsCanModify; 127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int startDay; // start Julian day 129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int endDay; // end Julian day 130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int startTime; // Start and end time are in minutes since midnight 131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int endTime; 132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 133146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long startMillis; // UTC milliseconds since the epoch 134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long endMillis; // UTC milliseconds since the epoch 135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private int mColumn; 136146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private int mMaxColumns; 137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 138146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public boolean hasAlarm; 139146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public boolean isRepeating; 140981874e61ecf29a96a77601a3172b2503b6537eeErik 141146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int selfAttendeeStatus; 142146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The coordinates of the event rectangle drawn on the screen. 144146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public float left; 145146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public float right; 146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public float top; 147146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public float bottom; 148146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 149146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // These 4 fields are used for navigating among events within the selected 150146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // hour in the Day and Week view. 151146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public Event nextRight; 152146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public Event nextLeft; 153146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public Event nextUp; 154146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public Event nextDown; 155146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 156146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 15798ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan public final Object clone() throws CloneNotSupportedException { 15898ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan super.clone(); 159146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Event e = new Event(); 160146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 161146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.title = title; 162146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.color = color; 163146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.location = location; 164146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.allDay = allDay; 165146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.startDay = startDay; 166146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.endDay = endDay; 167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.startTime = startTime; 168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.endTime = endTime; 169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.startMillis = startMillis; 170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.endMillis = endMillis; 171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.hasAlarm = hasAlarm; 172146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.isRepeating = isRepeating; 173146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.selfAttendeeStatus = selfAttendeeStatus; 1746d34cec523930368976bc8d358d0a6de1da3462cMichael Chan e.organizer = organizer; 1756d34cec523930368976bc8d358d0a6de1da3462cMichael Chan e.guestsCanModify = guestsCanModify; 176146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 177146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return e; 178146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 179146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public final void copyTo(Event dest) { 181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.id = id; 182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.title = title; 183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.color = color; 184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.location = location; 185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.allDay = allDay; 186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.startDay = startDay; 187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.endDay = endDay; 188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.startTime = startTime; 189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.endTime = endTime; 190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.startMillis = startMillis; 191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.endMillis = endMillis; 192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.hasAlarm = hasAlarm; 193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.isRepeating = isRepeating; 194146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dest.selfAttendeeStatus = selfAttendeeStatus; 1956d34cec523930368976bc8d358d0a6de1da3462cMichael Chan dest.organizer = organizer; 1966d34cec523930368976bc8d358d0a6de1da3462cMichael Chan dest.guestsCanModify = guestsCanModify; 197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final Event newInstance() { 200146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Event e = new Event(); 201146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 202146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.id = 0; 203146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.title = null; 204146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.color = 0; 205146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.location = null; 206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.allDay = false; 207146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.startDay = 0; 208146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.endDay = 0; 209146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.startTime = 0; 210146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.endTime = 0; 211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.startMillis = 0; 212146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.endMillis = 0; 213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.hasAlarm = false; 214146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.isRepeating = false; 215146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project e.selfAttendeeStatus = Attendees.ATTENDEE_STATUS_NONE; 216146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 217146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return e; 218146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 219146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 221b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik * Loads <i>days</i> days worth of instances starting at <i>startDay</i>. 222146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 223b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik public static void loadEvents(Context context, ArrayList<Event> events, int startDay, int days, 224b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik int requestId, AtomicInteger sequenceNumber) { 225146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 226146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (PROFILE) { 227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Debug.startMethodTracing("loadEvents"); 228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 229146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 230ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik Cursor cEvents = null; 231ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik Cursor cAllday = null; 232146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 233146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project events.clear(); 234146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project try { 235b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik int endDay = startDay + days - 1; 236b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik 237b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik // We use the byDay instances query to get a list of all events for 238b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik // the days we're interested in. 239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The sort order is: events with an earlier start time occur 240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // first and if the start times are the same, then events with 241146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // a later end time occur first. The later end time is ordered 242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // first so that long rectangles in the calendar views appear on 243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the left side. If the start and end times of two events are 244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the same then we sort alphabetically on the title. This isn't 245146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // required for correctness, it just adds a nice touch. 246146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 247146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Respect the preference to show/hide declined events 2484b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); 2494b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa boolean hideDeclined = prefs.getBoolean(GeneralPreferences.KEY_HIDE_DECLINED, 250146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project false); 251146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 252ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String where = EVENTS_WHERE; 253ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String whereAllday = ALLDAY_WHERE; 254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (hideDeclined) { 255ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String hideString = " AND " + Instances.SELF_ATTENDEE_STATUS + "!=" 256ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik + Attendees.ATTENDEE_STATUS_DECLINED; 257ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik where += hideString; 258ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik whereAllday += hideString; 259146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 260146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 261b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik cEvents = instancesQuery(context.getContentResolver(), EVENT_PROJECTION, startDay, 262b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik endDay, where, null, SORT_EVENTS_BY); 263b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik cAllday = instancesQuery(context.getContentResolver(), EVENT_PROJECTION, startDay, 264b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik endDay, whereAllday, null, SORT_ALLDAY_BY); 265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Check if we should return early because there are more recent 267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // load requests waiting. 268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (requestId != sequenceNumber.get()) { 269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return; 270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 272ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik buildEventsFromCursor(events, cEvents, context, startDay, endDay); 273ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik buildEventsFromCursor(events, cAllday, context, startDay, endDay); 274146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } finally { 276ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (cEvents != null) { 277ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik cEvents.close(); 278ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 279ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (cAllday != null) { 280ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik cAllday.close(); 281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (PROFILE) { 283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Debug.stopMethodTracing(); 284146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 285146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 287146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 288ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik /** 289a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * Performs a query to return all visible instances in the given range 290a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * that match the given selection. This is a blocking function and 291a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * should not be done on the UI thread. This will cause an expansion of 292a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * recurring events to fill this time range if they are not already 293a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * expanded and will slow down for larger time ranges with many 294a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * recurring events. 295a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * 296a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param cr The ContentResolver to use for the query 297a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param projection The columns to return 298a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param begin The start of the time range to query in UTC millis since 299a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * epoch 300a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param end The end of the time range to query in UTC millis since 301a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * epoch 302a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param selection Filter on the query as an SQL WHERE statement 303a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param selectionArgs Args to replace any '?'s in the selection 304a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @param orderBy How to order the rows as an SQL ORDER BY statement 305a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik * @return A Cursor of instances matching the selection 306a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik */ 307b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik private static final Cursor instancesQuery(ContentResolver cr, String[] projection, 308b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik int startDay, int endDay, String selection, String[] selectionArgs, String orderBy) { 309a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik String WHERE_CALENDARS_SELECTED = Calendars.VISIBLE + "=?"; 310a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik String[] WHERE_CALENDARS_ARGS = {"1"}; 311a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik String DEFAULT_SORT_ORDER = "begin ASC"; 312a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik 313b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik Uri.Builder builder = Instances.CONTENT_BY_DAY_URI.buildUpon(); 314b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik ContentUris.appendId(builder, startDay); 315b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik ContentUris.appendId(builder, endDay); 316a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik if (TextUtils.isEmpty(selection)) { 317a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selection = WHERE_CALENDARS_SELECTED; 318a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs = WHERE_CALENDARS_ARGS; 319a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } else { 320a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selection = "(" + selection + ") AND " + WHERE_CALENDARS_SELECTED; 321a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik if (selectionArgs != null && selectionArgs.length > 0) { 322a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs = Arrays.copyOf(selectionArgs, selectionArgs.length + 1); 323a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs[selectionArgs.length - 1] = WHERE_CALENDARS_ARGS[0]; 324a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } else { 325a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik selectionArgs = WHERE_CALENDARS_ARGS; 326a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } 327a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } 328a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik return cr.query(builder.build(), projection, selection, selectionArgs, 329a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik orderBy == null ? DEFAULT_SORT_ORDER : orderBy); 330a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik } 331a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik 332a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik /** 333ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * Adds all the events from the cursors to the events list. 334ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * 335ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param events The list of events 336ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param cEvents Events to add to the list 337ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param context 338ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param startDay 339ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param endDay 340ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik */ 341ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik public static void buildEventsFromCursor( 342ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik ArrayList<Event> events, Cursor cEvents, Context context, int startDay, int endDay) { 343ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (cEvents == null || events == null) { 344981874e61ecf29a96a77601a3172b2503b6537eeErik Log.e(TAG, "buildEventsFromCursor: null cursor or null events list!"); 345981874e61ecf29a96a77601a3172b2503b6537eeErik return; 346981874e61ecf29a96a77601a3172b2503b6537eeErik } 347981874e61ecf29a96a77601a3172b2503b6537eeErik 348ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik int count = cEvents.getCount(); 349981874e61ecf29a96a77601a3172b2503b6537eeErik 350981874e61ecf29a96a77601a3172b2503b6537eeErik if (count == 0) { 351981874e61ecf29a96a77601a3172b2503b6537eeErik return; 352981874e61ecf29a96a77601a3172b2503b6537eeErik } 353981874e61ecf29a96a77601a3172b2503b6537eeErik 354981874e61ecf29a96a77601a3172b2503b6537eeErik Resources res = context.getResources(); 355ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik mNoTitleString = res.getString(R.string.no_title_label); 356ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik mNoColorColor = res.getColor(R.color.event_center); 357ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // Sort events in two passes so we ensure the allday and standard events 358ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // get sorted in the correct order 3594d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson cEvents.moveToPosition(-1); 360ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik while (cEvents.moveToNext()) { 361b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik Event e = generateEventFromCursor(cEvents); 362b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik if (e.startDay > endDay || e.endDay < startDay) { 363b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik continue; 364b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik } 365ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik events.add(e); 366ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 367ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 368981874e61ecf29a96a77601a3172b2503b6537eeErik 369ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik /** 370ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @param cEvents Cursor pointing at event 371ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik * @return An event created from the cursor 372ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik */ 373b5e3c17201b2c08ca9f3fd33f4585e1ec8fa71b1RoboErik private static Event generateEventFromCursor(Cursor cEvents) { 374ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik Event e = new Event(); 375981874e61ecf29a96a77601a3172b2503b6537eeErik 376ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.id = cEvents.getLong(PROJECTION_EVENT_ID_INDEX); 377ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.title = cEvents.getString(PROJECTION_TITLE_INDEX); 378ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.location = cEvents.getString(PROJECTION_LOCATION_INDEX); 379ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.allDay = cEvents.getInt(PROJECTION_ALL_DAY_INDEX) != 0; 380ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.organizer = cEvents.getString(PROJECTION_ORGANIZER_INDEX); 381ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.guestsCanModify = cEvents.getInt(PROJECTION_GUESTS_CAN_INVITE_OTHERS_INDEX) != 0; 382981874e61ecf29a96a77601a3172b2503b6537eeErik 383ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (e.title == null || e.title.length() == 0) { 384ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.title = mNoTitleString; 385ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 386981874e61ecf29a96a77601a3172b2503b6537eeErik 387ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (!cEvents.isNull(PROJECTION_COLOR_INDEX)) { 388ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // Read the color from the database 3894acb2fd087308dea146b8b10f5278c59df387680RoboErik e.color = Utils.getDisplayColorFromColor(cEvents.getInt(PROJECTION_COLOR_INDEX)); 390ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } else { 391ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.color = mNoColorColor; 392ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } 393981874e61ecf29a96a77601a3172b2503b6537eeErik 394ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik long eStart = cEvents.getLong(PROJECTION_BEGIN_INDEX); 395ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik long eEnd = cEvents.getLong(PROJECTION_END_INDEX); 396981874e61ecf29a96a77601a3172b2503b6537eeErik 397ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.startMillis = eStart; 398ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.startTime = cEvents.getInt(PROJECTION_START_MINUTE_INDEX); 399ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.startDay = cEvents.getInt(PROJECTION_START_DAY_INDEX); 400981874e61ecf29a96a77601a3172b2503b6537eeErik 401ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.endMillis = eEnd; 402ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.endTime = cEvents.getInt(PROJECTION_END_MINUTE_INDEX); 403ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.endDay = cEvents.getInt(PROJECTION_END_DAY_INDEX); 404981874e61ecf29a96a77601a3172b2503b6537eeErik 405ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.hasAlarm = cEvents.getInt(PROJECTION_HAS_ALARM_INDEX) != 0; 406981874e61ecf29a96a77601a3172b2503b6537eeErik 407ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik // Check if this is a repeating event 408ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String rrule = cEvents.getString(PROJECTION_RRULE_INDEX); 409ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik String rdate = cEvents.getString(PROJECTION_RDATE_INDEX); 410ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik if (!TextUtils.isEmpty(rrule) || !TextUtils.isEmpty(rdate)) { 411ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.isRepeating = true; 412ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik } else { 413ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.isRepeating = false; 414981874e61ecf29a96a77601a3172b2503b6537eeErik } 415ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik 416ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik e.selfAttendeeStatus = cEvents.getInt(PROJECTION_SELF_ATTENDEE_STATUS_INDEX); 417ff982e820f7c1e5f369ea71bf1e6fc511778bac4RoboErik return e; 418981874e61ecf29a96a77601a3172b2503b6537eeErik } 419981874e61ecf29a96a77601a3172b2503b6537eeErik 420146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 421146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Computes a position for each event. Each event is displayed 422146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * as a non-overlapping rectangle. For normal events, these rectangles 423146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * are displayed in separate columns in the week view and day view. For 424146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * all-day events, these rectangles are displayed in separate rows along 425146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * the top. In both cases, each event is assigned two numbers: N, and 426146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Max, that specify that this event is the Nth event of Max number of 427146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * events that are displayed in a group. The width and position of each 428146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * rectangle depend on the maximum number of rectangles that occur at 429146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * the same time. 430146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 431146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param eventsList the list of events, sorted into increasing time order 43246b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa * @param minimumDurationMillis minimum duration acceptable as cell height of each event 43346b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa * rectangle in millisecond. Should be 0 when it is not determined. 434146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 43546b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa /* package */ static void computePositions(ArrayList<Event> eventsList, 43627d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa long minimumDurationMillis) { 43746b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa if (eventsList == null) { 438146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return; 43946b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa } 440146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 441146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Compute the column positions separately for the all-day events 44246b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa doComputePositions(eventsList, minimumDurationMillis, false); 44346b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa doComputePositions(eventsList, minimumDurationMillis, true); 444146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 445146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 446146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static void doComputePositions(ArrayList<Event> eventsList, 44768655b5af2b7e5f872a103858ec58a19042123ceRoboErik long minimumDurationMillis, boolean doAlldayEvents) { 44846b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa final ArrayList<Event> activeList = new ArrayList<Event>(); 44946b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa final ArrayList<Event> groupList = new ArrayList<Event>(); 45046b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa 45127d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa if (minimumDurationMillis < 0) { 45227d671cdba3e8b50219def2c9e1118abe987f908Daisuke Miyakawa minimumDurationMillis = 0; 45346b05ffc746a3150b6bad5d3a72138ffa38b0a99Daisuke Miyakawa } 454146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 455146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long colMask = 0; 456146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int maxCols = 0; 457146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (Event event : eventsList) { 458146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Process all-day events separately 45968655b5af2b7e5f872a103858ec58a19042123ceRoboErik if (event.drawAsAllday() != doAlldayEvents) 460146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project continue; 461146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 46268655b5af2b7e5f872a103858ec58a19042123ceRoboErik if (!doAlldayEvents) { 46368655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask = removeNonAlldayActiveEvents( 46468655b5af2b7e5f872a103858ec58a19042123ceRoboErik event, activeList.iterator(), minimumDurationMillis, colMask); 46568655b5af2b7e5f872a103858ec58a19042123ceRoboErik } else { 46668655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask = removeAlldayActiveEvents(event, activeList.iterator(), colMask); 467146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 468146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 469146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the active list is empty, then reset the max columns, clear 470146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the column bit mask, and empty the groupList. 471146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (activeList.isEmpty()) { 472146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (Event ev : groupList) { 473146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ev.setMaxColumns(maxCols); 474146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 475146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project maxCols = 0; 476146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project colMask = 0; 477146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project groupList.clear(); 478146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 479146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 480146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Find the first empty column. Empty columns are represented by 481146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // zero bits in the column mask "colMask". 482146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int col = findFirstZeroBit(colMask); 483146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (col == 64) 484146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project col = 63; 485146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project colMask |= (1L << col); 486146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project event.setColumn(col); 487146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project activeList.add(event); 488146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project groupList.add(event); 489146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int len = activeList.size(); 490146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (maxCols < len) 491146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project maxCols = len; 492146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 493146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (Event ev : groupList) { 494146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ev.setMaxColumns(maxCols); 495146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 496146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 497146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 49868655b5af2b7e5f872a103858ec58a19042123ceRoboErik private static long removeAlldayActiveEvents(Event event, Iterator<Event> iter, long colMask) { 49968655b5af2b7e5f872a103858ec58a19042123ceRoboErik // Remove the inactive allday events. An event on the active list 50068655b5af2b7e5f872a103858ec58a19042123ceRoboErik // becomes inactive when the end day is less than the current event's 50168655b5af2b7e5f872a103858ec58a19042123ceRoboErik // start day. 50268655b5af2b7e5f872a103858ec58a19042123ceRoboErik while (iter.hasNext()) { 50368655b5af2b7e5f872a103858ec58a19042123ceRoboErik final Event active = iter.next(); 50468655b5af2b7e5f872a103858ec58a19042123ceRoboErik if (active.endDay < event.startDay) { 50568655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask &= ~(1L << active.getColumn()); 50668655b5af2b7e5f872a103858ec58a19042123ceRoboErik iter.remove(); 50768655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 50868655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 50968655b5af2b7e5f872a103858ec58a19042123ceRoboErik return colMask; 51068655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 51168655b5af2b7e5f872a103858ec58a19042123ceRoboErik 51268655b5af2b7e5f872a103858ec58a19042123ceRoboErik private static long removeNonAlldayActiveEvents( 51368655b5af2b7e5f872a103858ec58a19042123ceRoboErik Event event, Iterator<Event> iter, long minDurationMillis, long colMask) { 51468655b5af2b7e5f872a103858ec58a19042123ceRoboErik long start = event.getStartMillis(); 51568655b5af2b7e5f872a103858ec58a19042123ceRoboErik // Remove the inactive events. An event on the active list 51668655b5af2b7e5f872a103858ec58a19042123ceRoboErik // becomes inactive when its end time is less than or equal to 51768655b5af2b7e5f872a103858ec58a19042123ceRoboErik // the current event's start time. 51868655b5af2b7e5f872a103858ec58a19042123ceRoboErik while (iter.hasNext()) { 51968655b5af2b7e5f872a103858ec58a19042123ceRoboErik final Event active = iter.next(); 52068655b5af2b7e5f872a103858ec58a19042123ceRoboErik 52168655b5af2b7e5f872a103858ec58a19042123ceRoboErik final long duration = Math.max( 52268655b5af2b7e5f872a103858ec58a19042123ceRoboErik active.getEndMillis() - active.getStartMillis(), minDurationMillis); 52368655b5af2b7e5f872a103858ec58a19042123ceRoboErik if ((active.getStartMillis() + duration) <= start) { 52468655b5af2b7e5f872a103858ec58a19042123ceRoboErik colMask &= ~(1L << active.getColumn()); 52568655b5af2b7e5f872a103858ec58a19042123ceRoboErik iter.remove(); 52668655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 52768655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 52868655b5af2b7e5f872a103858ec58a19042123ceRoboErik return colMask; 52968655b5af2b7e5f872a103858ec58a19042123ceRoboErik } 53068655b5af2b7e5f872a103858ec58a19042123ceRoboErik 531146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static int findFirstZeroBit(long val) { 532146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (int ii = 0; ii < 64; ++ii) { 533146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if ((val & (1L << ii)) == 0) 534146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return ii; 535146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 536146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return 64; 537146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 538146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 539146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public final void dump() { 540146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+-----------------------------------------+"); 541146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ id = " + id); 542146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ color = " + color); 543146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ title = " + title); 544146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ location = " + location); 545146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ allDay = " + allDay); 546146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ startDay = " + startDay); 547146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ endDay = " + endDay); 548146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ startTime = " + startTime); 549146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Log.e("Cal", "+ endTime = " + endTime); 5506d34cec523930368976bc8d358d0a6de1da3462cMichael Chan Log.e("Cal", "+ organizer = " + organizer); 5516d34cec523930368976bc8d358d0a6de1da3462cMichael Chan Log.e("Cal", "+ guestwrt = " + guestsCanModify); 552146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 553146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 554146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public final boolean intersects(int julianDay, int startMinute, 555146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int endMinute) { 556146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endDay < julianDay) { 557146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 558146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 559146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 560146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (startDay > julianDay) { 561146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 562146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 563146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 564146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endDay == julianDay) { 565146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endTime < startMinute) { 566146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 567146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 568146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // An event that ends at the start minute should not be considered 569146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // as intersecting the given time span, but don't exclude 570146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // zero-length (or very short) events. 571146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endTime == startMinute 572146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project && (startTime != endTime || startDay != endDay)) { 573146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 574146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 575146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 576146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 577146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (startDay == julianDay && startTime > endMinute) { 578146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 579146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 580146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 581146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return true; 582146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 583146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 584146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 585146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Returns the event title and location separated by a comma. If the 586146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * location is already part of the title (at the end of the title), then 587146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * just the title is returned. 588146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 589146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the event title and location as a String 590146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 591146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public String getTitleAndLocation() { 592146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project String text = title.toString(); 593146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 594146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Append the location to the title, unless the title ends with the 595146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // location (for example, "meeting in building 42" ends with the 596146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // location). 597146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (location != null) { 598146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project String locationString = location.toString(); 599146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (!text.endsWith(locationString)) { 600146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project text += ", " + locationString; 601146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 602146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 603146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return text; 604146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 605146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 606146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setColumn(int column) { 607146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mColumn = column; 608146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 609146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 610146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getColumn() { 611146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mColumn; 612146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 613146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 614146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setMaxColumns(int maxColumns) { 615146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mMaxColumns = maxColumns; 616146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 617146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 618146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getMaxColumns() { 619146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mMaxColumns; 620146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 621146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 622146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setStartMillis(long startMillis) { 623146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project this.startMillis = startMillis; 624146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 625146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 626146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long getStartMillis() { 627146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return startMillis; 628146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 629146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 630146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void setEndMillis(long endMillis) { 631146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project this.endMillis = endMillis; 632146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 633146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 634146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long getEndMillis() { 635146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return endMillis; 636146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 637d031419da7900dab91ac9f512374d7e59bb74dceErik 63868655b5af2b7e5f872a103858ec58a19042123ceRoboErik public boolean drawAsAllday() { 6391d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErik // Use >= so we'll pick up Exchange allday events 6401d92cbdf5b754f9da92303eaf554d8db7d7b0849RoboErik return allDay || endMillis - startMillis >= DateUtils.DAY_IN_MILLIS; 641d031419da7900dab91ac9f512374d7e59bb74dceErik } 642146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 643