AgendaWindowAdapter.java revision a9507932dbc49ecb9f5c71fda6af3a47b0b2a39a
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 1900b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangimport com.android.calendar.R; 2000b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangimport com.android.calendar.Utils; 2113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 2213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.AsyncQueryHandler; 2313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.ContentResolver; 249138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.content.ContentUris; 2513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.Context; 26a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawaimport android.content.res.Resources; 2713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.database.Cursor; 28a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawaimport android.graphics.Color; 2913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.net.Uri; 309138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.provider.Calendar; 3113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.provider.Calendar.Attendees; 3213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.provider.Calendar.Calendars; 3313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.provider.Calendar.Instances; 3413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.text.format.DateUtils; 3513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.text.format.Time; 3613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.util.Log; 3713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.LayoutInflater; 3813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.View; 3913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.View.OnClickListener; 409a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport android.view.ViewGroup; 4113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.widget.BaseAdapter; 4213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.widget.TextView; 4313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 4413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Formatter; 4513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Iterator; 4613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.LinkedList; 4713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Locale; 4813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.concurrent.ConcurrentLinkedQueue; 4913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan/* 5113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanBugs Bugs Bugs: 5213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- At rotation and launch time, the initial position is not set properly. This code is calling 5313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listview.setSelection() in 2 rapid secessions but it dropped or didn't process the first one. 5413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Scroll using trackball isn't repositioning properly after a new adapter is added. 5523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan- Track ball clicks at the header/footer doesn't work. 5613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Potential ping pong effect if the prefetch window is big and data is limited 5713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Add index in calendar provider 5813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanToDo ToDo ToDo: 6013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanGet design of header and footer from designer 6113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanMake scrolling smoother. 6313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanTest for correctness 6413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanLoading speed 6513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanCheck for leaks and excessive allocations 6613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 6713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanpublic class AgendaWindowAdapter extends BaseAdapter { 6913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan static final boolean BASICLOG = false; 7123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan static final boolean DEBUGLOG = false; 72a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private static final String TAG = "AgendaWindowAdapter"; 7313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 749138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private static final String AGENDA_SORT_ORDER = 75a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa Calendar.Instances.START_DAY + " ASC, " + 76a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa Calendar.Instances.BEGIN + " ASC, " + 77a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa Calendar.Events.TITLE + " ASC"; 789138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 7913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_TITLE = 1; 8013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_EVENT_LOCATION = 2; 8113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_ALL_DAY = 3; 8213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_HAS_ALARM = 4; 8313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_COLOR = 5; 8413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_RRULE = 6; 8513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_BEGIN = 7; 8613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_END = 8; 8713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_EVENT_ID = 9; 8813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_START_DAY = 10; 8913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_END_DAY = 11; 9013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_SELF_ATTENDEE_STATUS = 12; 9113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 9213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final String[] PROJECTION = new String[] { 9313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances._ID, // 0 9413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.TITLE, // 1 9513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.EVENT_LOCATION, // 2 9613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.ALL_DAY, // 3 9713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.HAS_ALARM, // 4 9813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.COLOR, // 5 9913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.RRULE, // 6 10013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.BEGIN, // 7 10113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.END, // 8 10213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.EVENT_ID, // 9 10313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.START_DAY, // 10 Julian start day 10413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.END_DAY, // 11 Julian end day 10513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.SELF_ATTENDEE_STATUS, // 12 10613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan }; 10713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 10813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Listview may have a bug where the index/position is not consistent when there's a header. 109a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa // position == positionInListView - OFF_BY_ONE_BUG 11013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // TODO Need to look into this. 11113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int OFF_BY_ONE_BUG = 1; 11213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MAX_NUM_OF_ADAPTERS = 5; 11313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int IDEAL_NUM_OF_EVENTS = 50; 11413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MIN_QUERY_DURATION = 7; // days 11513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MAX_QUERY_DURATION = 60; // days 11613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int PREFETCH_BOUNDARY = 1; 11713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1189138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Times to auto-expand/retry query after getting no data */ 1199138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private static final int RETRIES_ON_NO_DATA = 1; 12013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 12113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private Context mContext; 122a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private Resources mResources; 12313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private QueryHandler mQueryHandler; 12413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private AgendaListView mAgendaListView; 12513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1269138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The sum of the rows in all the adapters */ 1279138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private int mRowCount; 12813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1299138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The number of times we have queried and gotten no results back */ 13013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mEmptyCursorCount; 13113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1329138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Cached value of the last used adapter */ 1339138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private DayAdapterInfo mLastUsedInfo; 13413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 135a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final LinkedList<DayAdapterInfo> mAdapterInfos = 136a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa new LinkedList<DayAdapterInfo>(); 137a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final ConcurrentLinkedQueue<QuerySpec> mQueryQueue = 138a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa new ConcurrentLinkedQueue<QuerySpec>(); 13913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private TextView mHeaderView; 14013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private TextView mFooterView; 14113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mDoneSettingUpHeaderFooter = false; 14213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1439138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 14413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * When the user scrolled to the top, a query will be made for older events 14513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * and this will be incremented. Don't make more requests if 14613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * mOlderRequests > mOlderRequestsProcessed. 14713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 14813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mOlderRequests; 14913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1509138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Number of "older" query that has been processed. */ 15113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mOlderRequestsProcessed; 15213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1539138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 15413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * When the user scrolled to the bottom, a query will be made for newer 15513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * events and this will be incremented. Don't make more requests if 15613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * mNewerRequests > mNewerRequestsProcessed. 15713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 15813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mNewerRequests; 15913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1609138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Number of "newer" query that has been processed. */ 16113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mNewerRequestsProcessed; 16213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 16323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread. 16423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan private Formatter mFormatter; 16513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private StringBuilder mStringBuilder; 1669a88873f9ec97b47aaaaae47208d22b3998b8e99Erik private String mTimeZone; 1679a88873f9ec97b47aaaaae47208d22b3998b8e99Erik 1689a88873f9ec97b47aaaaae47208d22b3998b8e99Erik private Runnable mTZUpdater = new Runnable() { 1699a88873f9ec97b47aaaaae47208d22b3998b8e99Erik @Override 1709a88873f9ec97b47aaaaae47208d22b3998b8e99Erik public void run() { 1719a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTimeZone = Utils.getTimeZone(mContext, this); 1729a88873f9ec97b47aaaaae47208d22b3998b8e99Erik notifyDataSetChanged(); 1739a88873f9ec97b47aaaaae47208d22b3998b8e99Erik } 1749a88873f9ec97b47aaaaae47208d22b3998b8e99Erik }; 17513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 17613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mShuttingDown; 17713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mHideDeclined; 17813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1799138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The current search query, or null if none */ 1809138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private String mSearchQuery; 1819138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 182a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private int mSelectedPosition = -1; 183a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 184a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final int mSelectedAgendaItemColor; 185a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 18613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Types of Query 18713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_OLDER = 0; // Query for older events 18813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_NEWER = 1; // Query for newer events 18913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_CLEAN = 2; // Delete everything and query around a date 19013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 19113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static class QuerySpec { 19213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long queryStartMillis; 19313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time goToTime; 19413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start; 19513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end; 1969138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang String searchQuery; 19713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryType; 19813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 19913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public QuerySpec(int queryType) { 20013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan this.queryType = queryType; 20113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 20223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan 20323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan @Override 20423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan public int hashCode() { 20523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan final int prime = 31; 20623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan int result = 1; 20723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + end; 20823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + (int) (queryStartMillis ^ (queryStartMillis >>> 32)); 20923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + queryType; 21023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + start; 2119138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang result = prime * result + searchQuery.hashCode(); 21223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime != null) { 21323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan long goToTimeMillis = goToTime.toMillis(false); 21423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + (int) (goToTimeMillis ^ (goToTimeMillis >>> 32)); 21523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 21623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return result; 21723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 21823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan 21923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan @Override 22023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan public boolean equals(Object obj) { 22123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (this == obj) return true; 22223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (obj == null) return false; 22323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (getClass() != obj.getClass()) return false; 22423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan QuerySpec other = (QuerySpec) obj; 22523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (end != other.end || queryStartMillis != other.queryStartMillis 2269138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang || queryType != other.queryType || start != other.start 2279138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang || Utils.equals(searchQuery, other.searchQuery)) { 22823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 22923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 2309138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 23123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime != null) { 23223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime.toMillis(false) != other.goToTime.toMillis(false)) { 23323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 23423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 23523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } else { 23623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (other.goToTime != null) { 23723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 23823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 23923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 24023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return true; 24123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 24213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 24313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 24413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static class EventInfo { 24513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long begin; 24613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long end; 24713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long id; 24813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 24913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 250dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan static class DayAdapterInfo { 25113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Cursor cursor; 25213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan AgendaByDayAdapter dayAdapter; 25313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start; // start day of the cursor's coverage 25413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end; // end day of the cursor's coverage 25513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int offset; // offset in position in the list view 25613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int size; // dayAdapter.getCount() 25713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 25813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public DayAdapterInfo(Context context) { 25913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan dayAdapter = new AgendaByDayAdapter(context); 26013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 26113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 26213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 26313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public String toString() { 2649a88873f9ec97b47aaaaae47208d22b3998b8e99Erik // Static class, so the time in this toString will not reflect the 2659a88873f9ec97b47aaaaae47208d22b3998b8e99Erik // home tz settings. This should only affect debugging. 26613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time time = new Time(); 26713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan StringBuilder sb = new StringBuilder(); 26813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(start); 26913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.normalize(false); 27013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append("Start:").append(time.toString()); 27113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(end); 27213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.normalize(false); 27313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" End:").append(time.toString()); 27413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" Offset:").append(offset); 27513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" Size:").append(size); 27613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return sb.toString(); 27713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 27813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 27913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 2809138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang public AgendaWindowAdapter(Context context, 28113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan AgendaListView agendaListView) { 2829138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mContext = context; 283a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa mResources = context.getResources(); 284a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa mSelectedAgendaItemColor = mResources.getColor(R.color.agenda_item_selected); 285a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 2869a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTimeZone = Utils.getTimeZone(context, mTZUpdater); 28713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView = agendaListView; 2889138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mQueryHandler = new QueryHandler(context.getContentResolver()); 28913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 29013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder = new StringBuilder(50); 29113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 29213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 2939138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mSearchQuery = null; 2949138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 2959138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang LayoutInflater inflater = (LayoutInflater) context 29613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 29713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView = (TextView)inflater.inflate(R.layout.agenda_header_footer, null); 29813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView = (TextView)inflater.inflate(R.layout.agenda_header_footer, null); 29913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setText(R.string.loading); 30013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.addHeaderView(mHeaderView); 30113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 30213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 30313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in Adapter 30413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 30513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getViewTypeCount() { 30613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return AgendaByDayAdapter.TYPE_LAST; 30713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 30813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 30913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in BaseAdapter 31013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 31113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public boolean areAllItemsEnabled() { 31213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 31313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 31413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 31513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in Adapter 31613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 31713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getItemViewType(int position) { 31813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 31913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 32013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.getItemViewType(position - info.offset); 32113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 32213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 32313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 32413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 32513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 32613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in BaseAdapter 32713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 32813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public boolean isEnabled(int position) { 32913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 33013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 33113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.isEnabled(position - info.offset); 33213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 33313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 33413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 33513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 33613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 33713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 33813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getCount() { 33913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mRowCount; 34013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 34113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 34213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 34313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public Object getItem(int position) { 34413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 34513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 34613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.getItem(position - info.offset); 34713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 34813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 34913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 35013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 35113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 352c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan // Method in BaseAdapter 353c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan @Override 354c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan public boolean hasStableIds() { 355c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan return true; 356c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 357c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan 35813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 35913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public long getItemId(int position) { 36013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 36113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 362c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan return ((position - info.offset) << 20) + info.start ; 36313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 36413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 36513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 36813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 36913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public View getView(int position, View convertView, ViewGroup parent) { 37013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (position >= (mRowCount - PREFETCH_BOUNDARY) 37113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && mNewerRequests <= mNewerRequestsProcessed) { 37213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "queryForNewerEvents: "); 37313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mNewerRequests++; 37413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_NEWER)); 37513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 37613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 37713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (position < PREFETCH_BOUNDARY 37813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && mOlderRequests <= mOlderRequestsProcessed) { 37913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "queryForOlderEvents: "); 38013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mOlderRequests++; 38113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_OLDER)); 38213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 38313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 384a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa final View v; 38513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 38613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 38713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan v = info.dayAdapter.getView(position - info.offset, convertView, 38813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan parent); 38913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 39013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan //TODO 39113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "BUG: getAdapterInfoByPosition returned null!!! " + position); 39213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView tv = new TextView(mContext); 39313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan tv.setText("Bug! " + position); 39413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan v = tv; 39513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 39613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 397a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (mSelectedPosition == position) { 398a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa v.setBackgroundColor(mSelectedAgendaItemColor); 399a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } else { 400a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa v.setBackgroundResource(0); 401a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } 402a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 40313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) { 40413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "getView " + position + " = " + getViewTitle(v)); 40513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 40613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return v; 40713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 40813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 40913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int findDayPositionNearestTime(Time time) { 41013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "findDayPositionNearestTime " + time); 41113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 41213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByTime(time); 41313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 41413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.offset + info.dayAdapter.findDayPositionNearestTime(time); 41513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 41613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 41713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 41813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 41913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 42013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo getAdapterInfoByPosition(int position) { 42113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 42213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mLastUsedInfo != null && mLastUsedInfo.offset <= position 42313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && position < (mLastUsedInfo.offset + mLastUsedInfo.size)) { 42413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mLastUsedInfo; 42513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 42613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info : mAdapterInfos) { 42713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info.offset <= position 42813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && position < (info.offset + info.size)) { 42913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mLastUsedInfo = info; 43013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info; 43113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 43213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 43313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 43413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 43513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 43613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 43713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo getAdapterInfoByTime(Time time) { 43813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "getAdapterInfoByTime " + time.toString()); 43913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 44013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time tmpTime = new Time(time); 44113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long timeInMillis = tmpTime.normalize(true); 44213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int day = Time.getJulianDay(timeInMillis, tmpTime.gmtoff); 44313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 44413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info : mAdapterInfos) { 44513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info.start <= day && day < info.end) { 44613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info; 44713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 44813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 44913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 45013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 45113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 45213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 453a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa public EventInfo getEventByPosition(final int positionInListView) { 454a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (DEBUGLOG) Log.e(TAG, "getEventByPosition " + positionInListView); 45513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 45613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan EventInfo event = new EventInfo(); 457a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa final int positionInAdapter = positionInListView - OFF_BY_ONE_BUG; 458a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa DayAdapterInfo info = getAdapterInfoByPosition(positionInAdapter); 45913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info == null) { 46013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 46113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 46213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 463a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa int cursorPosition = info.dayAdapter.getCursorPosition(positionInAdapter - info.offset); 464a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition == Integer.MIN_VALUE) { 46513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 46613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 46713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 46813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan boolean isDayHeader = false; 469a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition < 0) { 470a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa cursorPosition = -cursorPosition; 47113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan isDayHeader = true; 47213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 47313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 474a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition < info.cursor.getCount()) { 475a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa info.cursor.moveToPosition(cursorPosition); 47613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan event.begin = info.cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN); 477c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan boolean allDay = info.cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0; 478c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan 479c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan if (allDay) { // UTC 4809a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 481c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan time.setJulianDay(Time.getJulianDay(event.begin, 0)); 482c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan event.begin = time.toMillis(false /* use isDst */); 483c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } else if (isDayHeader) { // Trim to midnight. 4849a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 48513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.set(event.begin); 48613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.hour = 0; 48713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.minute = 0; 48813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.second = 0; 48913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan event.begin = time.toMillis(false /* use isDst */); 490c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 491c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan 492c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan if (!isDayHeader) { 49313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan event.end = info.cursor.getLong(AgendaWindowAdapter.INDEX_END); 49413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan event.id = info.cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID); 49513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 49613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return event; 49713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 49813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 49913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 50013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5019138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang public void refresh(Time goToTime, String searchQuery, boolean forced) { 5024003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (searchQuery != null) { 5034003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mSearchQuery = searchQuery; 5044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 5054003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 506c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan if (DEBUGLOG) { 507c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan Log.e(TAG, "refresh " + goToTime.toString() + (forced ? " forced" : " not forced")); 508c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 5097278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik 51023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan int startDay = Time.getJulianDay(goToTime.toMillis(false), goToTime.gmtoff); 51113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 51213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!forced && isInRange(startDay, startDay)) { 51313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // No need to requery 51413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.setSelection(findDayPositionNearestTime(goToTime) + OFF_BY_ONE_BUG); 51513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return; 51613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 51713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 518088a7d0d8c4d0652a42b8bbeb940421cea5ad8dcMichael Chan // Query for a total of MIN_QUERY_DURATION days 51913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int endDay = startDay + MIN_QUERY_DURATION; 52013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5219138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queueQuery(startDay, endDay, goToTime, searchQuery, QUERY_TYPE_CLEAN); 52213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 52313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 52413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void close() { 52513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mShuttingDown = true; 52613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan pruneAdapterInfo(QUERY_TYPE_CLEAN); 52713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mQueryHandler != null) { 52813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryHandler.cancelOperation(0); 52913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 53013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 53113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 53213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo pruneAdapterInfo(int queryType) { 53313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 53413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo recycleMe = null; 53513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 53613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.size() >= MAX_NUM_OF_ADAPTERS) { 53713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (queryType == QUERY_TYPE_NEWER) { 53813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = mAdapterInfos.removeFirst(); 53913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (queryType == QUERY_TYPE_OLDER) { 54013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = mAdapterInfos.removeLast(); 54113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Keep the size only if the oldest items are removed. 54213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.size = 0; 54313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 54413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe != null) { 54513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe.cursor != null) { 54613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.cursor.close(); 54713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 54813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return recycleMe; 54913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 55013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 55113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 55213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mRowCount == 0 || queryType == QUERY_TYPE_CLEAN) { 55313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount = 0; 55413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int deletedRows = 0; 55513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info; 55613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan do { 55713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info = mAdapterInfos.poll(); 55813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 559bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // TODO the following causes ANR's. Do this in a thread. 56013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.cursor.close(); 56113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan deletedRows += info.size; 56213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = info; 56313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 56413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } while (info != null); 56513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 56613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe != null) { 56713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.cursor = null; 56813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.size = deletedRows; 56913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 57013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 57113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 57213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return recycleMe; 57313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 57413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 57513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 57613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private String buildQuerySelection() { 57713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Respect the preference to show/hide declined events 57813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 57913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mHideDeclined) { 58013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return Calendars.SELECTED + "=1 AND " 58113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + Instances.SELF_ATTENDEE_STATUS + "!=" 58213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + Attendees.ATTENDEE_STATUS_DECLINED; 58313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 58413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return Calendars.SELECTED + "=1"; 58513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 58613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 58713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5889138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private Uri buildQueryUri(int start, int end, String searchQuery) { 5899138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri rootUri = searchQuery == null ? 5909138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Instances.CONTENT_BY_DAY_URI : 5919138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Instances.CONTENT_SEARCH_BY_DAY_URI; 5929138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri.Builder builder = rootUri.buildUpon(); 5939138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang ContentUris.appendId(builder, start); 5949138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang ContentUris.appendId(builder, end); 5959138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang if (searchQuery != null) { 5969138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang builder.appendPath(searchQuery); 5979138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang } 5989138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang return builder.build(); 59913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 60113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean isInRange(int start, int end) { 60213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 60313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.isEmpty()) { 60413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 60513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mAdapterInfos.getFirst().start <= start && end <= mAdapterInfos.getLast().end; 60713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 61013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int calculateQueryDuration(int start, int end) { 61113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryDuration = MAX_QUERY_DURATION; 61213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mRowCount != 0) { 61313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = IDEAL_NUM_OF_EVENTS * (end - start + 1) / mRowCount; 61413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 61513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 61613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (queryDuration > MAX_QUERY_DURATION) { 61713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = MAX_QUERY_DURATION; 61813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (queryDuration < MIN_QUERY_DURATION) { 61913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = MIN_QUERY_DURATION; 62013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 62113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 62213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queryDuration; 62313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 62413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6259138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private boolean queueQuery(int start, int end, Time goToTime, 6269138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang String searchQuery, int queryType) { 62713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec queryData = new QuerySpec(queryType); 62813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.goToTime = goToTime; 62913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = start; 63013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = end; 6319138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.searchQuery = searchQuery; 63213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queueQuery(queryData); 63313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 63413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 63513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean queueQuery(QuerySpec queryData) { 6369138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.searchQuery = mSearchQuery; 63713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Boolean queuedQuery; 63813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mQueryQueue) { 63913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queuedQuery = false; 64013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Boolean doQueryNow = mQueryQueue.isEmpty(); 64123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mQueryQueue.add(queryData); 64223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan queuedQuery = true; 64323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (doQueryNow) { 64423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan doQuery(queryData); 64513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 64613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 64713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queuedQuery; 64813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 64913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 65013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private void doQuery(QuerySpec queryData) { 65113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 65213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start = mAdapterInfos.getFirst().start; 65313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end = mAdapterInfos.getLast().end; 65413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryDuration = calculateQueryDuration(start, end); 65513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan switch(queryData.queryType) { 65613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_OLDER: 65713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = start - 1; 65813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = queryData.end - queryDuration; 65913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 66013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_NEWER: 66113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = end + 1; 66213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = queryData.start + queryDuration; 66313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 66413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 66513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 66613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 66713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) { 6689a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 66913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(queryData.start); 6709a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time2 = new Time(mTimeZone); 67113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time2.setJulianDay(queryData.end); 67213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.v(TAG, "startQuery: " + time.toString() + " to " 67313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + time2.toString() + " then go to " + queryData.goToTime); 67413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 67513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 67613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryHandler.cancelOperation(0); 67713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) queryData.queryStartMillis = System.nanoTime(); 6789138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 6799138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri queryUri = buildQueryUri( 6809138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.start, queryData.end, queryData.searchQuery); 6819138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mQueryHandler.startQuery(0, queryData, queryUri, 6829138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang PROJECTION, buildQuerySelection(), null, 6839138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang AGENDA_SORT_ORDER); 68413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 68513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 68613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private String formatDateString(int julianDay) { 6879a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 68813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(julianDay); 68913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long millis = time.toMillis(false); 69013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder.setLength(0); 69113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return DateUtils.formatDateRange(mContext, mFormatter, millis, millis, 69213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE 6939a88873f9ec97b47aaaaae47208d22b3998b8e99Erik | DateUtils.FORMAT_ABBREV_MONTH, mTimeZone).toString(); 69413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 69513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 69613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private void updateHeaderFooter(final int start, final int end) { 69713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setText(mContext.getString(R.string.show_older_events, 69813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan formatDateString(start))); 69913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView.setText(mContext.getString(R.string.show_newer_events, 70013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan formatDateString(end))); 70113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 70213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 70313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private class QueryHandler extends AsyncQueryHandler { 70413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 70513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public QueryHandler(ContentResolver cr) { 70613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan super(cr); 70713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 70813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 70913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 71013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 71113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec data = (QuerySpec)cookie; 71213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) { 71313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long queryEndMillis = System.nanoTime(); 71413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "Query time(ms): " 71513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + (queryEndMillis - data.queryStartMillis) / 1000000 71613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + " Count: " + cursor.getCount()); 71713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 71813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 71913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mShuttingDown) { 72013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan cursor.close(); 72113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return; 72213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 72313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 72413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Notify Listview of changes and update position 72513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int cursorSize = cursor.getCount(); 7267278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik if (cursorSize > 0 || mAdapterInfos.isEmpty() || data.queryType == QUERY_TYPE_CLEAN) { 72713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan final int listPositionOffset = processNewCursor(data, cursor); 72813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (data.goToTime == null) { // Typical Scrolling type query 72913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan notifyDataSetChanged(); 73013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (listPositionOffset != 0) { 73113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.shiftSelection(listPositionOffset); 73213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 73313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { // refresh() called. Go to the designated position 73413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan final Time goToTime = data.goToTime; 73513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan notifyDataSetChanged(); 73613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int newPosition = findDayPositionNearestTime(goToTime); 73713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (newPosition >= 0) { 73813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.setSelection(newPosition + OFF_BY_ONE_BUG); 73913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 7407278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik if (DEBUGLOG) { 74113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "Setting listview to " + 7427278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik "findDayPositionNearestTime: " + (newPosition + OFF_BY_ONE_BUG)); 7437278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik } 74413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 74613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan cursor.close(); 74713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 74913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update header and footer 75013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mDoneSettingUpHeaderFooter) { 75113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan OnClickListener headerFooterOnClickListener = new OnClickListener() { 75213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void onClick(View v) { 75313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (v == mHeaderView) { 75413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_OLDER)); 75513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 75613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_NEWER)); 75713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 75813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan }}; 75913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setOnClickListener(headerFooterOnClickListener); 76013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView.setOnClickListener(headerFooterOnClickListener); 76113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.addFooterView(mFooterView); 76213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mDoneSettingUpHeaderFooter = true; 76313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 76413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mQueryQueue) { 76513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int totalAgendaRangeStart = -1; 76613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int totalAgendaRangeEnd = -1; 76713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 76813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (cursorSize != 0) { 76913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Remove the query that just completed 77013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec x = mQueryQueue.poll(); 77123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (BASICLOG && !x.equals(data)) { 77223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan Log.e(TAG, "onQueryComplete - cookie != head of queue"); 77323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 77413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mEmptyCursorCount = 0; 77523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (data.queryType == QUERY_TYPE_NEWER) { 77623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mNewerRequestsProcessed++; 77723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } else if (data.queryType == QUERY_TYPE_OLDER) { 77823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mOlderRequestsProcessed++; 77923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 78013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 78113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = mAdapterInfos.getFirst().start; 78213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = mAdapterInfos.getLast().end; 78313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { // CursorSize == 0 78413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec querySpec = mQueryQueue.peek(); 78513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 78613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update Adapter Info with new start and end date range 78713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 78813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo first = mAdapterInfos.getFirst(); 78913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo last = mAdapterInfos.getLast(); 79013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 79113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (first.start - 1 <= querySpec.end && querySpec.start < first.start) { 79213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan first.start = querySpec.start; 79313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 79413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 79513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (querySpec.start <= last.end + 1 && last.end < querySpec.end) { 79613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan last.end = querySpec.end; 79713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 79813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 79913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = first.start; 80013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = last.end; 80113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 80213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 80313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 80413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 80513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 80613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update query specification with expanded search range 80713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // and maybe rerun query 80813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan switch (querySpec.queryType) { 80913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_OLDER: 81013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 81113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.start -= MAX_QUERY_DURATION; 81213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 81313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_NEWER: 81413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 81513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.end += MAX_QUERY_DURATION; 81613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 81713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_CLEAN: 81813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 81913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 82013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.start -= MAX_QUERY_DURATION / 2; 82113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.end += MAX_QUERY_DURATION / 2; 82213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 82313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 82413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 82513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (++mEmptyCursorCount > RETRIES_ON_NO_DATA) { 82613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Nothing in the cursor again. Dropping query 82713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryQueue.poll(); 82813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 82913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 83013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 83113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan updateHeaderFooter(totalAgendaRangeStart, totalAgendaRangeEnd); 83213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 83313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Fire off the next query if any 83413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Iterator<QuerySpec> it = mQueryQueue.iterator(); 83513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan while (it.hasNext()) { 83613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec queryData = it.next(); 83713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!isInRange(queryData.start, queryData.end)) { 83813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Query accepted 83913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "Query accepted. QueueSize:" + mQueryQueue.size()); 84013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan doQuery(queryData); 84113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 84213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 84313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Query rejected 84413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan it.remove(); 84513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "Query rejected. QueueSize:" + mQueryQueue.size()); 84613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 84713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 84813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 84923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (BASICLOG) { 85013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info3 : mAdapterInfos) { 85113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "> " + info3.toString()); 85213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 85313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 85413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 85513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 85613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan /* 85713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * Update the adapter info array with a the new cursor. Close out old 85813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * cursors as needed. 85913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * 86013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * @return number of rows removed from the beginning 86113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 86213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int processNewCursor(QuerySpec data, Cursor cursor) { 86313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 86413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Remove adapter info's from adapterInfos as needed 86513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = pruneAdapterInfo(data.queryType); 86613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int listPositionOffset = 0; 86713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info == null) { 86813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info = new DayAdapterInfo(mContext); 86913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 87013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) 87113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "processNewCursor listPositionOffsetA=" 87213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + -info.size); 87313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listPositionOffset = -info.size; 87413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 87513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 87613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Setup adapter info 87713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.start = data.start; 87813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.end = data.end; 87913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.cursor = cursor; 880dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan info.dayAdapter.changeCursor(info); 88113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.size = info.dayAdapter.getCount(); 88213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 88313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Insert into adapterInfos 88413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.isEmpty() 88513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan || data.end <= mAdapterInfos.getFirst().start) { 88613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addFirst(info); 88713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listPositionOffset += info.size; 88813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (BASICLOG && data.start < mAdapterInfos.getLast().end) { 88913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addLast(info); 89013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info2 : mAdapterInfos) { 89113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e("========== BUG ==", info2.toString()); 89213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 89313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 89413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addLast(info); 89513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 89613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 89713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update offsets in adapterInfos 89813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount = 0; 89913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info3 : mAdapterInfos) { 90013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info3.offset = mRowCount; 90113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount += info3.size; 90213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 90313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mLastUsedInfo = null; 90413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 90513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return listPositionOffset; 90613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 90713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 90813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 90913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 91013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static String getViewTitle(View x) { 91113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan String title = ""; 91213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (x != null) { 91313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Object yy = x.getTag(); 91413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (yy instanceof AgendaAdapter.ViewHolder) { 91513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView tv = ((AgendaAdapter.ViewHolder) yy).title; 91613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (tv != null) { 91713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan title = (String) tv.getText(); 91813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 91913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (yy != null) { 92013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView dateView = ((AgendaByDayAdapter.ViewHolder) yy).dateView; 92113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (dateView != null) { 92213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan title = (String) dateView.getText(); 92313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 92413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 92513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 92613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return title; 92713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 92813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 9299a88873f9ec97b47aaaaae47208d22b3998b8e99Erik public void onResume() { 9309a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTZUpdater.run(); 9319a88873f9ec97b47aaaaae47208d22b3998b8e99Erik } 9329a88873f9ec97b47aaaaae47208d22b3998b8e99Erik 93313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void setHideDeclinedEvents(boolean hideDeclined) { 93413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHideDeclined = hideDeclined; 93513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 936a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 937a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa public void setSelectedPosition(int positionInListView) { 938a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa mSelectedPosition = positionInListView - OFF_BY_ONE_BUG; 939a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } 94013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan} 941