CalendarViewAdapter.java revision 8135093480db642734fb40d9627325bf9e97a8c9
19a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson/* 29a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * Copyright (C) 2011 The Android Open Source Project 39a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * 49a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * Licensed under the Apache License, Version 2.0 (the "License"); 59a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * you may not use this file except in compliance with the License. 69a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * You may obtain a copy of the License at 79a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * 89a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * http://www.apache.org/licenses/LICENSE-2.0 99a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * 109a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * Unless required by applicable law or agreed to in writing, software 119a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * distributed under the License is distributed on an "AS IS" BASIS, 129a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * See the License for the specific language governing permissions and 149a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * limitations under the License. 159a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson */ 169a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 179a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonpackage com.android.calendar; 189a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 199a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport com.android.calendar.CalendarController.ViewType; 209a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 219a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.content.Context; 229a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.database.DataSetObserver; 239a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.os.Handler; 249a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.text.TextUtils; 259a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.text.format.DateUtils; 269a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.text.format.Time; 279a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.util.Log; 289a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.view.LayoutInflater; 299a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.view.View; 309a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.view.ViewGroup; 319a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.widget.SpinnerAdapter; 329a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport android.widget.TextView; 339a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 349a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport java.util.ArrayList; 359a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport java.util.Arrays; 369a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport java.util.Formatter; 379a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport java.util.Iterator; 389a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonimport java.util.Locale; 399a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 409a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 419a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson/* 429a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * The MenuSpinnerAdapter defines the look of the ActionBar's pull down menu 439a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * for small screen layouts. The pull down menu replaces the tabs uses for big screen layouts 449a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * 459a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson * The MenuSpinnerAdapter responsible for creating the views used for in the pull down menu. 469a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson */ 479a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 489a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelsonpublic class CalendarViewAdapter implements SpinnerAdapter { 499a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 509a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private static final String TAG = "MenuSpinnerAdapter"; 519a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 529a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String mButtonNames []; // Text on buttons 539a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private ArrayList<DataSetObserver> mObservers; 549a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 559a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Used to define the look of the menu button according to the current view: 569a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Day view: show day of the week + full date underneath 579a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Week view: show the month + year 589a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Month view: show the month + year 599a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Agenda view: show day of the week + full date underneath 609a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private int mCurrentMainView; 619a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 629a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private final LayoutInflater mInflater; 639a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 649a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Defines the types of view returned by this spinner 659a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private static final int BUTTON_VIEW_TYPE = 0; 669a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson static final int VIEW_TYPE_NUM = 1; // Increase this if you add more view types 679a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 689a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public static final int DAY_BUTTON_INDEX = 0; 699a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public static final int WEEK_BUTTON_INDEX = 1; 709a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public static final int MONTH_BUTTON_INDEX = 2; 719a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public static final int AGENDA_BUTTON_INDEX = 3; 729a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 739a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // The current selected event's time, used to calculate the date and day of the week 749a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // for the buttons. 759a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long mMilliTime; 769a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String mTimeZone; 779a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private Time mTmpTime; 789a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long mTodayJulianDay; 799a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 809a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Context mContext; 819a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private Formatter mFormatter; 829a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private StringBuilder mStringBuilder; 839a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private Handler mMidnightHandler = null; // Used to run a time update every midnight 849a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 859a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Updates time specific variables (time-zone, today's Julian day). 869a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private Runnable mTimeUpdater = new Runnable() { 879a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson @Override 889a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void run() { 899a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson setTimeVars(mContext); 909a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 919a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson }; 929a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 939a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public CalendarViewAdapter(Context context, int viewType) { 949a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson super(); 959a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 969a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mCurrentMainView = viewType; 979a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mContext = context; 989a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 999a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Initialize 1009a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mButtonNames = context.getResources().getStringArray(R.array.buttons_list); 1019a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mObservers = new ArrayList<DataSetObserver>(); 1029a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 1039a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder = new StringBuilder(50); 1049a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 1059a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1069a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Sets time specific variables and starts a thread for midnight updates 1079a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson setTimeVars(context); 1089a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1099a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1109a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1119a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Sets the time zone and today's Julian day to be used by the adapter. 1129a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Also, notify listener on the change and resets the midnight update thread. 1139a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private void setTimeVars(Context context) { 1149a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mTimeZone = Utils.getTimeZone(context, mTimeUpdater); 1159a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mTmpTime = new Time(mTimeZone); 1169a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Time time = new Time(mTimeZone); 1179a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long now = System.currentTimeMillis(); 1189a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson time.set(now); 1199a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mTodayJulianDay = Time.getJulianDay(now, time.gmtoff); 1209a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson notifyDataChange(); 1219a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson setMidnightHandler(); 1229a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1239a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1249a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Sets a thread to run 1 second after midnight and update the current date 1259a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // This is used to display correctly the date of yesterday/today/tomorrow 1269a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void setMidnightHandler() { 1279a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (mMidnightHandler == null) { 1289a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mMidnightHandler = new Handler(); 1299a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } else { 1309a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mMidnightHandler.removeCallbacks(mTimeUpdater); 1319a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1329a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Set the time updater to run at 1 second after midnight 1339a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long now = System.currentTimeMillis(); 1349a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Time time = new Time(mTimeZone); 1359a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson time.set(now); 1369a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long runInMillis = (24 * 3600 - time.hour * 3600 - time.minute * 60 - 1379a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson time.second + 1) * 1000; 1389a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mMidnightHandler.postDelayed(mTimeUpdater, runInMillis); 1399a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1409a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1419a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Stops the midnight update thread, called by the activity when it is paused. 1429a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void resetMidnightHandler() { 1439a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (mMidnightHandler != null) { 1449a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mMidnightHandler.removeCallbacks(mTimeUpdater); 1459a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1469a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1479a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1489a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Add a data observer that will be called if there is a change in the data set (buttons list) 1499a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void registerDataSetObserver(DataSetObserver observer) { 1509a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (observer != null) { 1519a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson synchronized(mObservers) { 1529a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mObservers.add(observer); 1539a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1549a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1559a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1569a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1579a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Remove an existing data observer 1589a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void unregisterDataSetObserver(DataSetObserver observer) { 1599a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (observer != null) { 1609a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson synchronized(mObservers) { 1619a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mObservers.remove(observer); 1629a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1639a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1649a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1659a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1669a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Returns the amount of buttons in the menu 1679a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public int getCount() { 1689a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return mButtonNames.length; 1699a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1709a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1719a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1729a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public Object getItem(int position) { 1739a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (position < mButtonNames.length) { 1749a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return mButtonNames[position]; 1759a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1769a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return null; 1779a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1789a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1799a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public long getItemId(int position) { 1809a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Item ID is its location in the list 1819a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return position; 1829a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1839a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1849a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public boolean hasStableIds() { 1859a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return false; 1869a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 1879a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1889a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public View getView(int position, View convertView, ViewGroup parent) { 1899a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 1909a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson View v; 1919a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Check if can recycle the view 1929a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (convertView == null || 1939a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson ((Integer)convertView.getTag()).intValue() != 1949a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson R.layout.actionbar_pulldown_menu_top_button) { 1959a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson v = mInflater.inflate(R.layout.actionbar_pulldown_menu_top_button, parent, false); 1969a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Set the tag to make sure you can recycle it when you get it as a convert view 1979a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson v.setTag(new Integer(R.layout.actionbar_pulldown_menu_top_button)); 1989a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } else { 1999a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson v = convertView; 2009a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2019a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson TextView weekDay = (TextView)v.findViewById(R.id.top_button_weekday); 2029a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson TextView date = (TextView)v.findViewById(R.id.top_button_date); 2039a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2049a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson switch (mCurrentMainView) { 2059a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case ViewType.DAY: 2069a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson weekDay.setVisibility(View.VISIBLE); 2079a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson weekDay.setText(buildDayOfWeek()); 2089a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildFullDate()); 2099a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2109a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case ViewType.WEEK: 21114e82b453a95456277fa5c40189c9b253a8e487fRoboErik weekDay.setVisibility(View.VISIBLE); 21214e82b453a95456277fa5c40189c9b253a8e487fRoboErik weekDay.setText(buildWeekNum()); 2139a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildMonthYearDate()); 2149a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2159a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case ViewType.MONTH: 2169a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson weekDay.setVisibility(View.GONE); 2179a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildMonthYearDate()); 2189a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2199a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case ViewType.AGENDA: 2209a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson weekDay.setVisibility(View.VISIBLE); 2219a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson weekDay.setText(buildDayOfWeek()); 2229a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildFullDate()); 2239a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2249a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson default: 2259a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson v = null; 2269a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2279a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2289a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return v; 2299a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2309a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2319a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public int getItemViewType(int position) { 2329a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Only one kind of view is used 2339a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return BUTTON_VIEW_TYPE; 2349a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2359a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2369a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public int getViewTypeCount() { 2379a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return VIEW_TYPE_NUM; 2389a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2399a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2409a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public boolean isEmpty() { 2419a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return (mButtonNames.length == 0); 2429a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2439a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2449a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public View getDropDownView(int position, View convertView, ViewGroup parent) { 2459a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson View v = mInflater.inflate(R.layout.actionbar_pulldown_menu_button, parent, false); 2469a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson TextView viewType = (TextView)v.findViewById(R.id.button_view); 2479a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson TextView date = (TextView)v.findViewById(R.id.button_date); 2489a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson switch (position) { 2499a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case DAY_BUTTON_INDEX: 2509a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson viewType.setText(mButtonNames [DAY_BUTTON_INDEX]); 2519a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildMonthDayDate()); 2529a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2539a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case WEEK_BUTTON_INDEX: 2549a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson viewType.setText(mButtonNames [WEEK_BUTTON_INDEX]); 2559a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildWeekDate()); 2569a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2579a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case MONTH_BUTTON_INDEX: 2589a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson viewType.setText(mButtonNames [MONTH_BUTTON_INDEX]); 2599a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildMonthDate()); 2609a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2619a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson case AGENDA_BUTTON_INDEX: 2629a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson viewType.setText(mButtonNames [AGENDA_BUTTON_INDEX]); 2639a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson date.setText(buildMonthDayDate()); 2649a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2659a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson default: 2669a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson v = convertView; 2679a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson break; 2689a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2699a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return v; 2709a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2719a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2729a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Updates the current viewType 2739a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Used to match the label on the menu button with the calendar view 2749a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void setMainView(int viewType) { 2759a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mCurrentMainView = viewType; 2769a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson notifyDataChange(); 2779a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2789a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2799a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Update the date that is displayed on buttons 2809a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Used when the user selects a new day/week/month to watch 2819a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson public void setTime(long time) { 2829a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mMilliTime = time; 2839a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson notifyDataChange(); 2849a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2859a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2869a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private void notifyDataChange() { 2879a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson synchronized(mObservers) { 2889a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (!mObservers.isEmpty()) { 2899a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Iterator<DataSetObserver> i = mObservers.iterator(); 2909a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson while (i.hasNext()) { 2919a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson i.next().onChanged(); 2929a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2939a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2949a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2959a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 2969a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 2979a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Builds a string with the day of the week and the word yesterday/today/tomorrow 2989a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // before it if applicable. 2999a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String buildDayOfWeek() { 3009a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3019a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Time t = new Time(mTimeZone); 3029a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson t.set(mMilliTime); 3039a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long julianDay = Time.getJulianDay(mMilliTime,t.gmtoff); 3049a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String dayOfWeek = null; 3059a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder.setLength(0); 3069a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3079a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (julianDay == mTodayJulianDay) { 3089a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson dayOfWeek = mContext.getString(R.string.agenda_today, 3099a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3109a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_WEEKDAY, mTimeZone).toString()); 3119a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } else if (julianDay == mTodayJulianDay - 1) { 3129a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson dayOfWeek = mContext.getString(R.string.agenda_yesterday, 3139a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3149a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_WEEKDAY, mTimeZone).toString()); 3159a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } else if (julianDay == mTodayJulianDay + 1) { 3169a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson dayOfWeek = mContext.getString(R.string.agenda_tomorrow, 3179a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3189a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_WEEKDAY, mTimeZone).toString()); 3199a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } else { 3209a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson dayOfWeek = DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3219a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_WEEKDAY, mTimeZone).toString(); 3229a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3239a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return dayOfWeek.toUpperCase(); 3249a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3259a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3269a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Builds strings with different formats: 3279a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Full date: Month,day Year 3289a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Month year 3299a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Month day 3309a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Month 3319a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Week: month day-day or month day - month day 3329a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String buildFullDate() { 3339a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder.setLength(0); 3349a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String date = DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3359a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR, mTimeZone).toString(); 3369a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return date; 3379a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3389a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String buildMonthYearDate() { 3399a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder.setLength(0); 3409a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String date = DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3419a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY | 3429a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_YEAR, mTimeZone).toString(); 3439a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return date; 3449a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3459a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String buildMonthDayDate() { 3469a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder.setLength(0); 3479a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String date = DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3489a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR, mTimeZone).toString(); 3499a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return date; 3509a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3519a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String buildMonthDate() { 3529a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder.setLength(0); 3539a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String date = DateUtils.formatDateRange(mContext, mFormatter, mMilliTime, mMilliTime, 3549a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | 3559a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson DateUtils.FORMAT_NO_MONTH_DAY, mTimeZone).toString(); 3569a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return date; 3579a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3589a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson private String buildWeekDate() { 3599a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3609a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3619a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // Calculate the start of the week, taking into account the "first day of the week" 3629a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // setting. 3639a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3649a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Time t = new Time(mTimeZone); 3659a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson t.set(mMilliTime); 3669a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson int firstDayOfWeek = Utils.getFirstDayOfWeek(mContext); 3679a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson int dayOfWeek = t.weekDay; 3689a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson int diff = dayOfWeek - firstDayOfWeek; 3699a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (diff != 0) { 3709a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (diff < 0) { 3719a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson diff += 7; 3729a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3739a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson t.monthDay -= diff; 3749a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson t.normalize(true /* ignore isDst */); 3759a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3769a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3779a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson long weekStartTime = t.toMillis(true); 3788135093480db642734fb40d9627325bf9e97a8c9RoboErik // The end of the week is 6 days after the start of the week 3798135093480db642734fb40d9627325bf9e97a8c9RoboErik long weekEndTime = weekStartTime + DateUtils.WEEK_IN_MILLIS - DateUtils.DAY_IN_MILLIS; 3809a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3819a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson // If week start and end is in 2 different months, use short months names 3829a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson Time t1 = new Time(mTimeZone); 3839a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson t.set(weekEndTime); 3849a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR; 3859a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson if (t.month != t1.month) { 3869a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson flags |= DateUtils.FORMAT_ABBREV_MONTH; 3879a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3889a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 3899a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson mStringBuilder.setLength(0); 3909a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson String date = DateUtils.formatDateRange(mContext, mFormatter, weekStartTime, 3919a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson weekEndTime, flags, mTimeZone).toString(); 3929a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson return date; 3939a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson } 3949a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 39514e82b453a95456277fa5c40189c9b253a8e487fRoboErik private String buildWeekNum() { 39614e82b453a95456277fa5c40189c9b253a8e487fRoboErik int week = Utils.getWeekNumberFromTime(mMilliTime, mContext); 39714e82b453a95456277fa5c40189c9b253a8e487fRoboErik return mContext.getResources().getQuantityString(R.plurals.weekN, week, week); 39814e82b453a95456277fa5c40189c9b253a8e487fRoboErik } 39914e82b453a95456277fa5c40189c9b253a8e487fRoboErik 4009a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson} 4019a39bddb8e519b710a06d1c77257de6962ae5f72Isaac Katzenelson 402