AgendaWindowAdapter.java revision cf31ab351c9becad6785d4d77eefc934f30b92e3
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 19035cb8c2704c42f237bfc360a533ab6f0017b430James Kungimport android.app.Activity; 2013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.AsyncQueryHandler; 2113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.ContentResolver; 229138ce8a14924612c014da2b6e727b4117ba1a92Mason Tangimport android.content.ContentUris; 2313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.content.Context; 24a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawaimport android.content.res.Resources; 2513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.database.Cursor; 2613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.net.Uri; 27c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelsonimport android.os.Handler; 28a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract; 29a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees; 30a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars; 31a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Instances; 3213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.text.format.DateUtils; 3313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.text.format.Time; 3413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.util.Log; 3513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.LayoutInflater; 3613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.View; 3713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.view.View.OnClickListener; 389a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport android.view.ViewGroup; 39c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelsonimport android.widget.AbsListView.OnScrollListener; 4013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.widget.BaseAdapter; 4118af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport android.widget.GridLayout; 4213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport android.widget.TextView; 4313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 4418af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport com.android.calendar.CalendarController; 4518af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport com.android.calendar.CalendarController.EventType; 4618af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport com.android.calendar.CalendarController.ViewType; 4718af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport com.android.calendar.R; 4818af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport com.android.calendar.StickyHeaderListView; 4918af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelsonimport com.android.calendar.Utils; 5018af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson 5113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Formatter; 5213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Iterator; 5313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.LinkedList; 5413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Locale; 5513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.concurrent.ConcurrentLinkedQueue; 5613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan/* 5813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanBugs Bugs Bugs: 5913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- At rotation and launch time, the initial position is not set properly. This code is calling 6013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listview.setSelection() in 2 rapid secessions but it dropped or didn't process the first one. 6113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Scroll using trackball isn't repositioning properly after a new adapter is added. 6223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan- Track ball clicks at the header/footer doesn't work. 6313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Potential ping pong effect if the prefetch window is big and data is limited 6413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan- Add index in calendar provider 6513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanToDo ToDo ToDo: 6713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanGet design of header and footer from designer 6813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 6913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanMake scrolling smoother. 7013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanTest for correctness 7113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanLoading speed 7213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael ChanCheck for leaks and excessive allocations 7313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 7413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelsonpublic class AgendaWindowAdapter extends BaseAdapter 76c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson implements StickyHeaderListView.HeaderIndexer, StickyHeaderListView.HeaderHeightListener{ 7713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan static final boolean BASICLOG = false; 7992c6688283442c800b4de0ca76c0e05a089f84c3RoboErik static final boolean DEBUGLOG = false; 80a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private static final String TAG = "AgendaWindowAdapter"; 8113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 829138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private static final String AGENDA_SORT_ORDER = 83a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik CalendarContract.Instances.START_DAY + " ASC, " + 84a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik CalendarContract.Instances.BEGIN + " ASC, " + 85a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik CalendarContract.Events.TITLE + " ASC"; 869138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 87ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public static final int INDEX_INSTANCE_ID = 0; 8813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_TITLE = 1; 8913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_EVENT_LOCATION = 2; 9013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_ALL_DAY = 3; 9113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_HAS_ALARM = 4; 9213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_COLOR = 5; 9313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_RRULE = 6; 9413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_BEGIN = 7; 9513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_END = 8; 9613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_EVENT_ID = 9; 9713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_START_DAY = 10; 9813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_END_DAY = 11; 9913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public static final int INDEX_SELF_ATTENDEE_STATUS = 12; 100056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson public static final int INDEX_ORGANIZER = 13; 101056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson public static final int INDEX_OWNER_ACCOUNT = 14; 102056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson public static final int INDEX_CAN_ORGANIZER_RESPOND= 15; 1031121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik public static final int INDEX_TIME_ZONE = 16; 10413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 10513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final String[] PROJECTION = new String[] { 10613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances._ID, // 0 10713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.TITLE, // 1 10813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.EVENT_LOCATION, // 2 10913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.ALL_DAY, // 3 11013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.HAS_ALARM, // 4 111693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan Instances.DISPLAY_COLOR, // 5 If SDK < 16, set to Instances.CALENDAR_COLOR. 11213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.RRULE, // 6 11313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.BEGIN, // 7 11413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.END, // 8 11513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.EVENT_ID, // 9 11613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.START_DAY, // 10 Julian start day 11713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.END_DAY, // 11 Julian end day 11813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Instances.SELF_ATTENDEE_STATUS, // 12 119056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson Instances.ORGANIZER, // 13 120056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson Instances.OWNER_ACCOUNT, // 14 121056079920bc9d141241648662ad4ebdea91b1fd4Isaac Katzenelson Instances.CAN_ORGANIZER_RESPOND, // 15 1221121e409c5f504e8df75982475d8cc607d5f0dfaRoboErik Instances.EVENT_TIMEZONE, // 16 12313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan }; 12413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 125693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan static { 126fac2d1594f7ecae8e50dc7790ce67de0c9b70d22Sara Ting if (!Utils.isJellybeanOrLater()) { 127693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan PROJECTION[INDEX_COLOR] = Instances.CALENDAR_COLOR; 128693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 129693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan } 130693ca60d79650af15ab226f7ce6958f61fb7de39Michael Chan 13113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Listview may have a bug where the index/position is not consistent when there's a header. 132a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa // position == positionInListView - OFF_BY_ONE_BUG 13313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // TODO Need to look into this. 13413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int OFF_BY_ONE_BUG = 1; 13513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MAX_NUM_OF_ADAPTERS = 5; 13613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int IDEAL_NUM_OF_EVENTS = 50; 13713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MIN_QUERY_DURATION = 7; // days 13813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int MAX_QUERY_DURATION = 60; // days 13913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int PREFETCH_BOUNDARY = 1; 14013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1419138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Times to auto-expand/retry query after getting no data */ 1429138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private static final int RETRIES_ON_NO_DATA = 1; 14313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 14418af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final Context mContext; 14518af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final Resources mResources; 14618af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final QueryHandler mQueryHandler; 14718af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final AgendaListView mAgendaListView; 14813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1499138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The sum of the rows in all the adapters */ 1509138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private int mRowCount; 15113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1529138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The number of times we have queried and gotten no results back */ 15313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mEmptyCursorCount; 15413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1559138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Cached value of the last used adapter */ 1569138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private DayAdapterInfo mLastUsedInfo; 15713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 158a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final LinkedList<DayAdapterInfo> mAdapterInfos = 159a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa new LinkedList<DayAdapterInfo>(); 160a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa private final ConcurrentLinkedQueue<QuerySpec> mQueryQueue = 161a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa new ConcurrentLinkedQueue<QuerySpec>(); 16218af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final TextView mHeaderView; 16318af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final TextView mFooterView; 16413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mDoneSettingUpHeaderFooter = false; 16513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 166980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson private final boolean mIsTabletConfig; 167980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson 168c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson boolean mCleanQueryInitiated = false; 169c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson private int mStickyHeaderSize = 44; // Initial size big enough for it to work 170c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 1719138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 17213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * When the user scrolled to the top, a query will be made for older events 17313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * and this will be incremented. Don't make more requests if 17413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * mOlderRequests > mOlderRequestsProcessed. 17513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 17613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mOlderRequests; 17713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1789138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Number of "older" query that has been processed. */ 17913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mOlderRequestsProcessed; 18013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1819138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** 18213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * When the user scrolled to the bottom, a query will be made for newer 18313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * events and this will be incremented. Don't make more requests if 18413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * mNewerRequests > mNewerRequestsProcessed. 18513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 18613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mNewerRequests; 18713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 1889138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** Number of "newer" query that has been processed. */ 18913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int mNewerRequestsProcessed; 19013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 19123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread. 19218af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final Formatter mFormatter; 19318af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final StringBuilder mStringBuilder; 1949a88873f9ec97b47aaaaae47208d22b3998b8e99Erik private String mTimeZone; 1959a88873f9ec97b47aaaaae47208d22b3998b8e99Erik 19696a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson // defines if to pop-up the current event when the agenda is first shown 19718af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final boolean mShowEventOnStart; 19896a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson 19918af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final Runnable mTZUpdater = new Runnable() { 2009a88873f9ec97b47aaaaae47208d22b3998b8e99Erik @Override 2019a88873f9ec97b47aaaaae47208d22b3998b8e99Erik public void run() { 2029a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTimeZone = Utils.getTimeZone(mContext, this); 2039a88873f9ec97b47aaaaae47208d22b3998b8e99Erik notifyDataSetChanged(); 2049a88873f9ec97b47aaaaae47208d22b3998b8e99Erik } 2059a88873f9ec97b47aaaaae47208d22b3998b8e99Erik }; 20613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 2074b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson private final Handler mDataChangedHandler = new Handler(); 2084b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson private final Runnable mDataChangedRunnable = new Runnable() { 2094b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson @Override 2104b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson public void run() { 2114b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson notifyDataSetChanged(); 2124b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson } 2134b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson }; 2144b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson 21513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mShuttingDown; 21613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean mHideDeclined; 21713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 218c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Used to stop a fling motion if the ListView is set to a specific position 219c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int mListViewScrollState = OnScrollListener.SCROLL_STATE_IDLE; 220c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 2219138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang /** The current search query, or null if none */ 2229138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private String mSearchQuery; 2239138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 224ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan private long mSelectedInstanceId = -1; 225a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 226163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan private final int mSelectedItemBackgroundColor; 227163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan private final int mSelectedItemTextColor; 22818af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson private final float mItemRightMargin; 229a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 23013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Types of Query 23113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_OLDER = 0; // Query for older events 23213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_NEWER = 1; // Query for newer events 23313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static final int QUERY_TYPE_CLEAN = 2; // Delete everything and query around a date 23413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 23513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private static class QuerySpec { 23613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long queryStartMillis; 23713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time goToTime; 23813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start; 23913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end; 2409138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang String searchQuery; 24113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryType; 242c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson long id; 24313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 24413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public QuerySpec(int queryType) { 24513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan this.queryType = queryType; 246c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson id = -1; 24713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 24823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan 24923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan @Override 25023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan public int hashCode() { 25123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan final int prime = 31; 25223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan int result = 1; 25323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + end; 25423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + (int) (queryStartMillis ^ (queryStartMillis >>> 32)); 25523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + queryType; 25623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + start; 2572f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan if (searchQuery != null) { 2582f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan result = prime * result + searchQuery.hashCode(); 2592f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan } 26023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime != null) { 26123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan long goToTimeMillis = goToTime.toMillis(false); 26223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan result = prime * result + (int) (goToTimeMillis ^ (goToTimeMillis >>> 32)); 26323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 264c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson result = prime * result + (int)id; 26523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return result; 26623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 26723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan 26823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan @Override 26923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan public boolean equals(Object obj) { 27023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (this == obj) return true; 27123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (obj == null) return false; 27223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (getClass() != obj.getClass()) return false; 27323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan QuerySpec other = (QuerySpec) obj; 27423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (end != other.end || queryStartMillis != other.queryStartMillis 2759138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang || queryType != other.queryType || start != other.start 276c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson || Utils.equals(searchQuery, other.searchQuery) || id != other.id) { 27723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 27823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 2799138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 28023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime != null) { 28123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (goToTime.toMillis(false) != other.goToTime.toMillis(false)) { 28223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 28323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 28423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } else { 28523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (other.goToTime != null) { 28623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return false; 28723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 28823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 28923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan return true; 29023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 29113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 29213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 293cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung static class AgendaItem { 29413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long begin; 29513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long end; 29613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long id; 297ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan int startDay; 2988b1119b1b58381c7fc550974f53cf93bd95dffa8Michael Chan boolean allDay; 29913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 30013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 301dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan static class DayAdapterInfo { 30213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Cursor cursor; 30313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan AgendaByDayAdapter dayAdapter; 30413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start; // start day of the cursor's coverage 30513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end; // end day of the cursor's coverage 30613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int offset; // offset in position in the list view 30713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int size; // dayAdapter.getCount() 30813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 30913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public DayAdapterInfo(Context context) { 31013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan dayAdapter = new AgendaByDayAdapter(context); 31113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 31213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 31313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 31413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public String toString() { 3159a88873f9ec97b47aaaaae47208d22b3998b8e99Erik // Static class, so the time in this toString will not reflect the 3169a88873f9ec97b47aaaaae47208d22b3998b8e99Erik // home tz settings. This should only affect debugging. 31713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time time = new Time(); 31813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan StringBuilder sb = new StringBuilder(); 31913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(start); 32013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.normalize(false); 32113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append("Start:").append(time.toString()); 32213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(end); 32313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.normalize(false); 32413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" End:").append(time.toString()); 32513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" Offset:").append(offset); 32613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan sb.append(" Size:").append(size); 32713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return sb.toString(); 32813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 32913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 33013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 3319138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang public AgendaWindowAdapter(Context context, 33296a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson AgendaListView agendaListView, boolean showEventOnStart) { 3339138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mContext = context; 334a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa mResources = context.getResources(); 335163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan mSelectedItemBackgroundColor = mResources 336163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan .getColor(R.color.agenda_selected_background_color); 337163192b54fdf9fc15ca6e4bf04402c73c904d0d7Michael Chan mSelectedItemTextColor = mResources.getColor(R.color.agenda_selected_text_color); 33818af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson mItemRightMargin = mResources.getDimension(R.dimen.agenda_item_right_margin); 339980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson mIsTabletConfig = Utils.getConfigBool(mContext, R.bool.tablet_config); 340a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 3419a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTimeZone = Utils.getTimeZone(context, mTZUpdater); 34213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView = agendaListView; 3439138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mQueryHandler = new QueryHandler(context.getContentResolver()); 34413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 34513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder = new StringBuilder(50); 34613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 34713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 34896a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson mShowEventOnStart = showEventOnStart; 34996a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson 350c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Implies there is no sticky header 351c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (!mShowEventOnStart) { 352c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mStickyHeaderSize = 0; 353c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 3549138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mSearchQuery = null; 3559138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 3569138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang LayoutInflater inflater = (LayoutInflater) context 35713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 35813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView = (TextView)inflater.inflate(R.layout.agenda_header_footer, null); 35913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView = (TextView)inflater.inflate(R.layout.agenda_header_footer, null); 36013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setText(R.string.loading); 36113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.addHeaderView(mHeaderView); 36213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 36413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in Adapter 36513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 36613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getViewTypeCount() { 36713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return AgendaByDayAdapter.TYPE_LAST; 36813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 36913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 37013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in BaseAdapter 37113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 37213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public boolean areAllItemsEnabled() { 37313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 37413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 37513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 37613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in Adapter 37713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 37813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getItemViewType(int position) { 37913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 38013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 38113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.getItemViewType(position - info.offset); 38213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 38313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 38413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 38513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 38613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 38713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Method in BaseAdapter 38813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 38913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public boolean isEnabled(int position) { 39013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 39113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 39213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.isEnabled(position - info.offset); 39313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 39413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 39513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 39613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 39713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 39813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 39913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public int getCount() { 40013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mRowCount; 40113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 40213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 40313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 40413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public Object getItem(int position) { 40513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 40613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 40713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info.dayAdapter.getItem(position - info.offset); 40813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 40913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 41013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 41113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 41213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 413c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan // Method in BaseAdapter 414c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan @Override 415c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan public boolean hasStableIds() { 416c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan return true; 417c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 418c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan 41913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 420c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson @Override 42113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public long getItemId(int position) { 42213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 42313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 424c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int curPos = info.dayAdapter.getCursorPosition(position - info.offset); 425c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (curPos == Integer.MIN_VALUE) { 426c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return -1; 427c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 428c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Regular event 429c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (curPos >= 0) { 430c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson info.cursor.moveToPosition(curPos); 431c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return info.cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID) << 20 + 432c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson info.cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN); 433c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 434c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Day Header 435c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return info.dayAdapter.findJulianDayFromPosition(position); 436c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 43713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 43813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -1; 43913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 44013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 44113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 44213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Abstract Method in BaseAdapter 44313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public View getView(int position, View convertView, ViewGroup parent) { 44413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (position >= (mRowCount - PREFETCH_BOUNDARY) 44513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && mNewerRequests <= mNewerRequestsProcessed) { 44613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "queryForNewerEvents: "); 44713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mNewerRequests++; 44813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_NEWER)); 44913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 45013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 45113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (position < PREFETCH_BOUNDARY 45213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && mOlderRequests <= mOlderRequestsProcessed) { 45313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "queryForOlderEvents: "); 45413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mOlderRequests++; 45513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_OLDER)); 45613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 45713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 458a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa final View v; 45913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByPosition(position); 46013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 4612d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson int offset = position - info.offset; 4622d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson v = info.dayAdapter.getView(offset, convertView, 46313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan parent); 4642d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson 4652d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // Turn on the past/present separator if the view is a day header 4662d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // and it is the first day with events after yesterday. 4672d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info.dayAdapter.isDayHeaderView(offset)) { 4682d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson View simpleDivider = v.findViewById(R.id.top_divider_simple); 4692d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson View pastPresentDivider = v.findViewById(R.id.top_divider_past_present); 4702d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info.dayAdapter.isFirstDayAfterYesterday(offset)) { 4712d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (simpleDivider != null && pastPresentDivider != null) { 4722d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson simpleDivider.setVisibility(View.GONE); 4732d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson pastPresentDivider.setVisibility(View.VISIBLE); 4742d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 4752d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } else if (simpleDivider != null && pastPresentDivider != null) { 4762d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson simpleDivider.setVisibility(View.VISIBLE); 4772d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson pastPresentDivider.setVisibility(View.GONE); 4782d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 4792d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 48013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 4812d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // TODO 48213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "BUG: getAdapterInfoByPosition returned null!!! " + position); 48313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView tv = new TextView(mContext); 48413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan tv.setText("Bug! " + position); 48513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan v = tv; 48613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 48713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 48833de4c48430262a0509ffe50fc376b87520cb938RoboErik // If this is not a tablet config don't do selection highlighting 48933de4c48430262a0509ffe50fc376b87520cb938RoboErik if (!mIsTabletConfig) { 49033de4c48430262a0509ffe50fc376b87520cb938RoboErik return v; 49133de4c48430262a0509ffe50fc376b87520cb938RoboErik } 492ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan // Show selected marker if this is item is selected 493ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan boolean selected = false; 494ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Object yy = v.getTag(); 495ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (yy instanceof AgendaAdapter.ViewHolder) { 496ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan AgendaAdapter.ViewHolder vh = (AgendaAdapter.ViewHolder) yy; 497ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan selected = mSelectedInstanceId == vh.instanceId; 49896a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson vh.selectedMarker.setVisibility((selected && mShowEventOnStart) ? 49996a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson View.VISIBLE : View.GONE); 50018af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson if (mShowEventOnStart) { 50118af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson GridLayout.LayoutParams lp = 50218af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson (GridLayout.LayoutParams)vh.textContainer.getLayoutParams(); 50318af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson if (selected) { 50418af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson mSelectedVH = vh; 50518af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson v.setBackgroundColor(mSelectedItemBackgroundColor); 50618af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson vh.title.setTextColor(mSelectedItemTextColor); 50718af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson vh.when.setTextColor(mSelectedItemTextColor); 50818af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson vh.where.setTextColor(mSelectedItemTextColor); 50918af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson lp.setMargins(0, 0, 0, 0); 51018af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson vh.textContainer.setLayoutParams(lp); 51118af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson } else { 51218af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson lp.setMargins(0, 0, (int)mItemRightMargin, 0); 51318af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson vh.textContainer.setLayoutParams(lp); 51418af2447a421c514ce6da1723abea2869e349fb3Isaac Katzenelson } 515ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 516a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } 517a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 51813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) { 51913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "getView " + position + " = " + getViewTitle(v)); 52013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 52113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return v; 52213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 52313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5249fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik private AgendaAdapter.ViewHolder mSelectedVH = null; 5259fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik 526c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson private int findEventPositionNearestTime(Time time, long id) { 52713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = getAdapterInfoByTime(time); 528499a660463ef870168cf0d63e668893a91d96b3aMichael Chan int pos = -1; 52913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 530499a660463ef870168cf0d63e668893a91d96b3aMichael Chan pos = info.offset + info.dayAdapter.findEventPositionNearestTime(time, id); 53113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 532499a660463ef870168cf0d63e668893a91d96b3aMichael Chan if (DEBUGLOG) Log.e(TAG, "findEventPositionNearestTime " + time + " id:" + id + " =" + pos); 533499a660463ef870168cf0d63e668893a91d96b3aMichael Chan return pos; 53413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 53513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5369a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson protected DayAdapterInfo getAdapterInfoByPosition(int position) { 53713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 53813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mLastUsedInfo != null && mLastUsedInfo.offset <= position 53913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && position < (mLastUsedInfo.offset + mLastUsedInfo.size)) { 54013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mLastUsedInfo; 54113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 54213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info : mAdapterInfos) { 54313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info.offset <= position 54413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan && position < (info.offset + info.size)) { 54513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mLastUsedInfo = info; 54613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info; 54713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 54813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 54913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 55013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 55113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 55213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 55313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo getAdapterInfoByTime(Time time) { 55413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "getAdapterInfoByTime " + time.toString()); 55513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 55613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time tmpTime = new Time(time); 55713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long timeInMillis = tmpTime.normalize(true); 55813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int day = Time.getJulianDay(timeInMillis, tmpTime.gmtoff); 55913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 56013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info : mAdapterInfos) { 5618e597ca4f8eb3f9a3730d49aaeb431a0231af7d1Michael Chan if (info.start <= day && day <= info.end) { 56213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return info; 56313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 56413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 56513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 56613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 56713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 56813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 569cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung public AgendaItem getAgendaItemByPosition(final int positionInListView) { 570cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung return getAgendaItemByPosition(positionInListView, true); 57196d6163c524b338307b01d25916ccffd495e2f29Michael Chan } 57296d6163c524b338307b01d25916ccffd495e2f29Michael Chan 57396d6163c524b338307b01d25916ccffd495e2f29Michael Chan /** 57496d6163c524b338307b01d25916ccffd495e2f29Michael Chan * Return the event info for a given position in the adapter 57596d6163c524b338307b01d25916ccffd495e2f29Michael Chan * @param positionInListView 57696d6163c524b338307b01d25916ccffd495e2f29Michael Chan * @param returnEventStartDay If true, return actual event startday. Otherwise 57796d6163c524b338307b01d25916ccffd495e2f29Michael Chan * return agenda date-header date as the startDay. 57896d6163c524b338307b01d25916ccffd495e2f29Michael Chan * The two will differ for multi-day events after the first day. 57996d6163c524b338307b01d25916ccffd495e2f29Michael Chan * @return 58096d6163c524b338307b01d25916ccffd495e2f29Michael Chan */ 581cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung public AgendaItem getAgendaItemByPosition(final int positionInListView, 58296d6163c524b338307b01d25916ccffd495e2f29Michael Chan boolean returnEventStartDay) { 583a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (DEBUGLOG) Log.e(TAG, "getEventByPosition " + positionInListView); 5849fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik if (positionInListView < 0) { 5859fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik return null; 5869fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik } 58713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 588a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa final int positionInAdapter = positionInListView - OFF_BY_ONE_BUG; 589a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa DayAdapterInfo info = getAdapterInfoByPosition(positionInAdapter); 59013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info == null) { 59113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 59213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 59313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 594a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa int cursorPosition = info.dayAdapter.getCursorPosition(positionInAdapter - info.offset); 595a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition == Integer.MIN_VALUE) { 59613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 59713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 59813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 59913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan boolean isDayHeader = false; 600a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition < 0) { 601a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa cursorPosition = -cursorPosition; 60213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan isDayHeader = true; 60313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 60413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 605a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa if (cursorPosition < info.cursor.getCount()) { 606cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung AgendaItem item = buildAgendaItemFromCursor(info.cursor, cursorPosition, isDayHeader); 60796d6163c524b338307b01d25916ccffd495e2f29Michael Chan if (!returnEventStartDay && !isDayHeader) { 608cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung item.startDay = info.dayAdapter.findJulianDayFromPosition(positionInAdapter - 609812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson info.offset); 61096d6163c524b338307b01d25916ccffd495e2f29Michael Chan } 611cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung return item; 61213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 61313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return null; 61413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 61513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 616cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung private AgendaItem buildAgendaItemFromCursor(final Cursor cursor, int cursorPosition, 617c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson boolean isDayHeader) { 618c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (cursorPosition == -1) { 619c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson cursor.moveToFirst(); 620c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } else { 621c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson cursor.moveToPosition(cursorPosition); 622c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 623cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung AgendaItem agendaItem = new AgendaItem(); 624cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung agendaItem.begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN); 625cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung agendaItem.end = cursor.getLong(AgendaWindowAdapter.INDEX_END); 626cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung agendaItem.startDay = cursor.getInt(AgendaWindowAdapter.INDEX_START_DAY); 627cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung agendaItem.allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0; 62819dc8872ca94c44c8094886c17f9b62160ac76cbJames Kung 62919dc8872ca94c44c8094886c17f9b62160ac76cbJames Kung if (isDayHeader) { // Trim to midnight. 630ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Time time = new Time(mTimeZone); 631cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung time.set(agendaItem.begin); 632ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.hour = 0; 633ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.minute = 0; 634ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan time.second = 0; 635cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung agendaItem.begin = time.toMillis(false); 63619dc8872ca94c44c8094886c17f9b62160ac76cbJames Kung } else { 637cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung agendaItem.id = cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID); 638ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 63919dc8872ca94c44c8094886c17f9b62160ac76cbJames Kung 640cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung return agendaItem; 641ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 642ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 643c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson public void refresh(Time goToTime, long id, String searchQuery, boolean forced, 644c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson boolean refreshEventInfo) { 6454003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang if (searchQuery != null) { 6464003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang mSearchQuery = searchQuery; 6474003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang } 6484003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang 649c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan if (DEBUGLOG) { 650c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson Log.e(TAG, this + ": refresh " + goToTime.toString() + " id " + id 651c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson + ((searchQuery != null) ? searchQuery : "") 652c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson + (forced ? " forced" : " not forced") 653c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson + (refreshEventInfo ? " refresh event info" : "")); 654c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan } 655b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson 65623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan int startDay = Time.getJulianDay(goToTime.toMillis(false), goToTime.gmtoff); 65713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 65813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!forced && isInRange(startDay, startDay)) { 659ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson // No need to re-query 660cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung if (!mAgendaListView.isAgendaItemVisible(goToTime, id)) { 661c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int gotoPosition = findEventPositionNearestTime(goToTime, id); 6628e597ca4f8eb3f9a3730d49aaeb431a0231af7d1Michael Chan if (gotoPosition > 0) { 6635731a2a7dab25becafbb4e134b558ba4d0bad2eeIsaac Katzenelson mAgendaListView.setSelectionFromTop(gotoPosition + 6645731a2a7dab25becafbb4e134b558ba4d0bad2eeIsaac Katzenelson OFF_BY_ONE_BUG, mStickyHeaderSize); 665c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (mListViewScrollState == OnScrollListener.SCROLL_STATE_FLING) { 666c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mAgendaListView.smoothScrollBy(0, 0); 667c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 668c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (refreshEventInfo) { 669c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson long newInstanceId = findInstanceIdFromPosition(gotoPosition); 670c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (newInstanceId != getSelectedInstanceId()) { 671c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson setSelectedInstanceId(newInstanceId); 6724b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson mDataChangedHandler.post(mDataChangedRunnable); 673c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson Cursor tempCursor = getCursorByPosition(gotoPosition); 674c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (tempCursor != null) { 675c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int tempCursorPosition = getCursorPositionByPosition(gotoPosition); 676cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung AgendaItem item = 677cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung buildAgendaItemFromCursor(tempCursor, tempCursorPosition, 678c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson false); 67919dc8872ca94c44c8094886c17f9b62160ac76cbJames Kung mSelectedVH = new AgendaAdapter.ViewHolder(); 680cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung mSelectedVH.allDay = item.allDay; 6816bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson CalendarController.getInstance(mContext) 6826bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson .sendEventRelatedEventWithExtra(this, EventType.VIEW_EVENT, 683cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung item.id, item.begin, item.end, 0, 6846bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson 0, CalendarController.EventInfo.buildViewExtraLong( 6856bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson Attendees.ATTENDEE_STATUS_NONE, 686cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung item.allDay), goToTime.toMillis(false)); 687c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 688c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 689c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 6908e597ca4f8eb3f9a3730d49aaeb431a0231af7d1Michael Chan } 691c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 692e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik Time actualTime = new Time(mTimeZone); 693499a660463ef870168cf0d63e668893a91d96b3aMichael Chan actualTime.set(goToTime); 694e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik CalendarController.getInstance(mContext).sendEvent(this, EventType.UPDATE_TITLE, 695e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik actualTime, actualTime, -1, ViewType.CURRENT); 696ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson } 69713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return; 69813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 69913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 700c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // If AllInOneActivity is sending a second GOTO event(in OnResume), ignore it. 701c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (!mCleanQueryInitiated || searchQuery != null) { 702c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Query for a total of MIN_QUERY_DURATION days 703c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int endDay = startDay + MIN_QUERY_DURATION; 70413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 705c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mSelectedInstanceId = -1; 706c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mCleanQueryInitiated = true; 707ab557bf10630e7d23c20a000bb06e12580852c75Michael Chan queueQuery(startDay, endDay, goToTime, searchQuery, QUERY_TYPE_CLEAN, id); 7084fe5d45eb8cbaac85764492e0a0b6c025771880aIsaac Katzenelson 709c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Pre-fetch more data to overcome a race condition in AgendaListView.shiftSelection 710c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Queuing more data with the goToTime set to the selected time skips the call to 711c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // shiftSelection on refresh. 712c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mOlderRequests++; 713c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson queueQuery(0, 0, goToTime, searchQuery, QUERY_TYPE_OLDER, id); 714c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mNewerRequests++; 715c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson queueQuery(0, 0, goToTime, searchQuery, QUERY_TYPE_NEWER, id); 716c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 71713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 71813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 71913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void close() { 72013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mShuttingDown = true; 72113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan pruneAdapterInfo(QUERY_TYPE_CLEAN); 72213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mQueryHandler != null) { 72313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryHandler.cancelOperation(0); 72413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 72513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 72613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 72713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private DayAdapterInfo pruneAdapterInfo(int queryType) { 72813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 72913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo recycleMe = null; 73013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 73113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.size() >= MAX_NUM_OF_ADAPTERS) { 73213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (queryType == QUERY_TYPE_NEWER) { 73313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = mAdapterInfos.removeFirst(); 73413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (queryType == QUERY_TYPE_OLDER) { 73513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = mAdapterInfos.removeLast(); 73613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Keep the size only if the oldest items are removed. 73713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.size = 0; 73813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 73913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe != null) { 74013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe.cursor != null) { 74113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.cursor.close(); 74213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return recycleMe; 74413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 74613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 74713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mRowCount == 0 || queryType == QUERY_TYPE_CLEAN) { 74813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount = 0; 74913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int deletedRows = 0; 75013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info; 75113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan do { 75213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info = mAdapterInfos.poll(); 75313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info != null) { 754bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // TODO the following causes ANR's. Do this in a thread. 75513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.cursor.close(); 75613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan deletedRows += info.size; 75713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe = info; 75813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 75913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } while (info != null); 76013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 76113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (recycleMe != null) { 76213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.cursor = null; 76313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan recycleMe.size = deletedRows; 76413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 76513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 76613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 76713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return recycleMe; 76813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 76913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 77013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 77113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private String buildQuerySelection() { 77213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Respect the preference to show/hide declined events 77313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 77413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mHideDeclined) { 775950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden return Calendars.VISIBLE + "=1 AND " 77613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + Instances.SELF_ATTENDEE_STATUS + "!=" 77713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + Attendees.ATTENDEE_STATUS_DECLINED; 77813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 779950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden return Calendars.VISIBLE + "=1"; 78013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 78113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 78213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 7839138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private Uri buildQueryUri(int start, int end, String searchQuery) { 7849138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri rootUri = searchQuery == null ? 7859138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Instances.CONTENT_BY_DAY_URI : 7869138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Instances.CONTENT_SEARCH_BY_DAY_URI; 7879138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri.Builder builder = rootUri.buildUpon(); 7889138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang ContentUris.appendId(builder, start); 7899138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang ContentUris.appendId(builder, end); 7909138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang if (searchQuery != null) { 7919138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang builder.appendPath(searchQuery); 7929138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang } 7939138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang return builder.build(); 79413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 79513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 79613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean isInRange(int start, int end) { 79713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 79813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.isEmpty()) { 79913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return false; 80013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 80113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return mAdapterInfos.getFirst().start <= start && end <= mAdapterInfos.getLast().end; 80213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 80313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 80413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 80513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int calculateQueryDuration(int start, int end) { 80613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryDuration = MAX_QUERY_DURATION; 80713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mRowCount != 0) { 80813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = IDEAL_NUM_OF_EVENTS * (end - start + 1) / mRowCount; 80913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 81013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 81113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (queryDuration > MAX_QUERY_DURATION) { 81213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = MAX_QUERY_DURATION; 81313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (queryDuration < MIN_QUERY_DURATION) { 81413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryDuration = MIN_QUERY_DURATION; 81513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 81613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 81713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queryDuration; 81813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 81913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 8209138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang private boolean queueQuery(int start, int end, Time goToTime, 821c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson String searchQuery, int queryType, long id) { 82213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec queryData = new QuerySpec(queryType); 82313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.goToTime = goToTime; 82413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = start; 82513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = end; 8269138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.searchQuery = searchQuery; 827c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson queryData.id = id; 82813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queueQuery(queryData); 82913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 83013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 83113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private boolean queueQuery(QuerySpec queryData) { 8329138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.searchQuery = mSearchQuery; 83313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Boolean queuedQuery; 83413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mQueryQueue) { 83513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queuedQuery = false; 83613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Boolean doQueryNow = mQueryQueue.isEmpty(); 83723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mQueryQueue.add(queryData); 83823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan queuedQuery = true; 83923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (doQueryNow) { 84023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan doQuery(queryData); 84113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 84213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 84313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return queuedQuery; 84413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 84513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 84613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private void doQuery(QuerySpec queryData) { 84713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 84813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int start = mAdapterInfos.getFirst().start; 84913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int end = mAdapterInfos.getLast().end; 85013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int queryDuration = calculateQueryDuration(start, end); 85113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan switch(queryData.queryType) { 85213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_OLDER: 85313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = start - 1; 85413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = queryData.end - queryDuration; 85513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 85613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_NEWER: 85713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.start = end + 1; 85813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queryData.end = queryData.start + queryDuration; 85913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 86013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 8612f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan 8622f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan // By "compacting" cursors, this fixes the disco/ping-pong problem 8632f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan // b/5311977 8642f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan if (mRowCount < 20 && queryData.queryType != QUERY_TYPE_CLEAN) { 8652f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan if (DEBUGLOG) { 8662f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan Log.e(TAG, "Compacting cursor: mRowCount=" + mRowCount 8672f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan + " totalStart:" + start 8682f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan + " totalEnd:" + end 8692f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan + " query.start:" + queryData.start 8702f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan + " query.end:" + queryData.end); 8712f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan } 8722f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan 8732f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan queryData.queryType = QUERY_TYPE_CLEAN; 8742f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan 8752f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan if (queryData.start > start) { 8762f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan queryData.start = start; 8772f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan } 8782f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan if (queryData.end < end) { 8792f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan queryData.end = end; 8802f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan } 8812f6a549faa941dd5996a50e885307ab8d6f88f2dMichael Chan } 88213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 88313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 88413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) { 8859a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 88613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(queryData.start); 8879a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time2 = new Time(mTimeZone); 88813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time2.setJulianDay(queryData.end); 88913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.v(TAG, "startQuery: " + time.toString() + " to " 89013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + time2.toString() + " then go to " + queryData.goToTime); 89113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 89213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 89313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryHandler.cancelOperation(0); 89413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) queryData.queryStartMillis = System.nanoTime(); 8959138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang 8969138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang Uri queryUri = buildQueryUri( 8979138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang queryData.start, queryData.end, queryData.searchQuery); 8989138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang mQueryHandler.startQuery(0, queryData, queryUri, 8999138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang PROJECTION, buildQuerySelection(), null, 9009138ce8a14924612c014da2b6e727b4117ba1a92Mason Tang AGENDA_SORT_ORDER); 90113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 90213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 90313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private String formatDateString(int julianDay) { 9049a88873f9ec97b47aaaaae47208d22b3998b8e99Erik Time time = new Time(mTimeZone); 90513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan time.setJulianDay(julianDay); 90613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long millis = time.toMillis(false); 90713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder.setLength(0); 90813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return DateUtils.formatDateRange(mContext, mFormatter, millis, millis, 90913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE 9109a88873f9ec97b47aaaaae47208d22b3998b8e99Erik | DateUtils.FORMAT_ABBREV_MONTH, mTimeZone).toString(); 91113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 91213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 91313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private void updateHeaderFooter(final int start, final int end) { 91413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setText(mContext.getString(R.string.show_older_events, 91513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan formatDateString(start))); 91613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView.setText(mContext.getString(R.string.show_newer_events, 91713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan formatDateString(end))); 91813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 91913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 92013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private class QueryHandler extends AsyncQueryHandler { 92113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 92213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public QueryHandler(ContentResolver cr) { 92313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan super(cr); 92413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 92513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 92613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan @Override 92713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 92813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec data = (QuerySpec)cookie; 929035cb8c2704c42f237bfc360a533ab6f0017b430James Kung 930035cb8c2704c42f237bfc360a533ab6f0017b430James Kung if (cursor == null) { 931035cb8c2704c42f237bfc360a533ab6f0017b430James Kung if (mAgendaListView != null && mAgendaListView.getContext() instanceof Activity) { 932035cb8c2704c42f237bfc360a533ab6f0017b430James Kung ((Activity) mAgendaListView.getContext()).finish(); 933035cb8c2704c42f237bfc360a533ab6f0017b430James Kung } 934035cb8c2704c42f237bfc360a533ab6f0017b430James Kung return; 935035cb8c2704c42f237bfc360a533ab6f0017b430James Kung } 936035cb8c2704c42f237bfc360a533ab6f0017b430James Kung 93713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (BASICLOG) { 93813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan long queryEndMillis = System.nanoTime(); 93913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "Query time(ms): " 94013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + (queryEndMillis - data.queryStartMillis) / 1000000 94113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + " Count: " + cursor.getCount()); 94213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 94313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 944c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (data.queryType == QUERY_TYPE_CLEAN) { 945c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mCleanQueryInitiated = false; 946c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 947c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 94813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mShuttingDown) { 94913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan cursor.close(); 95013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return; 95113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 95213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 95313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Notify Listview of changes and update position 95413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int cursorSize = cursor.getCount(); 9557278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik if (cursorSize > 0 || mAdapterInfos.isEmpty() || data.queryType == QUERY_TYPE_CLEAN) { 95613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan final int listPositionOffset = processNewCursor(data, cursor); 957c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int newPosition = -1; 95813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (data.goToTime == null) { // Typical Scrolling type query 95913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan notifyDataSetChanged(); 96013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (listPositionOffset != 0) { 96113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.shiftSelection(listPositionOffset); 96213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 96313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { // refresh() called. Go to the designated position 96413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan final Time goToTime = data.goToTime; 96513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan notifyDataSetChanged(); 966c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson newPosition = findEventPositionNearestTime(goToTime, data.id); 96713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (newPosition >= 0) { 968c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (mListViewScrollState == OnScrollListener.SCROLL_STATE_FLING) { 969c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mAgendaListView.smoothScrollBy(0, 0); 970c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 971b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson mAgendaListView.setSelectionFromTop(newPosition + OFF_BY_ONE_BUG, 972b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson mStickyHeaderSize); 973e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik Time actualTime = new Time(mTimeZone); 9744fe5d45eb8cbaac85764492e0a0b6c025771880aIsaac Katzenelson actualTime.set(goToTime); 975e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik CalendarController.getInstance(mContext).sendEvent(this, 976e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik EventType.UPDATE_TITLE, actualTime, actualTime, -1, 977e3f129ad0a39b47ef0f08f18734aed9b99126279RoboErik ViewType.CURRENT); 97813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 9797278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik if (DEBUGLOG) { 98013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "Setting listview to " + 981c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson "findEventPositionNearestTime: " + (newPosition + OFF_BY_ONE_BUG)); 982c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 983c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 984c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 985c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Make sure we change the selected instance Id only on a clean query and we 986c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // do not have one set already 987c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (mSelectedInstanceId == -1 && newPosition != -1 && 988c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson data.queryType == QUERY_TYPE_CLEAN) { 989c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (data.id != -1 || data.goToTime != null) { 990c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mSelectedInstanceId = findInstanceIdFromPosition(newPosition); 9917278388c9b666f3d79b2ce4c7eeefe6ceb97aeb4Erik } 99213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 993ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 99492ea39440681f86205ad10771f1770c550552320Michael Chan // size == 1 means a fresh query. Possibly after the data changed. 99592ea39440681f86205ad10771f1770c550552320Michael Chan // Let's check whether mSelectedInstanceId is still valid. 99692ea39440681f86205ad10771f1770c550552320Michael Chan if (mAdapterInfos.size() == 1 && mSelectedInstanceId != -1) { 99792ea39440681f86205ad10771f1770c550552320Michael Chan boolean found = false; 99892ea39440681f86205ad10771f1770c550552320Michael Chan cursor.moveToPosition(-1); 99992ea39440681f86205ad10771f1770c550552320Michael Chan while (cursor.moveToNext()) { 100092ea39440681f86205ad10771f1770c550552320Michael Chan if (mSelectedInstanceId == cursor 100192ea39440681f86205ad10771f1770c550552320Michael Chan .getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID)) { 100292ea39440681f86205ad10771f1770c550552320Michael Chan found = true; 100392ea39440681f86205ad10771f1770c550552320Michael Chan break; 100492ea39440681f86205ad10771f1770c550552320Michael Chan } 100592ea39440681f86205ad10771f1770c550552320Michael Chan }; 100692ea39440681f86205ad10771f1770c550552320Michael Chan 100792ea39440681f86205ad10771f1770c550552320Michael Chan if (!found) { 100892ea39440681f86205ad10771f1770c550552320Michael Chan mSelectedInstanceId = -1; 100992ea39440681f86205ad10771f1770c550552320Michael Chan } 101092ea39440681f86205ad10771f1770c550552320Michael Chan } 101192ea39440681f86205ad10771f1770c550552320Michael Chan 1012c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Show the requested event 1013c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (mShowEventOnStart && data.queryType == QUERY_TYPE_CLEAN) { 1014c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson Cursor tempCursor = null; 1015c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson int tempCursorPosition = -1; 1016c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 1017c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // If no valid event is selected , just pick the first one 1018c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (mSelectedInstanceId == -1) { 1019c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (cursor.moveToFirst()) { 1020c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mSelectedInstanceId = cursor 1021c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson .getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID); 1022c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // Set up a dummy view holder so we have the right all day 1023c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // info when the view is created. 1024c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // TODO determine the full set of what might be useful to 1025c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson // know about the selected view and fill it in. 1026c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mSelectedVH = new AgendaAdapter.ViewHolder(); 1027c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mSelectedVH.allDay = 1028c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0; 1029c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson tempCursor = cursor; 1030c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1031c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } else if (newPosition != -1) { 1032c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson tempCursor = getCursorByPosition(newPosition); 1033c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson tempCursorPosition = getCursorPositionByPosition(newPosition); 1034c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1035c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (tempCursor != null) { 1036cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung AgendaItem item = buildAgendaItemFromCursor(tempCursor, tempCursorPosition, 1037c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson false); 10384b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson long selectedTime = findStartTimeFromPosition(newPosition); 10396bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson CalendarController.getInstance(mContext).sendEventRelatedEventWithExtra( 1040cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung this, EventType.VIEW_EVENT, item.id, item.begin, 1041cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung item.end, 0, 0, CalendarController.EventInfo.buildViewExtraLong( 1042cf31ab351c9becad6785d4d77eefc934f30b92e3James Kung Attendees.ATTENDEE_STATUS_NONE, item.allDay), 10434b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson selectedTime); 104496a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson } 1045ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 104613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 104713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan cursor.close(); 104813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 104913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 105013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update header and footer 105113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mDoneSettingUpHeaderFooter) { 105213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan OnClickListener headerFooterOnClickListener = new OnClickListener() { 105313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void onClick(View v) { 105413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (v == mHeaderView) { 105513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_OLDER)); 105613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 105713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan queueQuery(new QuerySpec(QUERY_TYPE_NEWER)); 105813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 105913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan }}; 106013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHeaderView.setOnClickListener(headerFooterOnClickListener); 106113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFooterView.setOnClickListener(headerFooterOnClickListener); 106213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaListView.addFooterView(mFooterView); 106313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mDoneSettingUpHeaderFooter = true; 106413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 106513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mQueryQueue) { 106613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int totalAgendaRangeStart = -1; 106713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int totalAgendaRangeEnd = -1; 106813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 106913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (cursorSize != 0) { 107013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Remove the query that just completed 107113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec x = mQueryQueue.poll(); 107223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (BASICLOG && !x.equals(data)) { 107323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan Log.e(TAG, "onQueryComplete - cookie != head of queue"); 107423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 107513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mEmptyCursorCount = 0; 107623f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (data.queryType == QUERY_TYPE_NEWER) { 107723f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mNewerRequestsProcessed++; 107823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } else if (data.queryType == QUERY_TYPE_OLDER) { 107923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mOlderRequestsProcessed++; 108023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 108113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 108213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = mAdapterInfos.getFirst().start; 108313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = mAdapterInfos.getLast().end; 108413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { // CursorSize == 0 108513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec querySpec = mQueryQueue.peek(); 108613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 108713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update Adapter Info with new start and end date range 108813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (!mAdapterInfos.isEmpty()) { 108913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo first = mAdapterInfos.getFirst(); 109013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo last = mAdapterInfos.getLast(); 109113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 109213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (first.start - 1 <= querySpec.end && querySpec.start < first.start) { 109313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan first.start = querySpec.start; 109413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 109513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 109613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (querySpec.start <= last.end + 1 && last.end < querySpec.end) { 109713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan last.end = querySpec.end; 109813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 109913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 110013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = first.start; 110113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = last.end; 110213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 110313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 110413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 110513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 110613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 110713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update query specification with expanded search range 110813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // and maybe rerun query 110913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan switch (querySpec.queryType) { 111013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_OLDER: 111113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 111213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.start -= MAX_QUERY_DURATION; 111313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 111413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_NEWER: 111513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 111613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.end += MAX_QUERY_DURATION; 111713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 111813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan case QUERY_TYPE_CLEAN: 111913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeStart = querySpec.start; 112013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan totalAgendaRangeEnd = querySpec.end; 112113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.start -= MAX_QUERY_DURATION / 2; 112213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan querySpec.end += MAX_QUERY_DURATION / 2; 112313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 112413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 112513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 112613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (++mEmptyCursorCount > RETRIES_ON_NO_DATA) { 112713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Nothing in the cursor again. Dropping query 112813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mQueryQueue.poll(); 112913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 113013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 113113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 113213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan updateHeaderFooter(totalAgendaRangeStart, totalAgendaRangeEnd); 113313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 11342d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // Go over the events and mark the first day after yesterday 11352d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson // that has events in it 1136d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson // If the range of adapters doesn't include yesterday, skip marking it since it will 1137d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson // mark the first day in the adapters. 11382d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson synchronized (mAdapterInfos) { 11392d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson DayAdapterInfo info = mAdapterInfos.getFirst(); 1140d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson Time time = new Time(mTimeZone); 1141d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson long now = System.currentTimeMillis(); 1142d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson time.set(now); 1143d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson int JulianToday = Time.getJulianDay(now, time.gmtoff); 1144d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson if (info != null && JulianToday >= info.start && JulianToday 1145d2fb20d676ddc5b085dd777765b5f431d067e061Isaac Katzenelson <= mAdapterInfos.getLast().end) { 11462d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson Iterator<DayAdapterInfo> iter = mAdapterInfos.iterator(); 11472d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson boolean foundDay = false; 11482d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson while (iter.hasNext() && !foundDay) { 11492d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson info = iter.next(); 11502d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson for (int i = 0; i < info.size; i++) { 11512d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson if (info.dayAdapter.findJulianDayFromPosition(i) >= JulianToday) { 11522d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson info.dayAdapter.setAsFirstDayAfterYesterday(i); 11532d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson foundDay = true; 11542d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson break; 11552d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 11562d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 11572d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 11582d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 11592d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson } 11602d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson 116113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Fire off the next query if any 116213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Iterator<QuerySpec> it = mQueryQueue.iterator(); 116313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan while (it.hasNext()) { 116413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan QuerySpec queryData = it.next(); 1165ab557bf10630e7d23c20a000bb06e12580852c75Michael Chan if (queryData.queryType == QUERY_TYPE_CLEAN 1166ab557bf10630e7d23c20a000bb06e12580852c75Michael Chan || !isInRange(queryData.start, queryData.end)) { 116713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Query accepted 116813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "Query accepted. QueueSize:" + mQueryQueue.size()); 116913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan doQuery(queryData); 117013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan break; 117113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 117213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Query rejected 117313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan it.remove(); 117413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) Log.e(TAG, "Query rejected. QueueSize:" + mQueryQueue.size()); 117513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 117613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 117713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 117823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (BASICLOG) { 117913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info3 : mAdapterInfos) { 118013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "> " + info3.toString()); 118113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 118213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 118313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 118413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 118513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan /* 118613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * Update the adapter info array with a the new cursor. Close out old 118713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * cursors as needed. 118813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * 118913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan * @return number of rows removed from the beginning 119013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan */ 119113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private int processNewCursor(QuerySpec data, Cursor cursor) { 119213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan synchronized (mAdapterInfos) { 119313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Remove adapter info's from adapterInfos as needed 119413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan DayAdapterInfo info = pruneAdapterInfo(data.queryType); 119513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int listPositionOffset = 0; 119613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (info == null) { 119713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info = new DayAdapterInfo(mContext); 119813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 119913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (DEBUGLOG) 120013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e(TAG, "processNewCursor listPositionOffsetA=" 120113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan + -info.size); 120213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listPositionOffset = -info.size; 120313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 120413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 120513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Setup adapter info 120613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.start = data.start; 120713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.end = data.end; 120813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.cursor = cursor; 1209dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan info.dayAdapter.changeCursor(info); 121013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info.size = info.dayAdapter.getCount(); 121113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 121213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Insert into adapterInfos 121313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (mAdapterInfos.isEmpty() 121413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan || data.end <= mAdapterInfos.getFirst().start) { 121513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addFirst(info); 121613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan listPositionOffset += info.size; 121713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (BASICLOG && data.start < mAdapterInfos.getLast().end) { 121813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addLast(info); 121913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info2 : mAdapterInfos) { 122013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Log.e("========== BUG ==", info2.toString()); 122113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 122213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 122313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAdapterInfos.addLast(info); 122413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 122513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 122613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Update offsets in adapterInfos 122713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount = 0; 122813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan for (DayAdapterInfo info3 : mAdapterInfos) { 122913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan info3.offset = mRowCount; 123013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mRowCount += info3.size; 123113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 123213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mLastUsedInfo = null; 123313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 123413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return listPositionOffset; 123513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 123613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 123713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 123813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 123913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static String getViewTitle(View x) { 124013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan String title = ""; 124113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (x != null) { 124213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Object yy = x.getTag(); 124313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (yy instanceof AgendaAdapter.ViewHolder) { 124413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView tv = ((AgendaAdapter.ViewHolder) yy).title; 124513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (tv != null) { 124613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan title = (String) tv.getText(); 124713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 124813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else if (yy != null) { 124913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView dateView = ((AgendaByDayAdapter.ViewHolder) yy).dateView; 125013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (dateView != null) { 125113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan title = (String) dateView.getText(); 125213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 125313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 125413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 125513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return title; 125613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 125713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 12589a88873f9ec97b47aaaaae47208d22b3998b8e99Erik public void onResume() { 12599a88873f9ec97b47aaaaae47208d22b3998b8e99Erik mTZUpdater.run(); 12609a88873f9ec97b47aaaaae47208d22b3998b8e99Erik } 12619a88873f9ec97b47aaaaae47208d22b3998b8e99Erik 126213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public void setHideDeclinedEvents(boolean hideDeclined) { 126313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mHideDeclined = hideDeclined; 126413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 1265a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa 1266ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public void setSelectedView(View v) { 1267ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (v != null) { 1268ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan Object vh = v.getTag(); 1269ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan if (vh instanceof AgendaAdapter.ViewHolder) { 12709fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik mSelectedVH = (AgendaAdapter.ViewHolder) vh; 127114764f1bd8e6c9e932a22b96583b9cf87d2617e0Isaac Katzenelson if (mSelectedInstanceId != mSelectedVH.instanceId) { 127214764f1bd8e6c9e932a22b96583b9cf87d2617e0Isaac Katzenelson mSelectedInstanceId = mSelectedVH.instanceId; 127314764f1bd8e6c9e932a22b96583b9cf87d2617e0Isaac Katzenelson notifyDataSetChanged(); 127414764f1bd8e6c9e932a22b96583b9cf87d2617e0Isaac Katzenelson } 1275ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1276ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1277ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1278ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 12799fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik public AgendaAdapter.ViewHolder getSelectedViewHolder() { 12809fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik return mSelectedVH; 12819fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik } 12829fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik 1283ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public long getSelectedInstanceId() { 1284ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan return mSelectedInstanceId; 1285ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan } 1286ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan 1287ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan public void setSelectedInstanceId(long selectedInstanceId) { 1288ffbc790abf31576c84af7ddeab090fcd93ef3299Michael Chan mSelectedInstanceId = selectedInstanceId; 12899fb45ac4a8796afb05915fb152e74d02506f59c6RoboErik mSelectedVH = null; 1290a9507932dbc49ecb9f5c71fda6af3a47b0b2a39aDaisuke Miyakawa } 129137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 1292c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson private long findInstanceIdFromPosition(int position) { 1293c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(position); 1294c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (info != null) { 1295c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return info.dayAdapter.getInstanceId(position - info.offset); 1296c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1297c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return -1; 1298c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1299c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 13004b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson private long findStartTimeFromPosition(int position) { 13014b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(position); 13024b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson if (info != null) { 13034b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson return info.dayAdapter.getStartTime(position - info.offset); 13044b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson } 13054b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson return -1; 13064b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson } 13074b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson 13084b46839d81e351314da1bdf7cad1f111dd6d671cIsaac Katzenelson 1309c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson private Cursor getCursorByPosition(int position) { 1310c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(position); 1311c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (info != null) { 1312c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return info.cursor; 1313c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1314c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return null; 1315c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1316c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 1317c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson private int getCursorPositionByPosition(int position) { 1318c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(position); 1319c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson if (info != null) { 1320c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return info.dayAdapter.getCursorPosition(position - info.offset); 1321c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1322c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson return -1; 1323c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 132437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 132537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // Implementation of HeaderIndexer interface for StickyHeeaderListView 132637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 132737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // Returns the location of the day header of a specific event specified in the position 132837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // in the adapter 1329c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson @Override 133037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson public int getHeaderPositionFromItemPosition(int position) { 1331980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson 1332980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson // For phone configuration, return -1 so there will be no sticky header 1333980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson if (!mIsTabletConfig) { 1334980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson return -1; 1335980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson } 1336980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson 133737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(position); 133837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson if (info != null) { 133937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson int pos = info.dayAdapter.getHeaderPosition(position - info.offset); 134037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return (pos != -1)?(pos + info.offset):-1; 134137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 134237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return -1; 134337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 134437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson 134537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson // Returns the number of events for a specific day header 1346c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson @Override 134737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson public int getHeaderItemsNumber(int headerPosition) { 1348980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson if (headerPosition < 0 || !mIsTabletConfig) { 134937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return -1; 135037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 135137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson DayAdapterInfo info = getAdapterInfoByPosition(headerPosition); 135237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson if (info != null) { 135337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return info.dayAdapter.getHeaderItemsCount(headerPosition - info.offset); 135437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 135537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson return -1; 135637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson } 1357c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 1358c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson @Override 1359c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson public void OnHeaderHeightChanged(int height) { 1360c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mStickyHeaderSize = height; 1361c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 1362c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson 1363812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson public int getStickyHeaderHeight() { 1364812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson return mStickyHeaderSize; 1365812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson } 1366812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson 1367c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson public void setScrollState(int state) { 1368c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson mListViewScrollState = state; 1369c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson } 137013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan} 1371