AgendaAdapter.java revision 9a88873f9ec97b47aaaaae47208d22b3998b8e99
1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/*
2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2007 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
1700b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangpackage com.android.calendar.agenda;
1800b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang
1900b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangimport com.android.calendar.R;
209a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport com.android.calendar.Utils;
21146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context;
23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.res.Resources;
24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor;
25146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.provider.Calendar.Attendees;
26146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateFormat;
27146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateUtils;
289a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport android.text.format.Time;
29146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.View;
30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.ResourceCursorAdapter;
31146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.TextView;
32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
3313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Formatter;
3413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Locale;
3513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan
36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class AgendaAdapter extends ResourceCursorAdapter {
3798ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan    private String mNoTitleLabel;
38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private Resources mResources;
39b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan    private int mDeclinedColor;
4023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan    // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread.
4123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan    private Formatter mFormatter;
4213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    private StringBuilder mStringBuilder;
43b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
449a88873f9ec97b47aaaaae47208d22b3998b8e99Erik    private Runnable mTZUpdater = new Runnable() {
459a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        @Override
469a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        public void run() {
479a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            notifyDataSetChanged();
489a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        }
499a88873f9ec97b47aaaaae47208d22b3998b8e99Erik    };
509a88873f9ec97b47aaaaae47208d22b3998b8e99Erik
51b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan    static class ViewHolder {
52b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        int overLayColor; // Used by AgendaItemView to gray out the entire item if so desired
53d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan
54d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        /* Event */
55d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        TextView title;
56d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        TextView when;
57d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        TextView where;
58b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        int calendarColor; // Used by AgendaItemView to color the vertical stripe
59d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan    }
60146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
61146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public AgendaAdapter(Context context, int resource) {
62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        super(context, resource, null);
639a88873f9ec97b47aaaaae47208d22b3998b8e99Erik
64146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mResources = context.getResources();
65d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        mNoTitleLabel = mResources.getString(R.string.no_title_label);
66b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        mDeclinedColor = mResources.getColor(R.drawable.agenda_item_declined);
6713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mStringBuilder = new StringBuilder(50);
6813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mFormatter = new Formatter(mStringBuilder, Locale.getDefault());
69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
70d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan
71146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void bindView(View view, Context context, Cursor cursor) {
7313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        ViewHolder holder = null;
7413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan
7513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        // Listview may get confused and pass in a different type of view since
7613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        // we keep shifting data around. Not a big problem.
7713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        Object tag = view.getTag();
7813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        if (tag instanceof ViewHolder) {
7913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            holder = (ViewHolder) view.getTag();
8013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        }
81d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan
82d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        if (holder == null) {
83d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan            holder = new ViewHolder();
84d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan            view.setTag(holder);
85d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan            holder.title = (TextView) view.findViewById(R.id.title);
86d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan            holder.when = (TextView) view.findViewById(R.id.when);
87d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan            holder.where = (TextView) view.findViewById(R.id.where);
88d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        }
89d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan
90146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Fade text if event was declined.
9113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        int selfAttendeeStatus = cursor.getInt(AgendaWindowAdapter.INDEX_SELF_ATTENDEE_STATUS);
92b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        if (selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED) {
93b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan            holder.overLayColor = mDeclinedColor;
94b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        } else {
95b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan            holder.overLayColor = 0;
96b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        }
97d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan
98d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        TextView title = holder.title;
99d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        TextView when = holder.when;
100d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan        TextView where = holder.where;
101d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan
102b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        /* Calendar Color */
10313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        int color = cursor.getInt(AgendaWindowAdapter.INDEX_COLOR);
104b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan        holder.calendarColor = color;
105146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
106146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // What
10713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        String titleString = cursor.getString(AgendaWindowAdapter.INDEX_TITLE);
108146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (titleString == null || titleString.length() == 0) {
109d06a1bf1cf81b818b3e3dc0f81b7cb07382425f2Michael Chan            titleString = mNoTitleLabel;
110146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
111146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        title.setText(titleString);
112146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        title.setTextColor(color);
113b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
114146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // When
11513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        long begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN);
11613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        long end = cursor.getLong(AgendaWindowAdapter.INDEX_END);
11713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        boolean allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0;
1189a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        int flags = 0;
119146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        String whenString;
1209a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        // It's difficult to update all the adapters so just query this each
1219a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        // time we need to build the view.
1229a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        String tz = Utils.getTimeZone(context, mTZUpdater);;
123146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (allDay) {
1249a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            tz = Time.TIMEZONE_UTC;
125146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
126146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            flags = DateUtils.FORMAT_SHOW_TIME;
127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (DateFormat.is24HourFormat(context)) {
129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            flags |= DateUtils.FORMAT_24HOUR;
130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
13113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mStringBuilder.setLength(0);
1329a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        whenString = DateUtils.formatDateRange(context, mFormatter, begin, end, flags, tz)
1339a88873f9ec97b47aaaaae47208d22b3998b8e99Erik                .toString();
134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        when.setText(whenString);
135b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
13613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        String rrule = cursor.getString(AgendaWindowAdapter.INDEX_RRULE);
137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (rrule != null) {
138b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan            when.setCompoundDrawablesWithIntrinsicBounds(null, null,
139146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    context.getResources().getDrawable(R.drawable.ic_repeat_dark), null);
140146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            when.setCompoundDrawablePadding(5);
141146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
142146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            when.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
144b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
145146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        /*
146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Repeating info
147146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        View repeatContainer = view.findViewById(R.id.repeat_icon);
1484484b04707d5570a6de4a5a4b228a9bb273bbab7Michael Chan        String rrule = cursor.getString(AgendaWindowAdapter.INDEX_RRULE);
149146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (rrule != null) {
150146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            repeatContainer.setVisibility(View.VISIBLE);
151146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
152146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            repeatContainer.setVisibility(View.GONE);
153146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
154146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        */
155b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
156146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        /*
157146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Reminder
1584484b04707d5570a6de4a5a4b228a9bb273bbab7Michael Chan        boolean hasAlarm = cursor.getInt(AgendaWindowAdapter.INDEX_HAS_ALARM) != 0;
159146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (hasAlarm) {
1604484b04707d5570a6de4a5a4b228a9bb273bbab7Michael Chan            updateReminder(view, context, begin, cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID));
161146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
162146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        */
163b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
164146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Where
16513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        String whereString = cursor.getString(AgendaWindowAdapter.INDEX_EVENT_LOCATION);
166146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (whereString != null && whereString.length() > 0) {
167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            where.setVisibility(View.VISIBLE);
168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            where.setText(whereString);
169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            where.setVisibility(View.GONE);
171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
172146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
173146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
174146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /*
175146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static void updateReminder(View view, Context context, long begin, long eventId) {
176146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ContentResolver cr = context.getContentResolver();
177146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Uri uri = Reminders.CONTENT_URI;
178146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        String where = String.format(REMINDERS_WHERE, eventId);
179b3866cbd69a2688d0cb165f18f133e73f0243c8eMichael Chan
180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Cursor remindersCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null);
181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (remindersCursor != null) {
182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            LayoutInflater inflater =
183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminders_container);
185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            parent.removeAllViews();
186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            while (remindersCursor.moveToNext()) {
187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                int alarm = remindersCursor.getInt(REMINDERS_INDEX_MINUTES);
188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                String before = EditEvent.constructReminderLabel(context, alarm, true);
189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                LinearLayout reminderItem = (LinearLayout)
190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        inflater.inflate(R.layout.agenda_reminder_item, null);
191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                TextView reminderItemText = (TextView) reminderItem.findViewById(R.id.reminder);
192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                reminderItemText.setText(before);
193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                parent.addView(reminderItem);
194146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        remindersCursor.close();
197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    */
199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project}
200146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
201