AgendaAdapter.java revision d002bd24937d9c0823f283884961adc2c902558e
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.widget.ResourceCursorAdapter;
33import android.widget.TextView;
34
35import java.util.Formatter;
36import java.util.Locale;
37
38public class AgendaAdapter extends ResourceCursorAdapter {
39    private String mNoTitleLabel;
40    private Resources mResources;
41    private int mDeclinedColor;
42    // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread.
43    private Formatter mFormatter;
44    private StringBuilder mStringBuilder;
45
46    private Runnable mTZUpdater = new Runnable() {
47        @Override
48        public void run() {
49            notifyDataSetChanged();
50        }
51    };
52
53    static class ViewHolder {
54
55        public static final int DECLINED_RESPONSE = 0;
56        public static final int TENTATIVE_RESPONSE = 1;
57        public static final int ACCEPTED_RESPONSE = 2;
58
59        int overLayColor; // Used by AgendaItemView to gray out the entire item if so desired
60
61        /* Event */
62        TextView title;
63        TextView when;
64        TextView where;
65        View selectedMarker;
66        long instanceId;
67        ColorChipView colorChip;
68    }
69
70    public AgendaAdapter(Context context, int resource) {
71        super(context, resource, null);
72
73        mResources = context.getResources();
74        mNoTitleLabel = mResources.getString(R.string.no_title_label);
75        mDeclinedColor = mResources.getColor(R.drawable.agenda_item_declined);
76        mStringBuilder = new StringBuilder(50);
77        mFormatter = new Formatter(mStringBuilder, Locale.getDefault());
78    }
79
80    @Override
81    public void bindView(View view, Context context, Cursor cursor) {
82        ViewHolder holder = null;
83
84        // Listview may get confused and pass in a different type of view since
85        // we keep shifting data around. Not a big problem.
86        Object tag = view.getTag();
87        if (tag instanceof ViewHolder) {
88            holder = (ViewHolder) view.getTag();
89        }
90
91        if (holder == null) {
92            holder = new ViewHolder();
93            view.setTag(holder);
94            holder.title = (TextView) view.findViewById(R.id.title);
95            holder.when = (TextView) view.findViewById(R.id.when);
96            holder.where = (TextView) view.findViewById(R.id.where);
97            holder.selectedMarker = view.findViewById(R.id.selected_marker);
98            holder.colorChip = (ColorChipView)view.findViewById(R.id.agenda_item_color);
99        }
100
101        // Fade text if event was declined and set the color chip mode (response
102        int selfAttendeeStatus = cursor.getInt(AgendaWindowAdapter.INDEX_SELF_ATTENDEE_STATUS);
103        if (selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED) {
104            holder.overLayColor = mDeclinedColor;
105            holder.colorChip.setDrawStyle(ColorChipView.DRAW_CROSS_HATCHED);
106        } else {
107            holder.overLayColor = 0;
108            if (selfAttendeeStatus == Attendees.ATTENDEE_STATUS_TENTATIVE) {
109                holder.colorChip.setDrawStyle(ColorChipView.DRAW_BORDER);
110            } else {
111                holder.colorChip.setDrawStyle(ColorChipView.DRAW_FULL);
112            }
113        }
114
115        // Deal with exchange events that the owner cannot respond to
116        int canRespond = cursor.getInt(AgendaWindowAdapter.INDEX_CAN_ORGANIZER_RESPOND);
117        if (canRespond == 0) {
118            String owner = cursor.getString(AgendaWindowAdapter.INDEX_OWNER_ACCOUNT);
119            String organizer = cursor.getString(AgendaWindowAdapter.INDEX_ORGANIZER);
120            if (owner.equals(organizer)) {
121                holder.colorChip.setDrawStyle(ColorChipView.DRAW_FULL);
122            }
123        }
124
125        TextView title = holder.title;
126        TextView when = holder.when;
127        TextView where = holder.where;
128
129        holder.instanceId = cursor.getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID);
130
131        /* Calendar Color */
132        int color = cursor.getInt(AgendaWindowAdapter.INDEX_COLOR);
133        holder.colorChip.setColor(color);
134
135        // What
136        String titleString = cursor.getString(AgendaWindowAdapter.INDEX_TITLE);
137        if (titleString == null || titleString.length() == 0) {
138            titleString = mNoTitleLabel;
139        }
140        title.setText(titleString);
141        title.setTextColor(color);
142
143        // When
144        long begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN);
145        long end = cursor.getLong(AgendaWindowAdapter.INDEX_END);
146        boolean allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0;
147        int flags = 0;
148        String whenString;
149        // It's difficult to update all the adapters so just query this each
150        // time we need to build the view.
151        String tz = Utils.getTimeZone(context, mTZUpdater);;
152        if (allDay) {
153            tz = Time.TIMEZONE_UTC;
154        } else {
155            flags = DateUtils.FORMAT_SHOW_TIME;
156        }
157        if (DateFormat.is24HourFormat(context)) {
158            flags |= DateUtils.FORMAT_24HOUR;
159        }
160        mStringBuilder.setLength(0);
161        whenString = DateUtils.formatDateRange(context, mFormatter, begin, end, flags, tz)
162                .toString();
163        when.setText(whenString);
164
165        String rrule = cursor.getString(AgendaWindowAdapter.INDEX_RRULE);
166        if (!TextUtils.isEmpty(rrule)) {
167            when.setCompoundDrawablesWithIntrinsicBounds(null, null,
168                    context.getResources().getDrawable(R.drawable.ic_repeat_dark), null);
169            when.setCompoundDrawablePadding(5);
170        } else {
171            when.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
172        }
173
174        /*
175        // Repeating info
176        View repeatContainer = view.findViewById(R.id.repeat_icon);
177        String rrule = cursor.getString(AgendaWindowAdapter.INDEX_RRULE);
178        if (!TextUtils.isEmpty(rrule)) {
179            repeatContainer.setVisibility(View.VISIBLE);
180        } else {
181            repeatContainer.setVisibility(View.GONE);
182        }
183        */
184
185        /*
186        // Reminder
187        boolean hasAlarm = cursor.getInt(AgendaWindowAdapter.INDEX_HAS_ALARM) != 0;
188        if (hasAlarm) {
189            updateReminder(view, context, begin, cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID));
190        }
191        */
192
193        // Where
194        String whereString = cursor.getString(AgendaWindowAdapter.INDEX_EVENT_LOCATION);
195        if (whereString != null && whereString.length() > 0) {
196            where.setVisibility(View.VISIBLE);
197            where.setText(whereString);
198        } else {
199            where.setVisibility(View.GONE);
200        }
201    }
202
203    /*
204    public static void updateReminder(View view, Context context, long begin, long eventId) {
205        ContentResolver cr = context.getContentResolver();
206        Uri uri = Reminders.CONTENT_URI;
207        String where = String.format(REMINDERS_WHERE, eventId);
208
209        Cursor remindersCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null);
210        if (remindersCursor != null) {
211            LayoutInflater inflater =
212                    (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
213            LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminders_container);
214            parent.removeAllViews();
215            while (remindersCursor.moveToNext()) {
216                int alarm = remindersCursor.getInt(REMINDERS_INDEX_MINUTES);
217                String before = EditEvent.constructReminderLabel(context, alarm, true);
218                LinearLayout reminderItem = (LinearLayout)
219                        inflater.inflate(R.layout.agenda_reminder_item, null);
220                TextView reminderItemText = (TextView) reminderItem.findViewById(R.id.reminder);
221                reminderItemText.setText(before);
222                parent.addView(reminderItem);
223            }
224        }
225        remindersCursor.close();
226    }
227    */
228}
229
230