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