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