AgendaWindowAdapter.java revision e3f129ad0a39b47ef0f08f18734aed9b99126279
113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan/* 213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * Copyright (C) 2009 The Android Open Source Project 313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * 413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * Licensed under the Apache License, Version 2.0 (the "License"); 513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * you may not use this file except in compliance with the License. 613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * You may obtain a copy of the License at 713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * 813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * http://www.apache.org/licenses/LICENSE-2.0 913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * 1013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * Unless required by applicable law or agreed to in writing, software 1113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * distributed under the License is distributed on an "AS IS" BASIS, 1213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * See the License for the specific language governing permissions and 1413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * limitations under the License. 1513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 1613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1700b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangpackage com.android.calendar.agenda; 1800b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang 19ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chanimport com.android.calendar.CalendarController; 2000b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangimport com.android.calendar.R; 2100b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangimport com.android.calendar.Utils; 22ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chanimport com.android.calendar.CalendarController.EventType; 23e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErikimport com.android.calendar.CalendarController.ViewType; 2437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelsonimport com.android.calendar.StickyHeaderListView; 2513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 2613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.AsyncQueryHandler; 2713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.ContentResolver; 289138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.content.ContentUris; 2913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.Context; 30a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawaimport android.content.res.Resources; 3113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.database.Cursor; 3213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.net.Uri; 33a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract; 34a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees; 35a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars; 36a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Instances; 3713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.text.format.DateUtils; 3813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.text.format.Time; 3913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.util.Log; 4013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.LayoutInflater; 4113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.View; 4213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.View.OnClickListener; 439a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport android.view.ViewGroup; 4413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.widget.BaseAdapter; 4513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.widget.TextView; 4613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 4713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Formatter; 4813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Iterator; 4913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.LinkedList; 5013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Locale; 5113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.concurrent.ConcurrentLinkedQueue; 5213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan/* 5413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanBugs Bugs Bugs: 5513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- At rotation and launch time, the initial position is not set properly. This code is calling 5613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listview.setSelection() in 2 rapid secessions but it dropped or didn't process the first one. 5713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Scroll using trackball isn't repositioning properly after a new adapter is added. 5823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan- Track ball clicks at the header/footer doesn't work. 5913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Potential ping pong effect if the prefetch window is big and data is limited 6013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Add index in calendar provider 6113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanToDo ToDo ToDo: 6313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanGet design of header and footer from designer 6413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanMake scrolling smoother. 6613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanTest for correctness 6713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanLoading speed 6813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanCheck for leaks and excessive allocations 6913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 7013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelsonpublic class AgendaWindowAdapter extends BaseAdapter 7237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson implements StickyHeaderListView.HeaderIndexer{ 7313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan static final boolean BASICLOG = false; 75e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik static final boolean DEBUGLOG = true; 76a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private static final String TAG = "AgendaWindowAdapter"; 7713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 789138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private static final String AGENDA_SORT_ORDER = 79a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik CalendarContract.Instances.START_DAY + " ASC, " + 80a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik CalendarContract.Instances.BEGIN + " ASC, " + 81a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik CalendarContract.Events.TITLE + " ASC"; 829138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 83ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public static final int INDEX_INSTANCE_ID = 0; 8413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_TITLE = 1; 8513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_EVENT_LOCATION = 2; 8613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_ALL_DAY = 3; 8713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_HAS_ALARM = 4; 8813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_COLOR = 5; 8913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_RRULE = 6; 9013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_BEGIN = 7; 9113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_END = 8; 9213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_EVENT_ID = 9; 9313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_START_DAY = 10; 9413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_END_DAY = 11; 9513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_SELF_ATTENDEE_STATUS = 12; 96056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson public static final int INDEX_ORGANIZER = 13; 97056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson public static final int INDEX_OWNER_ACCOUNT = 14; 98056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson public static final int INDEX_CAN_ORGANIZER_RESPOND= 15; 991121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik public static final int INDEX_TIME_ZONE = 16; 10013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 10113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final String[] PROJECTION = new String[] { 10213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances._ID, // 0 10313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.TITLE, // 1 10413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.EVENT_LOCATION, // 2 10513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.ALL_DAY, // 3 10613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.HAS_ALARM, // 4 1070e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik Instances.CALENDAR_COLOR, // 5 10813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.RRULE, // 6 10913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.BEGIN, // 7 11013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.END, // 8 11113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.EVENT_ID, // 9 11213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.START_DAY, // 10 Julian start day 11313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.END_DAY, // 11 Julian end day 11413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.SELF_ATTENDEE_STATUS, // 12 115056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson Instances.ORGANIZER, // 13 116056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson Instances.OWNER_ACCOUNT, // 14 117056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson Instances.CAN_ORGANIZER_RESPOND, // 15 1181121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik Instances.EVENT_TIMEZONE, // 16 11913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan }; 12013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 12113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Listview may have a bug where the index/position is not consistent when there's a header. 122a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa // position == positionInListView - OFF_BY_ONE_BUG 12313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // TODO Need to look into this. 12413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int OFF_BY_ONE_BUG = 1; 12513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MAX_NUM_OF_ADAPTERS = 5; 12613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int IDEAL_NUM_OF_EVENTS = 50; 12713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MIN_QUERY_DURATION = 7; // days 12813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MAX_QUERY_DURATION = 60; // days 12913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int PREFETCH_BOUNDARY = 1; 13013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1319138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Times to auto-expand/retry query after getting no data */ 1329138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private static final int RETRIES_ON_NO_DATA = 1; 13313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 13413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private Context mContext; 135a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private Resources mResources; 13613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private QueryHandler mQueryHandler; 13713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private AgendaListView mAgendaListView; 13813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1399138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The sum of the rows in all the adapters */ 1409138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private int mRowCount; 14113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1429138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The number of times we have queried and gotten no results back */ 14313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mEmptyCursorCount; 14413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1459138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Cached value of the last used adapter */ 1469138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private DayAdapterInfo mLastUsedInfo; 14713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 148a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final LinkedList<DayAdapterInfo> mAdapterInfos = 149a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa new LinkedList<DayAdapterInfo>(); 150a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final ConcurrentLinkedQueue<QuerySpec> mQueryQueue = 151a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa new ConcurrentLinkedQueue<QuerySpec>(); 15213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private TextView mHeaderView; 15313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private TextView mFooterView; 15413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mDoneSettingUpHeaderFooter = false; 15513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 156980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson private final boolean mIsTabletConfig; 157cf6a46c5c81334f7c960ecc5fd354a14f1c4037cMichael Chan private final int mSkipDateHeader; 158980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson 1599138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 16013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * When the user scrolled to the top, a query will be made for older events 16113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * and this will be incremented. Don't make more requests if 16213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * mOlderRequests > mOlderRequestsProcessed. 16313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 16413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mOlderRequests; 16513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1669138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Number of "older" query that has been processed. */ 16713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mOlderRequestsProcessed; 16813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1699138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 17013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * When the user scrolled to the bottom, a query will be made for newer 17113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * events and this will be incremented. Don't make more requests if 17213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * mNewerRequests > mNewerRequestsProcessed. 17313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 17413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mNewerRequests; 17513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1769138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Number of "newer" query that has been processed. */ 17713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mNewerRequestsProcessed; 17813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 17923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread. 18023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan private Formatter mFormatter; 18113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private StringBuilder mStringBuilder; 1829a88873f9ec97b47aaaaae47208d22b3998b8e99Erik private String mTimeZone; 1839a88873f9ec97b47aaaaae47208d22b3998b8e99Erik 18496a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson // defines if to pop-up the current event when the agenda is first shown 18596a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson private boolean mShowEventOnStart; 18696a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson 1879a88873f9ec97b47aaaaae47208d22b3998b8e99Erik private Runnable mTZUpdater = new Runnable() { 1889a88873f9ec97b47aaaaae47208d22b3998b8e99Erik @Override 1899a88873f9ec97b47aaaaae47208d22b3998b8e99Erik public void run() { 1909a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTimeZone = Utils.getTimeZone(mContext, this); 1919a88873f9ec97b47aaaaae47208d22b3998b8e99Erik notifyDataSetChanged(); 1929a88873f9ec97b47aaaaae47208d22b3998b8e99Erik } 1939a88873f9ec97b47aaaaae47208d22b3998b8e99Erik }; 19413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 19513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mShuttingDown; 19613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mHideDeclined; 19713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1989138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The current search query, or null if none */ 1999138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private String mSearchQuery; 2009138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 201ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan private long mSelectedInstanceId = -1; 202a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 203163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan private final int mSelectedItemBackgroundColor; 204163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan private final int mSelectedItemTextColor; 205a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 20613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Types of Query 20713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_OLDER = 0; // Query for older events 20813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_NEWER = 1; // Query for newer events 20913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_CLEAN = 2; // Delete everything and query around a date 21013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 21113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static class QuerySpec { 21213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long queryStartMillis; 21313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time goToTime; 21413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start; 21513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end; 2169138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang String searchQuery; 21713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryType; 21813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 21913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public QuerySpec(int queryType) { 22013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan this.queryType = queryType; 22113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 22223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan 22323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan @Override 22423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan public int hashCode() { 22523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan final int prime = 31; 22623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan int result = 1; 22723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + end; 22823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + (int) (queryStartMillis ^ (queryStartMillis >>> 32)); 22923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + queryType; 23023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + start; 2319138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang result = prime * result + searchQuery.hashCode(); 23223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime != null) { 23323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan long goToTimeMillis = goToTime.toMillis(false); 23423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + (int) (goToTimeMillis ^ (goToTimeMillis >>> 32)); 23523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 23623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return result; 23723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 23823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan 23923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan @Override 24023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan public boolean equals(Object obj) { 24123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (this == obj) return true; 24223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (obj == null) return false; 24323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (getClass() != obj.getClass()) return false; 24423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan QuerySpec other = (QuerySpec) obj; 24523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (end != other.end || queryStartMillis != other.queryStartMillis 2469138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang || queryType != other.queryType || start != other.start 2479138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang || Utils.equals(searchQuery, other.searchQuery)) { 24823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 24923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 2509138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 25123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime != null) { 25223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime.toMillis(false) != other.goToTime.toMillis(false)) { 25323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 25423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 25523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } else { 25623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (other.goToTime != null) { 25723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 25823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 25923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 26023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return true; 26123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 26213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 26313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 26413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static class EventInfo { 26513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long begin; 26613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long end; 26713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long id; 268ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan int startDay; 26913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 27013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 271dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan static class DayAdapterInfo { 27213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Cursor cursor; 27313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan AgendaByDayAdapter dayAdapter; 27413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start; // start day of the cursor's coverage 27513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end; // end day of the cursor's coverage 27613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int offset; // offset in position in the list view 27713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int size; // dayAdapter.getCount() 27813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 27913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public DayAdapterInfo(Context context) { 28013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan dayAdapter = new AgendaByDayAdapter(context); 28113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 28213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 28313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 28413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public String toString() { 2859a88873f9ec97b47aaaaae47208d22b3998b8e99Erik // Static class, so the time in this toString will not reflect the 2869a88873f9ec97b47aaaaae47208d22b3998b8e99Erik // home tz settings. This should only affect debugging. 28713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time time = new Time(); 28813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan StringBuilder sb = new StringBuilder(); 28913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(start); 29013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.normalize(false); 29113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append("Start:").append(time.toString()); 29213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(end); 29313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.normalize(false); 29413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" End:").append(time.toString()); 29513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" Offset:").append(offset); 29613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" Size:").append(size); 29713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return sb.toString(); 29813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 29913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 30013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 3019138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang public AgendaWindowAdapter(Context context, 30296a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson AgendaListView agendaListView, boolean showEventOnStart) { 3039138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mContext = context; 304a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa mResources = context.getResources(); 305163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan mSelectedItemBackgroundColor = mResources 306163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan .getColor(R.color.agenda_selected_background_color); 307163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan mSelectedItemTextColor = mResources.getColor(R.color.agenda_selected_text_color); 308980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson mIsTabletConfig = Utils.getConfigBool(mContext, R.bool.tablet_config); 309cf6a46c5c81334f7c960ecc5fd354a14f1c4037cMichael Chan mSkipDateHeader = mIsTabletConfig ? 0 : 1; 310a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 3119a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTimeZone = Utils.getTimeZone(context, mTZUpdater); 31213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView = agendaListView; 3139138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mQueryHandler = new QueryHandler(context.getContentResolver()); 31413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 31513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder = new StringBuilder(50); 31613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 31713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 31896a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson mShowEventOnStart = showEventOnStart; 31996a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson 3209138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mSearchQuery = null; 3219138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 3229138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang LayoutInflater inflater = (LayoutInflater) context 32313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 32413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView = (TextView)inflater.inflate(R.layout.agenda_header_footer, null); 32513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView = (TextView)inflater.inflate(R.layout.agenda_header_footer, null); 32613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setText(R.string.loading); 32713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.addHeaderView(mHeaderView); 32813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 32913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 33013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in Adapter 33113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 33213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getViewTypeCount() { 33313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return AgendaByDayAdapter.TYPE_LAST; 33413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 33513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 33613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in BaseAdapter 33713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 33813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public boolean areAllItemsEnabled() { 33913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 34013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 34113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 34213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in Adapter 34313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 34413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getItemViewType(int position) { 34513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 34613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 34713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.getItemViewType(position - info.offset); 34813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 34913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 35013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 35113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 35213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 35313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in BaseAdapter 35413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 35513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public boolean isEnabled(int position) { 35613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 35713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 35813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.isEnabled(position - info.offset); 35913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 36013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 36113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 36413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 36513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getCount() { 36613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mRowCount; 36713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 36913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 37013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public Object getItem(int position) { 37113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 37213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 37313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.getItem(position - info.offset); 37413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 37513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 37613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 37713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 37813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 379c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan // Method in BaseAdapter 380c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan @Override 381c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan public boolean hasStableIds() { 382c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan return true; 383c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 384c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan 38513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 38613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public long getItemId(int position) { 38713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 38813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 389c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan return ((position - info.offset) << 20) + info.start ; 39013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 39113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 39213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 39313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 39413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 39513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 39613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public View getView(int position, View convertView, ViewGroup parent) { 39713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (position >= (mRowCount - PREFETCH_BOUNDARY) 39813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && mNewerRequests <= mNewerRequestsProcessed) { 39913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "queryForNewerEvents: "); 40013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mNewerRequests++; 40113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_NEWER)); 40213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 40313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 40413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (position < PREFETCH_BOUNDARY 40513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && mOlderRequests <= mOlderRequestsProcessed) { 40613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "queryForOlderEvents: "); 40713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mOlderRequests++; 40813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_OLDER)); 40913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 41013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 411a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa final View v; 41213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 41313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 4142d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson int offset = position - info.offset; 4152d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson v = info.dayAdapter.getView(offset, convertView, 41613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan parent); 4172d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson 4182d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // Turn on the past/present separator if the view is a day header 4192d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // and it is the first day with events after yesterday. 4202d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info.dayAdapter.isDayHeaderView(offset)) { 4212d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson View simpleDivider = v.findViewById(R.id.top_divider_simple); 4222d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson View pastPresentDivider = v.findViewById(R.id.top_divider_past_present); 4232d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info.dayAdapter.isFirstDayAfterYesterday(offset)) { 4242d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (simpleDivider != null && pastPresentDivider != null) { 4252d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson simpleDivider.setVisibility(View.GONE); 4262d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson pastPresentDivider.setVisibility(View.VISIBLE); 4272d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 4282d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } else if (simpleDivider != null && pastPresentDivider != null) { 4292d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson simpleDivider.setVisibility(View.VISIBLE); 4302d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson pastPresentDivider.setVisibility(View.GONE); 4312d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 4322d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 43313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 4342d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // TODO 43513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "BUG: getAdapterInfoByPosition returned null!!! " + position); 43613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView tv = new TextView(mContext); 43713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan tv.setText("Bug! " + position); 43813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan v = tv; 43913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 44013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 44133de4c48430262a0509ffe50fc376b87520cb938RoboErik // If this is not a tablet config don't do selection highlighting 44233de4c48430262a0509ffe50fc376b87520cb938RoboErik if (!mIsTabletConfig) { 44333de4c48430262a0509ffe50fc376b87520cb938RoboErik return v; 44433de4c48430262a0509ffe50fc376b87520cb938RoboErik } 445ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan // Show selected marker if this is item is selected 446ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan boolean selected = false; 447ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Object yy = v.getTag(); 448ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (yy instanceof AgendaAdapter.ViewHolder) { 449ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan AgendaAdapter.ViewHolder vh = (AgendaAdapter.ViewHolder) yy; 450ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan selected = mSelectedInstanceId == vh.instanceId; 45196a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson vh.selectedMarker.setVisibility((selected && mShowEventOnStart) ? 45296a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson View.VISIBLE : View.GONE); 453ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (selected) { 454163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan v.setBackgroundColor(mSelectedItemBackgroundColor); 455163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan vh.title.setTextColor(mSelectedItemTextColor); 456163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan vh.when.setTextColor(mSelectedItemTextColor); 457163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan vh.where.setTextColor(mSelectedItemTextColor); 458ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 459a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } 460a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 46113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) { 46213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "getView " + position + " = " + getViewTitle(v)); 46313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 46413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return v; 46513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 46613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 46713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int findDayPositionNearestTime(Time time) { 46813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "findDayPositionNearestTime " + time); 46913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 47013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByTime(time); 47113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 47213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.offset + info.dayAdapter.findDayPositionNearestTime(time); 47313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 47413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 47513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 47613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 47713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 4789a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson protected DayAdapterInfo getAdapterInfoByPosition(int position) { 47913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 48013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mLastUsedInfo != null && mLastUsedInfo.offset <= position 48113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && position < (mLastUsedInfo.offset + mLastUsedInfo.size)) { 48213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mLastUsedInfo; 48313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 48413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info : mAdapterInfos) { 48513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info.offset <= position 48613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && position < (info.offset + info.size)) { 48713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mLastUsedInfo = info; 48813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info; 48913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 49013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 49113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 49213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 49313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 49413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 49513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo getAdapterInfoByTime(Time time) { 49613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "getAdapterInfoByTime " + time.toString()); 49713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 49813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time tmpTime = new Time(time); 49913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long timeInMillis = tmpTime.normalize(true); 50013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int day = Time.getJulianDay(timeInMillis, tmpTime.gmtoff); 50113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 50213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info : mAdapterInfos) { 50313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info.start <= day && day < info.end) { 50413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info; 50513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 50613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 50713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 50813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 50913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 51013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 511a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa public EventInfo getEventByPosition(final int positionInListView) { 512a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (DEBUGLOG) Log.e(TAG, "getEventByPosition " + positionInListView); 51313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 514a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa final int positionInAdapter = positionInListView - OFF_BY_ONE_BUG; 515a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa DayAdapterInfo info = getAdapterInfoByPosition(positionInAdapter); 51613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info == null) { 51713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 51813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 51913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 520a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa int cursorPosition = info.dayAdapter.getCursorPosition(positionInAdapter - info.offset); 521a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition == Integer.MIN_VALUE) { 52213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 52313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 52413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 52513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan boolean isDayHeader = false; 526a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition < 0) { 527a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa cursorPosition = -cursorPosition; 52813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan isDayHeader = true; 52913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 53013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 531a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition < info.cursor.getCount()) { 532a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa info.cursor.moveToPosition(cursorPosition); 533ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan return buildEventInfoFromCursor(info.cursor, isDayHeader); 53413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 53513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 53613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 53713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 538ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan private EventInfo buildEventInfoFromCursor(final Cursor cursor, boolean isDayHeader) { 539ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan EventInfo event = new EventInfo(); 540ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan event.begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN); 541f836d4af478310abc9b63f1afa6ab964e2478fedRoboErik event.end = cursor.getLong(AgendaWindowAdapter.INDEX_END); 542ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan event.startDay = cursor.getInt(AgendaWindowAdapter.INDEX_START_DAY); 543ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 544ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan boolean allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0; 545ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (allDay) { // UTC 546ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Time time = new Time(mTimeZone); 547ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.setJulianDay(Time.getJulianDay(event.begin, 0)); 548ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan event.begin = time.toMillis(false /* use isDst */); 549ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } else if (isDayHeader) { // Trim to midnight. 550ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Time time = new Time(mTimeZone); 551ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.set(event.begin); 552ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.hour = 0; 553ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.minute = 0; 554ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.second = 0; 555ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan event.begin = time.toMillis(false /* use isDst */); 556ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 557ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 558ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (!isDayHeader) { 559ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson if (allDay) { 560ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson Time time = new Time(mTimeZone); 561ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson time.setJulianDay(Time.getJulianDay(event.end, 0)); 562ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson event.end = time.toMillis(false /* use isDst */); 563ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson } else { 564ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson event.end = cursor.getLong(AgendaWindowAdapter.INDEX_END); 565ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson } 566ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson 567ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan event.id = cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID); 568ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 569ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan return event; 570ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 571ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 572ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson public void refresh(Time goToTime, long id, String searchQuery, boolean forced) { 5734003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (searchQuery != null) { 5744003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mSearchQuery = searchQuery; 5754003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 5764003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 577c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan if (DEBUGLOG) { 578f836d4af478310abc9b63f1afa6ab964e2478fedRoboErik Log.e(TAG, this + ": refresh " + goToTime.toString() 579f836d4af478310abc9b63f1afa6ab964e2478fedRoboErik + (forced ? " forced" : " not forced")); 580c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 5817278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik 58223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan int startDay = Time.getJulianDay(goToTime.toMillis(false), goToTime.gmtoff); 58313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 58413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!forced && isInRange(startDay, startDay)) { 585ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson // No need to re-query 586ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson if (!mAgendaListView.isEventVisible(goToTime, id)) { 587cf6a46c5c81334f7c960ecc5fd354a14f1c4037cMichael Chan mAgendaListView.setSelection(findDayPositionNearestTime(goToTime) + OFF_BY_ONE_BUG 588cf6a46c5c81334f7c960ecc5fd354a14f1c4037cMichael Chan + mSkipDateHeader); 589e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik Time actualTime = new Time(mTimeZone); 590e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik actualTime.set(mAgendaListView.getFirstVisibleTime()); 591e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik CalendarController.getInstance(mContext).sendEvent(this, EventType.UPDATE_TITLE, 592e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik actualTime, actualTime, -1, ViewType.CURRENT); 593ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson } 59413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return; 59513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 59613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 597088a7d0d8c4d0652a42b8bbeb940421cea5ad8dcMichael Chan // Query for a total of MIN_QUERY_DURATION days 59813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int endDay = startDay + MIN_QUERY_DURATION; 59913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6009138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queueQuery(startDay, endDay, goToTime, searchQuery, QUERY_TYPE_CLEAN); 60113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 60313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void close() { 60413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mShuttingDown = true; 60513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan pruneAdapterInfo(QUERY_TYPE_CLEAN); 60613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mQueryHandler != null) { 60713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryHandler.cancelOperation(0); 60813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 61013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 61113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo pruneAdapterInfo(int queryType) { 61213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 61313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo recycleMe = null; 61413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 61513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.size() >= MAX_NUM_OF_ADAPTERS) { 61613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (queryType == QUERY_TYPE_NEWER) { 61713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = mAdapterInfos.removeFirst(); 61813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (queryType == QUERY_TYPE_OLDER) { 61913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = mAdapterInfos.removeLast(); 62013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Keep the size only if the oldest items are removed. 62113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.size = 0; 62213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 62313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe != null) { 62413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe.cursor != null) { 62513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.cursor.close(); 62613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 62713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return recycleMe; 62813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 62913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 63013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 63113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mRowCount == 0 || queryType == QUERY_TYPE_CLEAN) { 63213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount = 0; 63313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int deletedRows = 0; 63413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info; 63513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan do { 63613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info = mAdapterInfos.poll(); 63713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 638bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // TODO the following causes ANR's. Do this in a thread. 63913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.cursor.close(); 64013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan deletedRows += info.size; 64113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = info; 64213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 64313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } while (info != null); 64413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 64513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe != null) { 64613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.cursor = null; 64713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.size = deletedRows; 64813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 64913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 65013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 65113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return recycleMe; 65213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 65313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 65413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 65513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private String buildQuerySelection() { 65613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Respect the preference to show/hide declined events 65713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 65813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mHideDeclined) { 659950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden return Calendars.VISIBLE + "=1 AND " 66013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + Instances.SELF_ATTENDEE_STATUS + "!=" 66113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + Attendees.ATTENDEE_STATUS_DECLINED; 66213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 663950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden return Calendars.VISIBLE + "=1"; 66413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 66513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 66613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6679138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private Uri buildQueryUri(int start, int end, String searchQuery) { 6689138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri rootUri = searchQuery == null ? 6699138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Instances.CONTENT_BY_DAY_URI : 6709138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Instances.CONTENT_SEARCH_BY_DAY_URI; 6719138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri.Builder builder = rootUri.buildUpon(); 6729138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang ContentUris.appendId(builder, start); 6739138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang ContentUris.appendId(builder, end); 6749138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang if (searchQuery != null) { 6759138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang builder.appendPath(searchQuery); 6769138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang } 6779138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang return builder.build(); 67813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 67913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 68013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean isInRange(int start, int end) { 68113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 68213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.isEmpty()) { 68313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 68413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 68513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mAdapterInfos.getFirst().start <= start && end <= mAdapterInfos.getLast().end; 68613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 68713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 68813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 68913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int calculateQueryDuration(int start, int end) { 69013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryDuration = MAX_QUERY_DURATION; 69113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mRowCount != 0) { 69213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = IDEAL_NUM_OF_EVENTS * (end - start + 1) / mRowCount; 69313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 69413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 69513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (queryDuration > MAX_QUERY_DURATION) { 69613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = MAX_QUERY_DURATION; 69713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (queryDuration < MIN_QUERY_DURATION) { 69813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = MIN_QUERY_DURATION; 69913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 70013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 70113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queryDuration; 70213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 70313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7049138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private boolean queueQuery(int start, int end, Time goToTime, 7059138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang String searchQuery, int queryType) { 70613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec queryData = new QuerySpec(queryType); 70713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.goToTime = goToTime; 70813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = start; 70913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = end; 7109138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.searchQuery = searchQuery; 71113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queueQuery(queryData); 71213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 71313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 71413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean queueQuery(QuerySpec queryData) { 7159138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.searchQuery = mSearchQuery; 71613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Boolean queuedQuery; 71713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mQueryQueue) { 71813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queuedQuery = false; 71913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Boolean doQueryNow = mQueryQueue.isEmpty(); 72023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mQueryQueue.add(queryData); 72123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan queuedQuery = true; 72223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (doQueryNow) { 72323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan doQuery(queryData); 72413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 72513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 72613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queuedQuery; 72713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 72813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 72913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private void doQuery(QuerySpec queryData) { 73013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 73113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start = mAdapterInfos.getFirst().start; 73213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end = mAdapterInfos.getLast().end; 73313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryDuration = calculateQueryDuration(start, end); 73413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan switch(queryData.queryType) { 73513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_OLDER: 73613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = start - 1; 73713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = queryData.end - queryDuration; 73813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 73913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_NEWER: 74013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = end + 1; 74113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = queryData.start + queryDuration; 74213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 74313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 74613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) { 7479a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 74813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(queryData.start); 7499a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time2 = new Time(mTimeZone); 75013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time2.setJulianDay(queryData.end); 75113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.v(TAG, "startQuery: " + time.toString() + " to " 75213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + time2.toString() + " then go to " + queryData.goToTime); 75313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 75413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 75513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryHandler.cancelOperation(0); 75613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) queryData.queryStartMillis = System.nanoTime(); 7579138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 7589138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri queryUri = buildQueryUri( 7599138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.start, queryData.end, queryData.searchQuery); 7609138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mQueryHandler.startQuery(0, queryData, queryUri, 7619138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang PROJECTION, buildQuerySelection(), null, 7629138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang AGENDA_SORT_ORDER); 76313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 76413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 76513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private String formatDateString(int julianDay) { 7669a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 76713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(julianDay); 76813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long millis = time.toMillis(false); 76913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder.setLength(0); 77013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return DateUtils.formatDateRange(mContext, mFormatter, millis, millis, 77113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE 7729a88873f9ec97b47aaaaae47208d22b3998b8e99Erik | DateUtils.FORMAT_ABBREV_MONTH, mTimeZone).toString(); 77313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 77413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 77513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private void updateHeaderFooter(final int start, final int end) { 77613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setText(mContext.getString(R.string.show_older_events, 77713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan formatDateString(start))); 77813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView.setText(mContext.getString(R.string.show_newer_events, 77913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan formatDateString(end))); 78013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 78113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 78213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private class QueryHandler extends AsyncQueryHandler { 78313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 78413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public QueryHandler(ContentResolver cr) { 78513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan super(cr); 78613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 78713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 78813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 78913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 79013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec data = (QuerySpec)cookie; 79113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) { 79213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long queryEndMillis = System.nanoTime(); 79313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "Query time(ms): " 79413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + (queryEndMillis - data.queryStartMillis) / 1000000 79513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + " Count: " + cursor.getCount()); 79613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 79713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 79813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mShuttingDown) { 79913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan cursor.close(); 80013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return; 80113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 80213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 80313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Notify Listview of changes and update position 80413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int cursorSize = cursor.getCount(); 8057278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik if (cursorSize > 0 || mAdapterInfos.isEmpty() || data.queryType == QUERY_TYPE_CLEAN) { 80613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan final int listPositionOffset = processNewCursor(data, cursor); 80713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (data.goToTime == null) { // Typical Scrolling type query 80813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan notifyDataSetChanged(); 80913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (listPositionOffset != 0) { 81013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.shiftSelection(listPositionOffset); 81113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 81213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { // refresh() called. Go to the designated position 81313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan final Time goToTime = data.goToTime; 81413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan notifyDataSetChanged(); 81513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int newPosition = findDayPositionNearestTime(goToTime); 81613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (newPosition >= 0) { 817cf6a46c5c81334f7c960ecc5fd354a14f1c4037cMichael Chan mAgendaListView.setSelection(newPosition + OFF_BY_ONE_BUG 818cf6a46c5c81334f7c960ecc5fd354a14f1c4037cMichael Chan + mSkipDateHeader); 819e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik Time actualTime = new Time(mTimeZone); 820e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik actualTime.set(mAgendaListView.getFirstVisibleTime()); 821e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik CalendarController.getInstance(mContext).sendEvent(this, 822e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik EventType.UPDATE_TITLE, actualTime, actualTime, -1, 823e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik ViewType.CURRENT); 82413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 8257278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik if (DEBUGLOG) { 82613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "Setting listview to " + 8277278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik "findDayPositionNearestTime: " + (newPosition + OFF_BY_ONE_BUG)); 8287278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik } 82913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 830ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 83192ea39440681f86205ad10771f1770c550552320Michael Chan // size == 1 means a fresh query. Possibly after the data changed. 83292ea39440681f86205ad10771f1770c550552320Michael Chan // Let's check whether mSelectedInstanceId is still valid. 83392ea39440681f86205ad10771f1770c550552320Michael Chan if (mAdapterInfos.size() == 1 && mSelectedInstanceId != -1) { 83492ea39440681f86205ad10771f1770c550552320Michael Chan boolean found = false; 83592ea39440681f86205ad10771f1770c550552320Michael Chan cursor.moveToPosition(-1); 83692ea39440681f86205ad10771f1770c550552320Michael Chan while (cursor.moveToNext()) { 83792ea39440681f86205ad10771f1770c550552320Michael Chan if (mSelectedInstanceId == cursor 83892ea39440681f86205ad10771f1770c550552320Michael Chan .getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID)) { 83992ea39440681f86205ad10771f1770c550552320Michael Chan found = true; 84092ea39440681f86205ad10771f1770c550552320Michael Chan break; 84192ea39440681f86205ad10771f1770c550552320Michael Chan } 84292ea39440681f86205ad10771f1770c550552320Michael Chan }; 84392ea39440681f86205ad10771f1770c550552320Michael Chan 84492ea39440681f86205ad10771f1770c550552320Michael Chan if (!found) { 84592ea39440681f86205ad10771f1770c550552320Michael Chan mSelectedInstanceId = -1; 84692ea39440681f86205ad10771f1770c550552320Michael Chan } 84792ea39440681f86205ad10771f1770c550552320Michael Chan } 84892ea39440681f86205ad10771f1770c550552320Michael Chan 849ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (mSelectedInstanceId == -1 && cursor.moveToFirst()) { 850ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan mSelectedInstanceId = cursor.getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID); 851ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 852ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan EventInfo event = buildEventInfoFromCursor(cursor, false); 85396a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson if (mShowEventOnStart) { 85496a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson CalendarController.getInstance(mContext).sendEventRelatedEvent(this, 85596a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson EventType.VIEW_EVENT, event.id, event.begin, event.end, 0, 0, -1); 85696a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson } 857ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 85813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 85913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan cursor.close(); 86013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 86113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 86213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update header and footer 86313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mDoneSettingUpHeaderFooter) { 86413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan OnClickListener headerFooterOnClickListener = new OnClickListener() { 86513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void onClick(View v) { 86613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (v == mHeaderView) { 86713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_OLDER)); 86813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 86913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_NEWER)); 87013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 87113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan }}; 87213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setOnClickListener(headerFooterOnClickListener); 87313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView.setOnClickListener(headerFooterOnClickListener); 87413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.addFooterView(mFooterView); 87513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mDoneSettingUpHeaderFooter = true; 87613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 87713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mQueryQueue) { 87813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int totalAgendaRangeStart = -1; 87913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int totalAgendaRangeEnd = -1; 88013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 88113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (cursorSize != 0) { 88213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Remove the query that just completed 88313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec x = mQueryQueue.poll(); 88423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (BASICLOG && !x.equals(data)) { 88523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan Log.e(TAG, "onQueryComplete - cookie != head of queue"); 88623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 88713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mEmptyCursorCount = 0; 88823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (data.queryType == QUERY_TYPE_NEWER) { 88923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mNewerRequestsProcessed++; 89023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } else if (data.queryType == QUERY_TYPE_OLDER) { 89123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mOlderRequestsProcessed++; 89223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 89313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 89413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = mAdapterInfos.getFirst().start; 89513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = mAdapterInfos.getLast().end; 89613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { // CursorSize == 0 89713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec querySpec = mQueryQueue.peek(); 89813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 89913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update Adapter Info with new start and end date range 90013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 90113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo first = mAdapterInfos.getFirst(); 90213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo last = mAdapterInfos.getLast(); 90313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 90413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (first.start - 1 <= querySpec.end && querySpec.start < first.start) { 90513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan first.start = querySpec.start; 90613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 90713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 90813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (querySpec.start <= last.end + 1 && last.end < querySpec.end) { 90913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan last.end = querySpec.end; 91013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 91113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 91213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = first.start; 91313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = last.end; 91413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 91513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 91613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 91713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 91813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 91913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update query specification with expanded search range 92013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // and maybe rerun query 92113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan switch (querySpec.queryType) { 92213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_OLDER: 92313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 92413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.start -= MAX_QUERY_DURATION; 92513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 92613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_NEWER: 92713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 92813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.end += MAX_QUERY_DURATION; 92913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 93013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_CLEAN: 93113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 93213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 93313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.start -= MAX_QUERY_DURATION / 2; 93413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.end += MAX_QUERY_DURATION / 2; 93513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 93613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 93713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 93813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (++mEmptyCursorCount > RETRIES_ON_NO_DATA) { 93913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Nothing in the cursor again. Dropping query 94013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryQueue.poll(); 94113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 94213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 94313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 94413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan updateHeaderFooter(totalAgendaRangeStart, totalAgendaRangeEnd); 94513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 9462d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // Go over the events and mark the first day after yesterday 9472d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // that has events in it 9482d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson synchronized (mAdapterInfos) { 9492d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson DayAdapterInfo info = mAdapterInfos.getFirst(); 9502d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info != null) { 9512d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson Time time = new Time(mTimeZone); 9522d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson long now = System.currentTimeMillis(); 9532d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson time.set(now); 9542d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson int JulianToday = Time.getJulianDay(now, time.gmtoff); 9552d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson Iterator<DayAdapterInfo> iter = mAdapterInfos.iterator(); 9562d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson boolean foundDay = false; 9572d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson while (iter.hasNext() && !foundDay) { 9582d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson info = iter.next(); 9592d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson for (int i = 0; i < info.size; i++) { 9602d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info.dayAdapter.findJulianDayFromPosition(i) >= JulianToday) { 9612d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson info.dayAdapter.setAsFirstDayAfterYesterday(i); 9622d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson foundDay = true; 9632d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson break; 9642d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 9652d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 9662d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 9672d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 9682d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 9692d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson 97013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Fire off the next query if any 97113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Iterator<QuerySpec> it = mQueryQueue.iterator(); 97213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan while (it.hasNext()) { 97313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec queryData = it.next(); 97413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!isInRange(queryData.start, queryData.end)) { 97513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Query accepted 97613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "Query accepted. QueueSize:" + mQueryQueue.size()); 97713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan doQuery(queryData); 97813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 97913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 98013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Query rejected 98113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan it.remove(); 98213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "Query rejected. QueueSize:" + mQueryQueue.size()); 98313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 98413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 98513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 98623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (BASICLOG) { 98713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info3 : mAdapterInfos) { 98813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "> " + info3.toString()); 98913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 99013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 99113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 99213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 99313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan /* 99413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * Update the adapter info array with a the new cursor. Close out old 99513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * cursors as needed. 99613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * 99713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * @return number of rows removed from the beginning 99813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 99913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int processNewCursor(QuerySpec data, Cursor cursor) { 100013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 100113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Remove adapter info's from adapterInfos as needed 100213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = pruneAdapterInfo(data.queryType); 100313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int listPositionOffset = 0; 100413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info == null) { 100513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info = new DayAdapterInfo(mContext); 100613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 100713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) 100813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "processNewCursor listPositionOffsetA=" 100913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + -info.size); 101013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listPositionOffset = -info.size; 101113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 101213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 101313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Setup adapter info 101413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.start = data.start; 101513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.end = data.end; 101613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.cursor = cursor; 1017dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan info.dayAdapter.changeCursor(info); 101813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.size = info.dayAdapter.getCount(); 101913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 102013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Insert into adapterInfos 102113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.isEmpty() 102213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan || data.end <= mAdapterInfos.getFirst().start) { 102313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addFirst(info); 102413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listPositionOffset += info.size; 102513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (BASICLOG && data.start < mAdapterInfos.getLast().end) { 102613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addLast(info); 102713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info2 : mAdapterInfos) { 102813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e("========== BUG ==", info2.toString()); 102913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 103013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 103113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addLast(info); 103213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 103313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 103413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update offsets in adapterInfos 103513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount = 0; 103613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info3 : mAdapterInfos) { 103713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info3.offset = mRowCount; 103813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount += info3.size; 103913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 104013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mLastUsedInfo = null; 104113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 104213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return listPositionOffset; 104313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 104413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 104513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 104613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 104713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static String getViewTitle(View x) { 104813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan String title = ""; 104913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (x != null) { 105013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Object yy = x.getTag(); 105113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (yy instanceof AgendaAdapter.ViewHolder) { 105213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView tv = ((AgendaAdapter.ViewHolder) yy).title; 105313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (tv != null) { 105413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan title = (String) tv.getText(); 105513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 105613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (yy != null) { 105713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView dateView = ((AgendaByDayAdapter.ViewHolder) yy).dateView; 105813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (dateView != null) { 105913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan title = (String) dateView.getText(); 106013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 106113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 106213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 106313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return title; 106413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 106513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 10669a88873f9ec97b47aaaaae47208d22b3998b8e99Erik public void onResume() { 10679a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTZUpdater.run(); 10689a88873f9ec97b47aaaaae47208d22b3998b8e99Erik } 10699a88873f9ec97b47aaaaae47208d22b3998b8e99Erik 107013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void setHideDeclinedEvents(boolean hideDeclined) { 107113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHideDeclined = hideDeclined; 107213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 1073a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 1074ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public void setSelectedView(View v) { 1075ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (v != null) { 1076ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Object vh = v.getTag(); 1077ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (vh instanceof AgendaAdapter.ViewHolder) { 1078ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan mSelectedInstanceId = ((AgendaAdapter.ViewHolder) vh).instanceId; 1079ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1080ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1081ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1082ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 1083ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public long getSelectedInstanceId() { 1084ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan return mSelectedInstanceId; 1085ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1086ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 1087ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public void setSelectedInstanceId(long selectedInstanceId) { 1088ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan mSelectedInstanceId = selectedInstanceId; 1089a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } 109037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 109137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 109237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // Implementation of HeaderIndexer interface for StickyHeeaderListView 109337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 109437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // Returns the location of the day header of a specific event specified in the position 109537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // in the adapter 109637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson public int getHeaderPositionFromItemPosition(int position) { 1097980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson 1098980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson // For phone configuration, return -1 so there will be no sticky header 1099980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson if (!mIsTabletConfig) { 1100980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson return -1; 1101980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson } 1102980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson 110337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(position); 110437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson if (info != null) { 110537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson int pos = info.dayAdapter.getHeaderPosition(position - info.offset); 110637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return (pos != -1)?(pos + info.offset):-1; 110737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 110837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return -1; 110937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 111037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 111137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // Returns the number of events for a specific day header 111237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson public int getHeaderItemsNumber(int headerPosition) { 1113980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson if (headerPosition < 0 || !mIsTabletConfig) { 111437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return -1; 111537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 111637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(headerPosition); 111737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson if (info != null) { 111837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return info.dayAdapter.getHeaderItemsCount(headerPosition - info.offset); 111937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 112037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return -1; 112137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 112213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan} 1123