Home | History | Annotate | Download | only in agenda
      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 
     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
    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