1981874e61ecf29a96a77601a3172b2503b6537eeErik/* 2981874e61ecf29a96a77601a3172b2503b6537eeErik * Copyright (C) 2010 The Android Open Source Project 3981874e61ecf29a96a77601a3172b2503b6537eeErik * 4981874e61ecf29a96a77601a3172b2503b6537eeErik * Licensed under the Apache License, Version 2.0 (the "License"); 5981874e61ecf29a96a77601a3172b2503b6537eeErik * you may not use this file except in compliance with the License. 6981874e61ecf29a96a77601a3172b2503b6537eeErik * You may obtain a copy of the License at 7981874e61ecf29a96a77601a3172b2503b6537eeErik * 8981874e61ecf29a96a77601a3172b2503b6537eeErik * http://www.apache.org/licenses/LICENSE-2.0 9981874e61ecf29a96a77601a3172b2503b6537eeErik * 10981874e61ecf29a96a77601a3172b2503b6537eeErik * Unless required by applicable law or agreed to in writing, software 11981874e61ecf29a96a77601a3172b2503b6537eeErik * distributed under the License is distributed on an "AS IS" BASIS, 12981874e61ecf29a96a77601a3172b2503b6537eeErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13981874e61ecf29a96a77601a3172b2503b6537eeErik * See the License for the specific language governing permissions and 14981874e61ecf29a96a77601a3172b2503b6537eeErik * limitations under the License. 15981874e61ecf29a96a77601a3172b2503b6537eeErik */ 16981874e61ecf29a96a77601a3172b2503b6537eeErik 17981874e61ecf29a96a77601a3172b2503b6537eeErikpackage com.android.calendar.month; 18981874e61ecf29a96a77601a3172b2503b6537eeErik 19981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.app.Activity; 207cde59082bea124050df3293101251bbecdee064James Kungimport android.app.FragmentManager; 21981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.app.LoaderManager; 2282b318634af1b6594e60cfd1f2df4d3845f80587Erikimport android.content.ContentUris; 23981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.content.CursorLoader; 24981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.content.Loader; 25092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErikimport android.content.res.Resources; 26981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.database.Cursor; 2700544123439268a9f391396712560bd6cb8ee586James Kungimport android.graphics.drawable.StateListDrawable; 28981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.net.Uri; 29981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.os.Bundle; 3009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kungimport android.os.Handler; 3109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kungimport android.os.Message; 32a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Attendees; 33a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars; 34a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Instances; 353553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.text.format.DateUtils; 36981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.text.format.Time; 37981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.util.Log; 383553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.view.LayoutInflater; 39981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.view.MotionEvent; 40981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.view.View; 41981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.view.View.OnTouchListener; 42981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.view.ViewConfiguration; 433553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.view.ViewGroup; 44981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.widget.AbsListView; 45981874e61ecf29a96a77601a3172b2503b6537eeErikimport android.widget.AbsListView.OnScrollListener; 46981874e61ecf29a96a77601a3172b2503b6537eeErik 474d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.CalendarController; 484d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.CalendarController.EventInfo; 494d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.CalendarController.EventType; 504d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.CalendarController.ViewType; 514d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.Event; 524d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.R; 534d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport com.android.calendar.Utils; 5409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kungimport com.android.calendar.event.CreateEventDialogFragment; 554d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson 5682b318634af1b6594e60cfd1f2df4d3845f80587Erikimport java.util.ArrayList; 573553621c824afe1f3eacbe8555678005ca1264a1Erikimport java.util.Calendar; 5882b318634af1b6594e60cfd1f2df4d3845f80587Erikimport java.util.HashMap; 594d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelsonimport java.util.List; 6082b318634af1b6594e60cfd1f2df4d3845f80587Erik 61e21674aefc9755ba519dfc5b3ff4348be4814903Erikpublic class MonthByWeekFragment extends SimpleDayPickerFragment implements 6282b318634af1b6594e60cfd1f2df4d3845f80587Erik CalendarController.EventHandler, LoaderManager.LoaderCallbacks<Cursor>, OnScrollListener, 6382b318634af1b6594e60cfd1f2df4d3845f80587Erik OnTouchListener { 64981874e61ecf29a96a77601a3172b2503b6537eeErik private static final String TAG = "MonthFragment"; 6509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung private static final String TAG_EVENT_DIALOG = "event_dialog"; 6609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung 6709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung private CreateEventDialogFragment mEventDialog; 68981874e61ecf29a96a77601a3172b2503b6537eeErik 69981874e61ecf29a96a77601a3172b2503b6537eeErik // Selection and selection args for adding event queries 70950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden private static final String WHERE_CALENDARS_VISIBLE = Calendars.VISIBLE + "=1"; 7182b318634af1b6594e60cfd1f2df4d3845f80587Erik private static final String INSTANCES_SORT_ORDER = Instances.START_DAY + "," 7282b318634af1b6594e60cfd1f2df4d3845f80587Erik + Instances.START_MINUTE + "," + Instances.TITLE; 73092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected static boolean mShowDetailsInMonth = false; 7482b318634af1b6594e60cfd1f2df4d3845f80587Erik 7582b318634af1b6594e60cfd1f2df4d3845f80587Erik protected float mMinimumTwoMonthFlingVelocity; 7682b318634af1b6594e60cfd1f2df4d3845f80587Erik protected boolean mIsMiniMonth; 7740bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected boolean mHideDeclined; 7882b318634af1b6594e60cfd1f2df4d3845f80587Erik 7982b318634af1b6594e60cfd1f2df4d3845f80587Erik protected int mFirstLoadedJulianDay; 8082b318634af1b6594e60cfd1f2df4d3845f80587Erik protected int mLastLoadedJulianDay; 8182b318634af1b6594e60cfd1f2df4d3845f80587Erik 8282b318634af1b6594e60cfd1f2df4d3845f80587Erik private static final int WEEKS_BUFFER = 1; 8382b318634af1b6594e60cfd1f2df4d3845f80587Erik // How long to wait after scroll stops before starting the loader 843553621c824afe1f3eacbe8555678005ca1264a1Erik // Using scroll duration because scroll state changes don't update 853553621c824afe1f3eacbe8555678005ca1264a1Erik // correctly when a scroll is triggered programmatically. 8682b318634af1b6594e60cfd1f2df4d3845f80587Erik private static final int LOADER_DELAY = 200; 87e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik // The minimum time between requeries of the data if the db is 88e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik // changing 89e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik private static final int LOADER_THROTTLE_DELAY = 500; 90981874e61ecf29a96a77601a3172b2503b6537eeErik 91981874e61ecf29a96a77601a3172b2503b6537eeErik private CursorLoader mLoader; 92981874e61ecf29a96a77601a3172b2503b6537eeErik private Uri mEventUri; 9359a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private final Time mDesiredDay = new Time(); 94981874e61ecf29a96a77601a3172b2503b6537eeErik 9582b318634af1b6594e60cfd1f2df4d3845f80587Erik private volatile boolean mShouldLoad = true; 96ca56a02bc75ca52eca0c2670be0ee4146f292624Erik private boolean mUserScrolled = false; 97981874e61ecf29a96a77601a3172b2503b6537eeErik 984d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson private int mEventsLoadingDelay; 994d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson private boolean mShowCalendarControls; 1004d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson private boolean mIsDetached; 1014d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson 10209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung private Handler mEventDialogHandler = new Handler() { 10309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung 10409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung @Override 10509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung public void handleMessage(Message msg) { 1067cde59082bea124050df3293101251bbecdee064James Kung final FragmentManager manager = getFragmentManager(); 1077cde59082bea124050df3293101251bbecdee064James Kung if (manager != null) { 1087cde59082bea124050df3293101251bbecdee064James Kung Time day = (Time) msg.obj; 1097cde59082bea124050df3293101251bbecdee064James Kung mEventDialog = new CreateEventDialogFragment(day); 1107cde59082bea124050df3293101251bbecdee064James Kung mEventDialog.show(manager, TAG_EVENT_DIALOG); 1117cde59082bea124050df3293101251bbecdee064James Kung } 11209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung } 11309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung }; 11409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung 11509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung 11659a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private final Runnable mTZUpdater = new Runnable() { 11782b318634af1b6594e60cfd1f2df4d3845f80587Erik @Override 11882b318634af1b6594e60cfd1f2df4d3845f80587Erik public void run() { 11940bcd101b212c9863c3110c05a487a7ae6ebc3caErik String tz = Utils.getTimeZone(mContext, mTZUpdater); 12040bcd101b212c9863c3110c05a487a7ae6ebc3caErik mSelectedDay.timezone = tz; 12182b318634af1b6594e60cfd1f2df4d3845f80587Erik mSelectedDay.normalize(true); 12240bcd101b212c9863c3110c05a487a7ae6ebc3caErik mTempTime.timezone = tz; 12340bcd101b212c9863c3110c05a487a7ae6ebc3caErik mFirstDayOfMonth.timezone = tz; 12440bcd101b212c9863c3110c05a487a7ae6ebc3caErik mFirstDayOfMonth.normalize(true); 12540bcd101b212c9863c3110c05a487a7ae6ebc3caErik mFirstVisibleDay.timezone = tz; 12640bcd101b212c9863c3110c05a487a7ae6ebc3caErik mFirstVisibleDay.normalize(true); 12782b318634af1b6594e60cfd1f2df4d3845f80587Erik if (mAdapter != null) { 12882b318634af1b6594e60cfd1f2df4d3845f80587Erik mAdapter.refresh(); 12982b318634af1b6594e60cfd1f2df4d3845f80587Erik } 13082b318634af1b6594e60cfd1f2df4d3845f80587Erik } 13182b318634af1b6594e60cfd1f2df4d3845f80587Erik }; 13282b318634af1b6594e60cfd1f2df4d3845f80587Erik 13382b318634af1b6594e60cfd1f2df4d3845f80587Erik 13459a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private final Runnable mUpdateLoader = new Runnable() { 13582b318634af1b6594e60cfd1f2df4d3845f80587Erik @Override 13682b318634af1b6594e60cfd1f2df4d3845f80587Erik public void run() { 13782b318634af1b6594e60cfd1f2df4d3845f80587Erik synchronized (this) { 13882b318634af1b6594e60cfd1f2df4d3845f80587Erik if (!mShouldLoad || mLoader == null) { 13982b318634af1b6594e60cfd1f2df4d3845f80587Erik return; 14082b318634af1b6594e60cfd1f2df4d3845f80587Erik } 14182b318634af1b6594e60cfd1f2df4d3845f80587Erik // Stop any previous loads while we update the uri 14282b318634af1b6594e60cfd1f2df4d3845f80587Erik stopLoader(); 14382b318634af1b6594e60cfd1f2df4d3845f80587Erik 14482b318634af1b6594e60cfd1f2df4d3845f80587Erik // Start the loader again 14582b318634af1b6594e60cfd1f2df4d3845f80587Erik mEventUri = updateUri(); 146bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik 14782b318634af1b6594e60cfd1f2df4d3845f80587Erik mLoader.setUri(mEventUri); 14882b318634af1b6594e60cfd1f2df4d3845f80587Erik mLoader.startLoading(); 1490ac1b7644ce0c4f0c72482f553872a83cbf10032Erik mLoader.onContentChanged(); 1503553621c824afe1f3eacbe8555678005ca1264a1Erik if (Log.isLoggable(TAG, Log.DEBUG)) { 1513553621c824afe1f3eacbe8555678005ca1264a1Erik Log.d(TAG, "Started loader with uri: " + mEventUri); 1523553621c824afe1f3eacbe8555678005ca1264a1Erik } 15382b318634af1b6594e60cfd1f2df4d3845f80587Erik } 15482b318634af1b6594e60cfd1f2df4d3845f80587Erik } 15582b318634af1b6594e60cfd1f2df4d3845f80587Erik }; 1564d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson // Used to load the events when a delay is needed 1574d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson Runnable mLoadingRunnable = new Runnable() { 1584d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson @Override 1594d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson public void run() { 1604d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson if (!mIsDetached) { 1614d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mLoader = (CursorLoader) getLoaderManager().initLoader(0, null, 1624d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson MonthByWeekFragment.this); 1634d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 1644d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 1654d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson }; 1664d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson 16782b318634af1b6594e60cfd1f2df4d3845f80587Erik 16882b318634af1b6594e60cfd1f2df4d3845f80587Erik /** 16982b318634af1b6594e60cfd1f2df4d3845f80587Erik * Updates the uri used by the loader according to the current position of 17082b318634af1b6594e60cfd1f2df4d3845f80587Erik * the listview. 17182b318634af1b6594e60cfd1f2df4d3845f80587Erik * 17282b318634af1b6594e60cfd1f2df4d3845f80587Erik * @return The new Uri to use 17382b318634af1b6594e60cfd1f2df4d3845f80587Erik */ 17482b318634af1b6594e60cfd1f2df4d3845f80587Erik private Uri updateUri() { 175e21674aefc9755ba519dfc5b3ff4348be4814903Erik SimpleWeekView child = (SimpleWeekView) mListView.getChildAt(0); 1763553621c824afe1f3eacbe8555678005ca1264a1Erik if (child != null) { 1773553621c824afe1f3eacbe8555678005ca1264a1Erik int julianDay = child.getFirstJulianDay(); 17840bcd101b212c9863c3110c05a487a7ae6ebc3caErik mFirstLoadedJulianDay = julianDay; 1793553621c824afe1f3eacbe8555678005ca1264a1Erik } 18082b318634af1b6594e60cfd1f2df4d3845f80587Erik // -1 to ensure we get all day events from any time zone 18182b318634af1b6594e60cfd1f2df4d3845f80587Erik mTempTime.setJulianDay(mFirstLoadedJulianDay - 1); 18282b318634af1b6594e60cfd1f2df4d3845f80587Erik long start = mTempTime.toMillis(true); 18340bcd101b212c9863c3110c05a487a7ae6ebc3caErik mLastLoadedJulianDay = mFirstLoadedJulianDay + (mNumWeeks + 2 * WEEKS_BUFFER) * 7; 18482b318634af1b6594e60cfd1f2df4d3845f80587Erik // +1 to ensure we get all day events from any time zone 18582b318634af1b6594e60cfd1f2df4d3845f80587Erik mTempTime.setJulianDay(mLastLoadedJulianDay + 1); 18682b318634af1b6594e60cfd1f2df4d3845f80587Erik long end = mTempTime.toMillis(true); 18782b318634af1b6594e60cfd1f2df4d3845f80587Erik 18882b318634af1b6594e60cfd1f2df4d3845f80587Erik // Create a new uri with the updated times 18982b318634af1b6594e60cfd1f2df4d3845f80587Erik Uri.Builder builder = Instances.CONTENT_URI.buildUpon(); 19082b318634af1b6594e60cfd1f2df4d3845f80587Erik ContentUris.appendId(builder, start); 19182b318634af1b6594e60cfd1f2df4d3845f80587Erik ContentUris.appendId(builder, end); 19282b318634af1b6594e60cfd1f2df4d3845f80587Erik return builder.build(); 19382b318634af1b6594e60cfd1f2df4d3845f80587Erik } 19482b318634af1b6594e60cfd1f2df4d3845f80587Erik 1954d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson // Extract range of julian days from URI 1964d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson private void updateLoadedDays() { 1974d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson List<String> pathSegments = mEventUri.getPathSegments(); 1984d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson int size = pathSegments.size(); 1994d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson if (size <= 2) { 2004d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson return; 2014d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 2024d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson long first = Long.parseLong(pathSegments.get(size - 2)); 2034d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson long last = Long.parseLong(pathSegments.get(size - 1)); 2044d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mTempTime.set(first); 2054d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mFirstLoadedJulianDay = Time.getJulianDay(first, mTempTime.gmtoff); 2064d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mTempTime.set(last); 2074d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mLastLoadedJulianDay = Time.getJulianDay(last, mTempTime.gmtoff); 2084d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 2094d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson 21040bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected String updateWhere() { 21140bcd101b212c9863c3110c05a487a7ae6ebc3caErik // TODO fix selection/selection args after b/3206641 is fixed 212950e8a615f3dcca0b61b2eb8f8de72ecf6825d4bAndy McFadden String where = WHERE_CALENDARS_VISIBLE; 213a8de05eced810707676281ffc9cb0e4ad5e1a3efRoboErik if (mHideDeclined || !mShowDetailsInMonth) { 214db08870a2c8b9de543705eed2f296a8018f00a05Erik where += " AND " + Instances.SELF_ATTENDEE_STATUS + "!=" 215db08870a2c8b9de543705eed2f296a8018f00a05Erik + Attendees.ATTENDEE_STATUS_DECLINED; 21640bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 21740bcd101b212c9863c3110c05a487a7ae6ebc3caErik return where; 21840bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 21940bcd101b212c9863c3110c05a487a7ae6ebc3caErik 22082b318634af1b6594e60cfd1f2df4d3845f80587Erik private void stopLoader() { 22182b318634af1b6594e60cfd1f2df4d3845f80587Erik synchronized (mUpdateLoader) { 22282b318634af1b6594e60cfd1f2df4d3845f80587Erik mHandler.removeCallbacks(mUpdateLoader); 22382b318634af1b6594e60cfd1f2df4d3845f80587Erik if (mLoader != null) { 22482b318634af1b6594e60cfd1f2df4d3845f80587Erik mLoader.stopLoading(); 2253553621c824afe1f3eacbe8555678005ca1264a1Erik if (Log.isLoggable(TAG, Log.DEBUG)) { 2263553621c824afe1f3eacbe8555678005ca1264a1Erik Log.d(TAG, "Stopped loader from loading"); 2273553621c824afe1f3eacbe8555678005ca1264a1Erik } 22882b318634af1b6594e60cfd1f2df4d3845f80587Erik } 22982b318634af1b6594e60cfd1f2df4d3845f80587Erik } 23082b318634af1b6594e60cfd1f2df4d3845f80587Erik } 231981874e61ecf29a96a77601a3172b2503b6537eeErik 232981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 233981874e61ecf29a96a77601a3172b2503b6537eeErik public void onAttach(Activity activity) { 234981874e61ecf29a96a77601a3172b2503b6537eeErik super.onAttach(activity); 23540bcd101b212c9863c3110c05a487a7ae6ebc3caErik mTZUpdater.run(); 23604b288958078f8b29870dcbb2239df448c559610Erik if (mAdapter != null) { 23704b288958078f8b29870dcbb2239df448c559610Erik mAdapter.setSelectedDay(mSelectedDay); 23804b288958078f8b29870dcbb2239df448c559610Erik } 2394d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mIsDetached = false; 24082b318634af1b6594e60cfd1f2df4d3845f80587Erik 241981874e61ecf29a96a77601a3172b2503b6537eeErik ViewConfiguration viewConfig = ViewConfiguration.get(activity); 242981874e61ecf29a96a77601a3172b2503b6537eeErik mMinimumTwoMonthFlingVelocity = viewConfig.getScaledMaximumFlingVelocity() / 2; 2434d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson Resources res = activity.getResources(); 2444d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mShowCalendarControls = Utils.getConfigBool(activity, R.bool.show_calendar_controls); 2454d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson // Synchronized the loading time of the month's events with the animation of the 2464d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson // calendar controls. 2474d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson if (mShowCalendarControls) { 2484d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mEventsLoadingDelay = res.getInteger(R.integer.calendar_controls_animation_time); 2494d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 250a8133aacf45345c83fc02e2a6ddc86e62153eca8Isaac Katzenelson mShowDetailsInMonth = res.getBoolean(R.bool.show_details_in_month); 25182b318634af1b6594e60cfd1f2df4d3845f80587Erik } 252981874e61ecf29a96a77601a3172b2503b6537eeErik 25382b318634af1b6594e60cfd1f2df4d3845f80587Erik @Override 2544d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson public void onDetach() { 2554d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mIsDetached = true; 2564d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson super.onDetach(); 2574d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson if (mShowCalendarControls) { 2584e4e25a82e16872e6579af760eb17877decaceaeIsaac Katzenelson if (mListView != null) { 2594e4e25a82e16872e6579af760eb17877decaceaeIsaac Katzenelson mListView.removeCallbacks(mLoadingRunnable); 2604e4e25a82e16872e6579af760eb17877decaceaeIsaac Katzenelson } 2614d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 2624d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 2634d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson 2644d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson @Override 26582b318634af1b6594e60cfd1f2df4d3845f80587Erik protected void setUpAdapter() { 26682b318634af1b6594e60cfd1f2df4d3845f80587Erik mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext); 26782b318634af1b6594e60cfd1f2df4d3845f80587Erik mShowWeekNumber = Utils.getShowWeekNumber(mContext); 26882b318634af1b6594e60cfd1f2df4d3845f80587Erik 26982b318634af1b6594e60cfd1f2df4d3845f80587Erik HashMap<String, Integer> weekParams = new HashMap<String, Integer>(); 270e21674aefc9755ba519dfc5b3ff4348be4814903Erik weekParams.put(SimpleWeeksAdapter.WEEK_PARAMS_NUM_WEEKS, mNumWeeks); 271e21674aefc9755ba519dfc5b3ff4348be4814903Erik weekParams.put(SimpleWeeksAdapter.WEEK_PARAMS_SHOW_WEEK, mShowWeekNumber ? 1 : 0); 272e21674aefc9755ba519dfc5b3ff4348be4814903Erik weekParams.put(SimpleWeeksAdapter.WEEK_PARAMS_WEEK_START, mFirstDayOfWeek); 2733553621c824afe1f3eacbe8555678005ca1264a1Erik weekParams.put(MonthByWeekAdapter.WEEK_PARAMS_IS_MINI, mIsMiniMonth ? 1 : 0); 274e21674aefc9755ba519dfc5b3ff4348be4814903Erik weekParams.put(SimpleWeeksAdapter.WEEK_PARAMS_JULIAN_DAY, 27540bcd101b212c9863c3110c05a487a7ae6ebc3caErik Time.getJulianDay(mSelectedDay.toMillis(true), mSelectedDay.gmtoff)); 276e21674aefc9755ba519dfc5b3ff4348be4814903Erik weekParams.put(SimpleWeeksAdapter.WEEK_PARAMS_DAYS_PER_WEEK, mDaysPerWeek); 2773553621c824afe1f3eacbe8555678005ca1264a1Erik if (mAdapter == null) { 27809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung mAdapter = new MonthByWeekAdapter(getActivity(), weekParams, mEventDialogHandler); 2793553621c824afe1f3eacbe8555678005ca1264a1Erik mAdapter.registerDataSetObserver(mObserver); 2803553621c824afe1f3eacbe8555678005ca1264a1Erik } else { 2813553621c824afe1f3eacbe8555678005ca1264a1Erik mAdapter.updateParams(weekParams); 2823553621c824afe1f3eacbe8555678005ca1264a1Erik } 2833553621c824afe1f3eacbe8555678005ca1264a1Erik mAdapter.notifyDataSetChanged(); 2843553621c824afe1f3eacbe8555678005ca1264a1Erik } 2853553621c824afe1f3eacbe8555678005ca1264a1Erik 2863553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 2873553621c824afe1f3eacbe8555678005ca1264a1Erik public View onCreateView( 2883553621c824afe1f3eacbe8555678005ca1264a1Erik LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 289144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik View v; 290144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik if (mIsMiniMonth) { 291144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik v = inflater.inflate(R.layout.month_by_week, container, false); 292144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik } else { 293144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik v = inflater.inflate(R.layout.full_month_by_week, container, false); 294144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik } 2953553621c824afe1f3eacbe8555678005ca1264a1Erik mDayNamesHeader = (ViewGroup) v.findViewById(R.id.day_names); 2963553621c824afe1f3eacbe8555678005ca1264a1Erik return v; 297981874e61ecf29a96a77601a3172b2503b6537eeErik } 298981874e61ecf29a96a77601a3172b2503b6537eeErik 299981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 300981874e61ecf29a96a77601a3172b2503b6537eeErik public void onActivityCreated(Bundle savedInstanceState) { 301981874e61ecf29a96a77601a3172b2503b6537eeErik super.onActivityCreated(savedInstanceState); 30200544123439268a9f391396712560bd6cb8ee586James Kung mListView.setSelector(new StateListDrawable()); 303981874e61ecf29a96a77601a3172b2503b6537eeErik mListView.setOnTouchListener(this); 30400544123439268a9f391396712560bd6cb8ee586James Kung 30541cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson if (!mIsMiniMonth) { 30641cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson mListView.setBackgroundColor(getResources().getColor(R.color.month_bgcolor)); 30741cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson } 3084d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson 3094d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson // To get a smoother transition when showing this fragment, delay loading of events until 3104d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson // the fragment is expended fully and the calendar controls are gone. 3114d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson if (mShowCalendarControls) { 3124d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mListView.postDelayed(mLoadingRunnable, mEventsLoadingDelay); 3134d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } else { 3144d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson mLoader = (CursorLoader) getLoaderManager().initLoader(0, null, this); 3154d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson } 31659a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson mAdapter.setListView(mListView); 317981874e61ecf29a96a77601a3172b2503b6537eeErik } 318981874e61ecf29a96a77601a3172b2503b6537eeErik 31982b318634af1b6594e60cfd1f2df4d3845f80587Erik public MonthByWeekFragment() { 32040bcd101b212c9863c3110c05a487a7ae6ebc3caErik this(System.currentTimeMillis(), true); 321981874e61ecf29a96a77601a3172b2503b6537eeErik } 322981874e61ecf29a96a77601a3172b2503b6537eeErik 32340bcd101b212c9863c3110c05a487a7ae6ebc3caErik public MonthByWeekFragment(long initialTime, boolean isMiniMonth) { 32440bcd101b212c9863c3110c05a487a7ae6ebc3caErik super(initialTime); 32582b318634af1b6594e60cfd1f2df4d3845f80587Erik mIsMiniMonth = isMiniMonth; 326124b831510317b41acf3e391b25882a785272654Erik } 327124b831510317b41acf3e391b25882a785272654Erik 3283553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 329ca56a02bc75ca52eca0c2670be0ee4146f292624Erik protected void setUpHeader() { 3303553621c824afe1f3eacbe8555678005ca1264a1Erik if (mIsMiniMonth) { 331ca56a02bc75ca52eca0c2670be0ee4146f292624Erik super.setUpHeader(); 3323553621c824afe1f3eacbe8555678005ca1264a1Erik return; 3333553621c824afe1f3eacbe8555678005ca1264a1Erik } 3343553621c824afe1f3eacbe8555678005ca1264a1Erik 3353553621c824afe1f3eacbe8555678005ca1264a1Erik mDayLabels = new String[7]; 3363553621c824afe1f3eacbe8555678005ca1264a1Erik for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) { 3372be617ee36c587a97fe171acf90ed23683be2d80RoboErik mDayLabels[i - Calendar.SUNDAY] = DateUtils.getDayOfWeekString(i, 3382be617ee36c587a97fe171acf90ed23683be2d80RoboErik DateUtils.LENGTH_MEDIUM).toUpperCase(); 3393553621c824afe1f3eacbe8555678005ca1264a1Erik } 3403553621c824afe1f3eacbe8555678005ca1264a1Erik } 3413553621c824afe1f3eacbe8555678005ca1264a1Erik 342981874e61ecf29a96a77601a3172b2503b6537eeErik // TODO 343981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 344981874e61ecf29a96a77601a3172b2503b6537eeErik public Loader<Cursor> onCreateLoader(int id, Bundle args) { 3453553621c824afe1f3eacbe8555678005ca1264a1Erik if (mIsMiniMonth) { 3463553621c824afe1f3eacbe8555678005ca1264a1Erik return null; 3473553621c824afe1f3eacbe8555678005ca1264a1Erik } 348bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik CursorLoader loader; 34982b318634af1b6594e60cfd1f2df4d3845f80587Erik synchronized (mUpdateLoader) { 35040bcd101b212c9863c3110c05a487a7ae6ebc3caErik mFirstLoadedJulianDay = 35140bcd101b212c9863c3110c05a487a7ae6ebc3caErik Time.getJulianDay(mSelectedDay.toMillis(true), mSelectedDay.gmtoff) 35240bcd101b212c9863c3110c05a487a7ae6ebc3caErik - (mNumWeeks * 7 / 2); 35382b318634af1b6594e60cfd1f2df4d3845f80587Erik mEventUri = updateUri(); 35440bcd101b212c9863c3110c05a487a7ae6ebc3caErik String where = updateWhere(); 35540bcd101b212c9863c3110c05a487a7ae6ebc3caErik 356bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik loader = new CursorLoader( 35740bcd101b212c9863c3110c05a487a7ae6ebc3caErik getActivity(), mEventUri, Event.EVENT_PROJECTION, where, 35840bcd101b212c9863c3110c05a487a7ae6ebc3caErik null /* WHERE_CALENDARS_SELECTED_ARGS */, INSTANCES_SORT_ORDER); 359bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik loader.setUpdateThrottle(LOADER_THROTTLE_DELAY); 36082b318634af1b6594e60cfd1f2df4d3845f80587Erik } 3613553621c824afe1f3eacbe8555678005ca1264a1Erik if (Log.isLoggable(TAG, Log.DEBUG)) { 3623553621c824afe1f3eacbe8555678005ca1264a1Erik Log.d(TAG, "Returning new loader with uri: " + mEventUri); 3633553621c824afe1f3eacbe8555678005ca1264a1Erik } 364bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik return loader; 365981874e61ecf29a96a77601a3172b2503b6537eeErik } 366981874e61ecf29a96a77601a3172b2503b6537eeErik 367981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 36882b318634af1b6594e60cfd1f2df4d3845f80587Erik public void doResumeUpdates() { 36982b318634af1b6594e60cfd1f2df4d3845f80587Erik mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext); 37082b318634af1b6594e60cfd1f2df4d3845f80587Erik mShowWeekNumber = Utils.getShowWeekNumber(mContext); 37140bcd101b212c9863c3110c05a487a7ae6ebc3caErik boolean prevHideDeclined = mHideDeclined; 37240bcd101b212c9863c3110c05a487a7ae6ebc3caErik mHideDeclined = Utils.getHideDeclinedEvents(mContext); 373db08870a2c8b9de543705eed2f296a8018f00a05Erik if (prevHideDeclined != mHideDeclined && mLoader != null) { 37440bcd101b212c9863c3110c05a487a7ae6ebc3caErik mLoader.setSelection(updateWhere()); 37540bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 37691b01ed605e36fc5a7a924c226597a62c789b50dErik mDaysPerWeek = Utils.getDaysPerWeek(mContext); 37782b318634af1b6594e60cfd1f2df4d3845f80587Erik updateHeader(); 37863cd053150e00fde045b019dbe0f48b8a9ed3559Erik mAdapter.setSelectedDay(mSelectedDay); 37982b318634af1b6594e60cfd1f2df4d3845f80587Erik mTZUpdater.run(); 380bdd7af6fb85c67e3156feee2e898906cb4c53f34RoboErik mTodayUpdater.run(); 38140bcd101b212c9863c3110c05a487a7ae6ebc3caErik goTo(mSelectedDay.toMillis(true), false, true, false); 382981874e61ecf29a96a77601a3172b2503b6537eeErik } 383981874e61ecf29a96a77601a3172b2503b6537eeErik 38482b318634af1b6594e60cfd1f2df4d3845f80587Erik @Override 38582b318634af1b6594e60cfd1f2df4d3845f80587Erik public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 38682b318634af1b6594e60cfd1f2df4d3845f80587Erik synchronized (mUpdateLoader) { 38740bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (Log.isLoggable(TAG, Log.DEBUG)) { 38840bcd101b212c9863c3110c05a487a7ae6ebc3caErik Log.d(TAG, "Found " + data.getCount() + " cursor entries for uri " + mEventUri); 38940bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 39082b318634af1b6594e60cfd1f2df4d3845f80587Erik CursorLoader cLoader = (CursorLoader) loader; 391bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik if (mEventUri == null) { 392bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik mEventUri = cLoader.getUri(); 3934d2f035beb502dbd557fe31095c821d23b13608cIsaac Katzenelson updateLoadedDays(); 394bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik } 39582b318634af1b6594e60cfd1f2df4d3845f80587Erik if (cLoader.getUri().compareTo(mEventUri) != 0) { 39682b318634af1b6594e60cfd1f2df4d3845f80587Erik // We've started a new query since this loader ran so ignore the 39782b318634af1b6594e60cfd1f2df4d3845f80587Erik // result 39882b318634af1b6594e60cfd1f2df4d3845f80587Erik return; 39982b318634af1b6594e60cfd1f2df4d3845f80587Erik } 40082b318634af1b6594e60cfd1f2df4d3845f80587Erik ArrayList<Event> events = new ArrayList<Event>(); 40182b318634af1b6594e60cfd1f2df4d3845f80587Erik Event.buildEventsFromCursor( 40282b318634af1b6594e60cfd1f2df4d3845f80587Erik events, data, mContext, mFirstLoadedJulianDay, mLastLoadedJulianDay); 4033553621c824afe1f3eacbe8555678005ca1264a1Erik ((MonthByWeekAdapter) mAdapter).setEvents(mFirstLoadedJulianDay, 4043553621c824afe1f3eacbe8555678005ca1264a1Erik mLastLoadedJulianDay - mFirstLoadedJulianDay + 1, events); 40582b318634af1b6594e60cfd1f2df4d3845f80587Erik } 406981874e61ecf29a96a77601a3172b2503b6537eeErik } 407981874e61ecf29a96a77601a3172b2503b6537eeErik 408bb111d4d43ae96f3e74ba904f8c113f47553385bRoboErik @Override 4091d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn public void onLoaderReset(Loader<Cursor> loader) { 4101d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn } 4111d6d7c6fee68b1641ce8664caf5d6832bf6bb618Dianne Hackborn 412981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 41382b318634af1b6594e60cfd1f2df4d3845f80587Erik public void eventsChanged() { 414e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik // TODO remove this after b/3387924 is resolved 415e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik if (mLoader != null) { 416e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik mLoader.forceLoad(); 417e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik } 418981874e61ecf29a96a77601a3172b2503b6537eeErik } 419981874e61ecf29a96a77601a3172b2503b6537eeErik 420981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 421981874e61ecf29a96a77601a3172b2503b6537eeErik public long getSupportedEventTypes() { 422e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik return EventType.GO_TO | EventType.EVENTS_CHANGED; 423981874e61ecf29a96a77601a3172b2503b6537eeErik } 424981874e61ecf29a96a77601a3172b2503b6537eeErik 425981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 426981874e61ecf29a96a77601a3172b2503b6537eeErik public void handleEvent(EventInfo event) { 427981874e61ecf29a96a77601a3172b2503b6537eeErik if (event.eventType == EventType.GO_TO) { 42863cd053150e00fde045b019dbe0f48b8a9ed3559Erik boolean animate = true; 42963cd053150e00fde045b019dbe0f48b8a9ed3559Erik if (mDaysPerWeek * mNumWeeks * 2 < Math.abs( 43063cd053150e00fde045b019dbe0f48b8a9ed3559Erik Time.getJulianDay(event.selectedTime.toMillis(true), event.selectedTime.gmtoff) 43163cd053150e00fde045b019dbe0f48b8a9ed3559Erik - Time.getJulianDay(mFirstVisibleDay.toMillis(true), mFirstVisibleDay.gmtoff) 43263cd053150e00fde045b019dbe0f48b8a9ed3559Erik - mDaysPerWeek * mNumWeeks / 2)) { 43363cd053150e00fde045b019dbe0f48b8a9ed3559Erik animate = false; 43463cd053150e00fde045b019dbe0f48b8a9ed3559Erik } 4350271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mDesiredDay.set(event.selectedTime); 4360271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mDesiredDay.normalize(true); 4375b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik boolean animateToday = (event.extraLong & CalendarController.EXTRA_GOTO_TODAY) != 0; 4385b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik boolean delayAnimation = goTo(event.selectedTime.toMillis(true), animate, true, false); 4395b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (animateToday) { 4405b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik // If we need to flash today start the animation after any 4415b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik // movement from listView has ended. 4425b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mHandler.postDelayed(new Runnable() { 4435b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik @Override 4445b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public void run() { 4455b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik ((MonthByWeekAdapter) mAdapter).animateToday(); 4465b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAdapter.notifyDataSetChanged(); 4475b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 4485b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik }, delayAnimation ? GOTO_SCROLL_DURATION : 0); 4495b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 450e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik } else if (event.eventType == EventType.EVENTS_CHANGED) { 451e3ab9ec7b0d7001b93a25f55556529f6a1fb1871Erik eventsChanged(); 452981874e61ecf29a96a77601a3172b2503b6537eeErik } 453981874e61ecf29a96a77601a3172b2503b6537eeErik } 454981874e61ecf29a96a77601a3172b2503b6537eeErik 455981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 456a50f3172fdb7666f684f190d55d7ed701762fa3dRoboErik protected void setMonthDisplayed(Time time, boolean updateHighlight) { 457a50f3172fdb7666f684f190d55d7ed701762fa3dRoboErik super.setMonthDisplayed(time, updateHighlight); 45840bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (!mIsMiniMonth) { 4590271b412913bb157c92f6e42edcf535b1d3331e2RoboErik boolean useSelected = false; 4600271b412913bb157c92f6e42edcf535b1d3331e2RoboErik if (time.year == mDesiredDay.year && time.month == mDesiredDay.month) { 4610271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mSelectedDay.set(mDesiredDay); 4620271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mAdapter.setSelectedDay(mDesiredDay); 4630271b412913bb157c92f6e42edcf535b1d3331e2RoboErik useSelected = true; 4640271b412913bb157c92f6e42edcf535b1d3331e2RoboErik } else { 4650271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mSelectedDay.set(time); 4660271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mAdapter.setSelectedDay(time); 4670271b412913bb157c92f6e42edcf535b1d3331e2RoboErik } 46840bcd101b212c9863c3110c05a487a7ae6ebc3caErik CalendarController controller = CalendarController.getInstance(mContext); 4690271b412913bb157c92f6e42edcf535b1d3331e2RoboErik if (mSelectedDay.minute >= 30) { 4700271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mSelectedDay.minute = 30; 4710271b412913bb157c92f6e42edcf535b1d3331e2RoboErik } else { 4720271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mSelectedDay.minute = 0; 4730271b412913bb157c92f6e42edcf535b1d3331e2RoboErik } 4740271b412913bb157c92f6e42edcf535b1d3331e2RoboErik long newTime = mSelectedDay.normalize(true); 4750271b412913bb157c92f6e42edcf535b1d3331e2RoboErik if (newTime != controller.getTime() && mUserScrolled) { 4760271b412913bb157c92f6e42edcf535b1d3331e2RoboErik long offset = useSelected ? 0 : DateUtils.WEEK_IN_MILLIS * mNumWeeks / 3; 4770271b412913bb157c92f6e42edcf535b1d3331e2RoboErik controller.setTime(newTime + offset); 47840bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 4794cff9b80858a09ec526d42d93b51f4826a8639d4RoboErik controller.sendEvent(this, EventType.UPDATE_TITLE, time, time, time, -1, 480f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan ViewType.CURRENT, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY 481eaafa2b48be7194a61754604ae37b3d62e9118d8Erik | DateUtils.FORMAT_SHOW_YEAR, null, null); 482981874e61ecf29a96a77601a3172b2503b6537eeErik } 48340bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 48440bcd101b212c9863c3110c05a487a7ae6ebc3caErik 48540bcd101b212c9863c3110c05a487a7ae6ebc3caErik @Override 48640bcd101b212c9863c3110c05a487a7ae6ebc3caErik public void onScrollStateChanged(AbsListView view, int scrollState) { 48782b318634af1b6594e60cfd1f2df4d3845f80587Erik 48882b318634af1b6594e60cfd1f2df4d3845f80587Erik synchronized (mUpdateLoader) { 48982b318634af1b6594e60cfd1f2df4d3845f80587Erik if (scrollState != OnScrollListener.SCROLL_STATE_IDLE) { 49082b318634af1b6594e60cfd1f2df4d3845f80587Erik mShouldLoad = false; 49182b318634af1b6594e60cfd1f2df4d3845f80587Erik stopLoader(); 4920271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mDesiredDay.setToNow(); 4933553621c824afe1f3eacbe8555678005ca1264a1Erik } else { 4943553621c824afe1f3eacbe8555678005ca1264a1Erik mHandler.removeCallbacks(mUpdateLoader); 4953553621c824afe1f3eacbe8555678005ca1264a1Erik mShouldLoad = true; 4963553621c824afe1f3eacbe8555678005ca1264a1Erik mHandler.postDelayed(mUpdateLoader, LOADER_DELAY); 49782b318634af1b6594e60cfd1f2df4d3845f80587Erik } 49882b318634af1b6594e60cfd1f2df4d3845f80587Erik } 499ca56a02bc75ca52eca0c2670be0ee4146f292624Erik if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { 500ca56a02bc75ca52eca0c2670be0ee4146f292624Erik mUserScrolled = true; 501ca56a02bc75ca52eca0c2670be0ee4146f292624Erik } 50282b318634af1b6594e60cfd1f2df4d3845f80587Erik 50340bcd101b212c9863c3110c05a487a7ae6ebc3caErik mScrollStateChangedRunnable.doScrollStateChange(view, scrollState); 504981874e61ecf29a96a77601a3172b2503b6537eeErik } 505981874e61ecf29a96a77601a3172b2503b6537eeErik 506981874e61ecf29a96a77601a3172b2503b6537eeErik @Override 507981874e61ecf29a96a77601a3172b2503b6537eeErik public boolean onTouch(View v, MotionEvent event) { 5080271b412913bb157c92f6e42edcf535b1d3331e2RoboErik mDesiredDay.setToNow(); 509a8133aacf45345c83fc02e2a6ddc86e62153eca8Isaac Katzenelson return false; 510981874e61ecf29a96a77601a3172b2503b6537eeErik // TODO post a cleanup to push us back onto the grid if something went 511981874e61ecf29a96a77601a3172b2503b6537eeErik // wrong in a scroll such as the user stopping the view but not 512981874e61ecf29a96a77601a3172b2503b6537eeErik // scrolling 513981874e61ecf29a96a77601a3172b2503b6537eeErik } 514981874e61ecf29a96a77601a3172b2503b6537eeErik} 515