AgendaAdapter.java revision 4d09b91abf62994cf47ccdbf7e61f60b891f9f61
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.calendar.agenda; 18 19import com.android.calendar.ColorChipView; 20import com.android.calendar.R; 21import com.android.calendar.Utils; 22 23import android.content.Context; 24import android.content.res.Resources; 25import android.database.Cursor; 26import android.provider.CalendarContract.Attendees; 27import android.text.TextUtils; 28import android.text.format.DateFormat; 29import android.text.format.DateUtils; 30import android.text.format.Time; 31import android.view.View; 32import android.view.ViewGroup; 33import android.widget.ResourceCursorAdapter; 34import android.widget.TextView; 35 36import java.util.Formatter; 37import java.util.Locale; 38 39public class AgendaAdapter extends ResourceCursorAdapter { 40 private String mNoTitleLabel; 41 private Resources mResources; 42 private int mDeclinedColor; 43 private int mStandardColor; 44 // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread. 45 private Formatter mFormatter; 46 private StringBuilder mStringBuilder; 47 private float mScale; 48 49 private int COLOR_CHIP_ALL_DAY_HEIGHT; 50 private int COLOR_CHIP_HEIGHT; 51 52 private Runnable mTZUpdater = new Runnable() { 53 @Override 54 public void run() { 55 notifyDataSetChanged(); 56 } 57 }; 58 59 static class ViewHolder { 60 61 public static final int DECLINED_RESPONSE = 0; 62 public static final int TENTATIVE_RESPONSE = 1; 63 public static final int ACCEPTED_RESPONSE = 2; 64 65 /* Event */ 66 TextView title; 67 TextView when; 68 TextView where; 69 View selectedMarker; 70 long instanceId; 71 ColorChipView colorChip; 72 long endTimeMilli; 73 boolean allDay; 74 } 75 76 public AgendaAdapter(Context context, int resource) { 77 super(context, resource, null); 78 79 mResources = context.getResources(); 80 mNoTitleLabel = mResources.getString(R.string.no_title_label); 81 mDeclinedColor = mResources.getColor(R.color.agenda_item_declined_color); 82 mStandardColor = mResources.getColor(R.color.agenda_item_standard_color); 83 mStringBuilder = new StringBuilder(50); 84 mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 85 86 COLOR_CHIP_ALL_DAY_HEIGHT = mResources.getInteger(R.integer.color_chip_all_day_height); 87 COLOR_CHIP_HEIGHT = mResources.getInteger(R.integer.color_chip_height); 88 if (mScale == 0) { 89 mScale = mResources.getDisplayMetrics().density; 90 if (mScale != 1) { 91 COLOR_CHIP_ALL_DAY_HEIGHT *= mScale; 92 COLOR_CHIP_HEIGHT *= mScale; 93 } 94 } 95 96 } 97 98 @Override 99 public void bindView(View view, Context context, Cursor cursor) { 100 ViewHolder holder = null; 101 102 // Listview may get confused and pass in a different type of view since 103 // we keep shifting data around. Not a big problem. 104 Object tag = view.getTag(); 105 if (tag instanceof ViewHolder) { 106 holder = (ViewHolder) view.getTag(); 107 } 108 109 if (holder == null) { 110 holder = new ViewHolder(); 111 view.setTag(holder); 112 holder.title = (TextView) view.findViewById(R.id.title); 113 holder.when = (TextView) view.findViewById(R.id.when); 114 holder.where = (TextView) view.findViewById(R.id.where); 115 holder.selectedMarker = view.findViewById(R.id.selected_marker); 116 holder.colorChip = (ColorChipView)view.findViewById(R.id.agenda_item_color); 117 } 118 119 holder.endTimeMilli = cursor.getLong(AgendaWindowAdapter.INDEX_END); 120 // Fade text if event was declined and set the color chip mode (response 121 boolean allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0; 122 holder.allDay = allDay; 123 int selfAttendeeStatus = cursor.getInt(AgendaWindowAdapter.INDEX_SELF_ATTENDEE_STATUS); 124 if (selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED) { 125 holder.title.setTextColor(mDeclinedColor); 126 holder.when.setTextColor(mDeclinedColor); 127 holder.where.setTextColor(mDeclinedColor); 128 holder.colorChip.setDrawStyle(ColorChipView.DRAW_CROSS_HATCHED); 129 } else { 130 holder.title.setTextColor(mStandardColor); 131 holder.when.setTextColor(mStandardColor); 132 holder.where.setTextColor(mStandardColor); 133 if (selfAttendeeStatus == Attendees.ATTENDEE_STATUS_TENTATIVE) { 134 holder.colorChip.setDrawStyle(ColorChipView.DRAW_BORDER); 135 } else { 136 holder.colorChip.setDrawStyle(ColorChipView.DRAW_FULL); 137 } 138 } 139 140 // Set the size of the color chip 141 ViewGroup.LayoutParams params = holder.colorChip.getLayoutParams(); 142 if (allDay) { 143 params.height = COLOR_CHIP_ALL_DAY_HEIGHT; 144 } else { 145 params.height = COLOR_CHIP_HEIGHT; 146 147 } 148 holder.colorChip.setLayoutParams(params); 149 150 // Deal with exchange events that the owner cannot respond to 151 int canRespond = cursor.getInt(AgendaWindowAdapter.INDEX_CAN_ORGANIZER_RESPOND); 152 if (canRespond == 0) { 153 String owner = cursor.getString(AgendaWindowAdapter.INDEX_OWNER_ACCOUNT); 154 String organizer = cursor.getString(AgendaWindowAdapter.INDEX_ORGANIZER); 155 if (owner.equals(organizer)) { 156 holder.colorChip.setDrawStyle(ColorChipView.DRAW_FULL); 157 holder.title.setTextColor(mStandardColor); 158 holder.when.setTextColor(mStandardColor); 159 holder.where.setTextColor(mStandardColor); 160 } 161 } 162 163 TextView title = holder.title; 164 TextView when = holder.when; 165 TextView where = holder.where; 166 167 holder.instanceId = cursor.getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID); 168 169 /* Calendar Color */ 170 int color = cursor.getInt(AgendaWindowAdapter.INDEX_COLOR); 171 holder.colorChip.setColor(color); 172 173 // What 174 String titleString = cursor.getString(AgendaWindowAdapter.INDEX_TITLE); 175 if (titleString == null || titleString.length() == 0) { 176 titleString = mNoTitleLabel; 177 } 178 title.setText(titleString); 179 180 // When 181 long begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN); 182 long end = cursor.getLong(AgendaWindowAdapter.INDEX_END); 183 int flags = 0; 184 String whenString; 185 // It's difficult to update all the adapters so just query this each 186 // time we need to build the view. 187 String tz = Utils.getTimeZone(context, mTZUpdater);; 188 if (allDay) { 189 tz = Time.TIMEZONE_UTC; 190 } else { 191 flags = DateUtils.FORMAT_SHOW_TIME; 192 } 193 if (DateFormat.is24HourFormat(context)) { 194 flags |= DateUtils.FORMAT_24HOUR; 195 } 196 mStringBuilder.setLength(0); 197 whenString = DateUtils.formatDateRange(context, mFormatter, begin, end, flags, tz) 198 .toString(); 199 when.setText(whenString); 200 201 /* Recurring event icon is removed 202 String rrule = cursor.getString(AgendaWindowAdapter.INDEX_RRULE); 203 if (!TextUtils.isEmpty(rrule)) { 204 when.setCompoundDrawablesWithIntrinsicBounds(null, null, 205 context.getResources().getDrawable(R.drawable.ic_repeat_dark), null); 206 when.setCompoundDrawablePadding(5); 207 } else { 208 when.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); 209 } */ 210 211 /* 212 // Repeating info 213 View repeatContainer = view.findViewById(R.id.repeat_icon); 214 String rrule = cursor.getString(AgendaWindowAdapter.INDEX_RRULE); 215 if (!TextUtils.isEmpty(rrule)) { 216 repeatContainer.setVisibility(View.VISIBLE); 217 } else { 218 repeatContainer.setVisibility(View.GONE); 219 } 220 */ 221 222 /* 223 // Reminder 224 boolean hasAlarm = cursor.getInt(AgendaWindowAdapter.INDEX_HAS_ALARM) != 0; 225 if (hasAlarm) { 226 updateReminder(view, context, begin, cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID)); 227 } 228 */ 229 230 // Where 231 String whereString = cursor.getString(AgendaWindowAdapter.INDEX_EVENT_LOCATION); 232 if (whereString != null && whereString.length() > 0) { 233 where.setVisibility(View.VISIBLE); 234 where.setText(whereString); 235 } else { 236 where.setVisibility(View.GONE); 237 } 238 } 239 240 /* 241 public static void updateReminder(View view, Context context, long begin, long eventId) { 242 ContentResolver cr = context.getContentResolver(); 243 Uri uri = Reminders.CONTENT_URI; 244 String where = String.format(REMINDERS_WHERE, eventId); 245 246 Cursor remindersCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null); 247 if (remindersCursor != null) { 248 LayoutInflater inflater = 249 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 250 LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminders_container); 251 parent.removeAllViews(); 252 while (remindersCursor.moveToNext()) { 253 int alarm = remindersCursor.getInt(REMINDERS_INDEX_MINUTES); 254 String before = EditEvent.constructReminderLabel(context, alarm, true); 255 LinearLayout reminderItem = (LinearLayout) 256 inflater.inflate(R.layout.agenda_reminder_item, null); 257 TextView reminderItemText = (TextView) reminderItem.findViewById(R.id.reminder); 258 reminderItemText.setText(before); 259 parent.addView(reminderItem); 260 } 261 } 262 remindersCursor.close(); 263 } 264 */ 265} 266 267