AgendaByDayAdapter.java revision dad908b741d7d0a7e4a573030baeb74319ad9411
1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/* 2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License. 6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at 7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and 14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License. 15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 17146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpackage com.android.calendar; 18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 19146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context; 20146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor; 21146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateUtils; 22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time; 23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.LayoutInflater; 24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.View; 25146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.ViewGroup; 26146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.BaseAdapter; 27146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.TextView; 28146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 29dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chanimport com.android.calendar.AgendaWindowAdapter.DayAdapterInfo; 30dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan 31146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.ArrayList; 3213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Formatter; 33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.Iterator; 34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.LinkedList; 3513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Locale; 36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 37146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class AgendaByDayAdapter extends BaseAdapter { 38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int TYPE_DAY = 0; 39146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static final int TYPE_MEETING = 1; 4013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static final int TYPE_LAST = 2; 41146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 42146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private final Context mContext; 43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private final AgendaAdapter mAgendaAdapter; 44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private final LayoutInflater mInflater; 45146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private ArrayList<RowInfo> mRowInfo; 46146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private int mTodayJulianDay; 4713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private Time mTmpTime = new Time(); 4823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread. 4923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan private Formatter mFormatter; 5013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan private StringBuilder mStringBuilder; 51146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 5213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan static class ViewHolder { 5313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView dateView; 5413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 5513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 5613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan public AgendaByDayAdapter(Context context) { 57146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mContext = context; 5813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mAgendaAdapter = new AgendaAdapter(context, R.layout.agenda_item); 5913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 6013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder = new StringBuilder(50); 6113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 63146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 64146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getCount() { 65146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo != null) { 66146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mRowInfo.size(); 67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mAgendaAdapter.getCount(); 69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 70146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 71146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public Object getItem(int position) { 72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo != null) { 73146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(position); 74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mType == TYPE_DAY) { 75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return row; 76146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 77146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mAgendaAdapter.getItem(row.mData); 78146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 79146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 80146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mAgendaAdapter.getItem(position); 81146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 82146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 83146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public long getItemId(int position) { 84146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo != null) { 85146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(position); 86146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mType == TYPE_DAY) { 87146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return position; 88146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 89146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mAgendaAdapter.getItemId(row.mData); 90146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 91146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 92146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mAgendaAdapter.getItemId(position); 93146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 94146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 95146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 96146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getViewTypeCount() { 97146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return TYPE_LAST; 98146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 99146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 100146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 101146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getItemViewType(int position) { 102146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mRowInfo != null && mRowInfo.size() > position ? 103146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mRowInfo.get(position).mType : TYPE_DAY; 104146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 105146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 106146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public View getView(int position, View convertView, ViewGroup parent) { 107146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if ((mRowInfo == null) || (position > mRowInfo.size())) { 108146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If we have no row info, mAgendaAdapter returns the view. 109146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return mAgendaAdapter.getView(position, convertView, parent); 110146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 111146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 112146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(position); 113146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mType == TYPE_DAY) { 11413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan ViewHolder holder = null; 11513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan View agendaDayView = null; 11613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if ((convertView != null) && (convertView.getTag() != null)) { 11713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // Listview may get confused and pass in a different type of 11813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan // view since we keep shifting data around. Not a big problem. 11913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Object tag = convertView.getTag(); 12013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (tag instanceof ViewHolder) { 12113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan agendaDayView = convertView; 12213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan holder = (ViewHolder) tag; 12313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 12413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 12513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 12613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (holder == null) { 127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Create a new AgendaView with a ViewHolder for fast access to 128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // views w/o calling findViewById() 129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project holder = new ViewHolder(); 130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project agendaDayView = mInflater.inflate(R.layout.agenda_day, parent, false); 131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project holder.dateView = (TextView) agendaDayView.findViewById(R.id.date); 132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project agendaDayView.setTag(holder); 133146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Re-use the member variable "mTime" which is set to the local timezone. 13613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan Time date = mTmpTime; 137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long millis = date.setJulianDay(row.mData); 1383cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project int flags = DateUtils.FORMAT_SHOW_YEAR 1393cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project | DateUtils.FORMAT_SHOW_DATE; 14013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 14113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan mStringBuilder.setLength(0); 14223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan String dateViewText; 143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mData == mTodayJulianDay) { 14423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan dateViewText = mContext.getString(R.string.agenda_today, DateUtils.formatDateRange( 14523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan mContext, mFormatter, millis, millis, flags).toString()); 146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 1473cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project flags |= DateUtils.FORMAT_SHOW_WEEKDAY; 14823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan dateViewText = DateUtils.formatDateRange(mContext, mFormatter, millis, millis, 14923f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan flags).toString(); 150146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 1513cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project 15223f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan if (AgendaWindowAdapter.BASICLOG) { 15323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan dateViewText += " P:" + position; 15423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan } 15523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan holder.dateView.setText(dateViewText); 1563cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project 157146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return agendaDayView; 158146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else if (row.mType == TYPE_MEETING) { 15913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan View x = mAgendaAdapter.getView(row.mData, convertView, parent); 16013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan TextView y = ((AgendaAdapter.ViewHolder) x.getTag()).title; 16124ed7b9e8a54f9aea703f62b64c53b119ebf4680Michael Chan y.setText(y.getText()); 16213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return x; 163146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 164146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Error 165146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project throw new IllegalStateException("Unknown event type:" + row.mType); 166146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public void clearDayHeaderInfo() { 170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mRowInfo = null; 171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 172146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 173dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan public void changeCursor(DayAdapterInfo info) { 174dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan calculateDays(info); 175dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan mAgendaAdapter.changeCursor(info.cursor); 17613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 17713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan 178dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan public void calculateDays(DayAdapterInfo dayAdapterInfo) { 179dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan Cursor cursor = dayAdapterInfo.cursor; 180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project ArrayList<RowInfo> rowInfo = new ArrayList<RowInfo>(); 181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int prevStartDay = -1; 182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Time time = new Time(); 183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long now = System.currentTimeMillis(); 184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project time.set(now); 185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mTodayJulianDay = Time.getJulianDay(now, time.gmtoff); 186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project LinkedList<MultipleDayInfo> multipleDayList = new LinkedList<MultipleDayInfo>(); 187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (int position = 0; cursor.moveToNext(); position++) { 18813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan boolean allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0; 18913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int startDay = cursor.getInt(AgendaWindowAdapter.INDEX_START_DAY); 190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 191dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan // Skip over the days outside of the adapter's range 192dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan startDay = Math.max(startDay, dayAdapterInfo.start); 193dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan 194146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (startDay != prevStartDay) { 195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Check if we skipped over any empty days 196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (prevStartDay == -1) { 197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_DAY, startDay)); 198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If there are any multiple-day events that span the empty 200146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // range of days, then create day headers and events for 201146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // those multiple-day events. 202146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project boolean dayHeaderAdded = false; 203146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (int currentDay = prevStartDay + 1; currentDay <= startDay; currentDay++) { 204146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dayHeaderAdded = false; 205146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Iterator<MultipleDayInfo> iter = multipleDayList.iterator(); 206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project while (iter.hasNext()) { 207146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project MultipleDayInfo info = iter.next(); 208146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If this event has ended then remove it from the 209146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // list. 210146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (info.mEndDay < currentDay) { 211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project iter.remove(); 212146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project continue; 213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 214146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 215146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If this is the first event for the day, then 216146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // insert a day header. 217146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (!dayHeaderAdded) { 218146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_DAY, currentDay)); 219146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dayHeaderAdded = true; 220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 221146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_MEETING, info.mPosition)); 222146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 225146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the day header was not added for the start day, then 226146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // add it now. 227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (!dayHeaderAdded) { 228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_DAY, startDay)); 229146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 230146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 231146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project prevStartDay = startDay; 232146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 233146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 234146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Add in the event for this cursor position 235146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_MEETING, position)); 236146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If this event spans multiple days, then add it to the multipleDay 238146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // list. 23913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int endDay = cursor.getInt(AgendaWindowAdapter.INDEX_END_DAY); 240dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan 241dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan // Skip over the days outside of the adapter's range 242dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan endDay = Math.min(endDay, dayAdapterInfo.end); 243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (endDay > startDay) { 244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project multipleDayList.add(new MultipleDayInfo(position, endDay)); 245146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 246146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 247146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 248146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // There are no more cursor events but we might still have multiple-day 249146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // events left. So create day headers and events for those. 250146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (prevStartDay > 0) { 251dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan for (int currentDay = prevStartDay + 1; currentDay <= dayAdapterInfo.end; 252dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan currentDay++) { 253146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project boolean dayHeaderAdded = false; 254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Iterator<MultipleDayInfo> iter = multipleDayList.iterator(); 255146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project while (iter.hasNext()) { 256146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project MultipleDayInfo info = iter.next(); 257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If this event has ended then remove it from the 258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // list. 259146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (info.mEndDay < currentDay) { 260146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project iter.remove(); 261146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project continue; 262146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 263146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If this is the first event for the day, then 265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // insert a day header. 266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (!dayHeaderAdded) { 267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_DAY, currentDay)); 268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project dayHeaderAdded = true; 269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project rowInfo.add(new RowInfo(TYPE_MEETING, info.mPosition)); 271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 273146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 274146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mRowInfo = rowInfo; 275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 276146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 277146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static class RowInfo { 278146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // mType is either a day header (TYPE_DAY) or an event (TYPE_MEETING) 279146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project final int mType; 280146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If mType is TYPE_DAY, then mData is the Julian day. Otherwise 282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // mType is TYPE_MEETING and mData is the cursor position. 283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project final int mData; 284146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 285146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo(int type, int data) { 286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mType = type; 287146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mData = data; 288146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 289146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 290146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 291146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private static class MultipleDayInfo { 292146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project final int mPosition; 293146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project final int mEndDay; 294146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 295146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project MultipleDayInfo(int position, int endDay) { 296146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mPosition = position; 297146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mEndDay = endDay; 298146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 299146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 300146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 301146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 302146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Searches for the day that matches the given Time object and returns the 303146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * list position of that day. If there are no events for that day, then it 304146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * finds the nearest day (before or after) that has events and returns the 305146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * list position for that day. 306146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 307146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param time the date to search for 308146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the cursor position of the first event for that date, or zero 309146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * if no match was found 310146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 311146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int findDayPositionNearestTime(Time time) { 312146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo == null) { 313146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return 0; 314146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 315146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long millis = time.toMillis(false /* use isDst */); 316146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int julianDay = Time.getJulianDay(millis, time.gmtoff); 317146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int minDistance = 1000; // some big number 318146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int minIndex = 0; 319146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int len = mRowInfo.size(); 320146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (int index = 0; index < len; index++) { 321146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(index); 322146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mType == TYPE_DAY) { 323146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int distance = Math.abs(julianDay - row.mData); 324146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (distance == 0) { 325146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return index; 326146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 327146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (distance < minDistance) { 328146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project minDistance = distance; 329146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project minIndex = index; 330146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 331146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 332146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 333146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 334146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // We didn't find an exact match so take the nearest day that had 335146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // events. 336146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return minIndex; 337146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 338146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 339146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 340146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Finds the Julian day containing the event at the given position. 341146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 342146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param position the list position of an event 343146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the Julian day containing that event 344146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 345146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int findJulianDayFromPosition(int position) { 346146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo == null || position < 0) { 347146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return 0; 348146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 349146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 350146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project int len = mRowInfo.size(); 351146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (position >= len) return 0; // no row info at this position 352146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 353146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project for (int index = position; index >= 0; index--) { 354146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(index); 355146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mType == TYPE_DAY) { 356146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return row.mData; 357146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 358146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 359146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return 0; 360146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 361146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 362146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project /** 363146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Converts a list position to a cursor position. The list contains 364146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * day headers as well as events. The cursor contains only events. 365146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 366146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @param listPos the list position of an event 367146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * @return the corresponding cursor position of that event 368146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 369146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public int getCursorPosition(int listPos) { 370146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo != null && listPos >= 0) { 371146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(listPos); 372146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (row.mType == TYPE_MEETING) { 373146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return row.mData; 37413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } else { 37513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan int nextPos = listPos + 1; 37613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (nextPos < mRowInfo.size()) { 37713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan nextPos = getCursorPosition(nextPos); 37813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan if (nextPos >= 0) { 37913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return -nextPos; 38013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 38113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan } 382146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 383146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 38413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan return Integer.MIN_VALUE; 385146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 386146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 387146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 388146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public boolean areAllItemsEnabled() { 389146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return false; 390146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 391146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 392146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 393146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public boolean isEnabled(int position) { 394146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mRowInfo != null && position < mRowInfo.size()) { 395146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project RowInfo row = mRowInfo.get(position); 396146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return row.mType == TYPE_MEETING; 397146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 398146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return true; 399146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 400146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 401