Home | History | Annotate | Download | only in calendar
      1 /*
      2  * Copyright (C) 2006 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;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.text.format.DateUtils;
     22 import android.text.format.Time;
     23 import android.util.TimeFormatException;
     24 
     25 import com.android.calendarcommon2.EventRecurrence;
     26 
     27 import java.util.Calendar;
     28 
     29 public class EventRecurrenceFormatter
     30 {
     31 
     32     private static int[] mMonthRepeatByDayOfWeekIds;
     33     private static String[][] mMonthRepeatByDayOfWeekStrs;
     34 
     35     public static String getRepeatString(Context context, Resources r, EventRecurrence recurrence,
     36             boolean includeEndString) {
     37         String endString = "";
     38         if (includeEndString) {
     39             StringBuilder sb = new StringBuilder();
     40             if (recurrence.until != null) {
     41                 try {
     42                     Time t = new Time();
     43                     t.parse(recurrence.until);
     44                     final String dateStr = DateUtils.formatDateTime(context,
     45                             t.toMillis(false), DateUtils.FORMAT_NUMERIC_DATE);
     46                     sb.append(r.getString(R.string.endByDate, dateStr));
     47                 } catch (TimeFormatException e) {
     48                 }
     49             }
     50 
     51             if (recurrence.count > 0) {
     52                 sb.append(r.getQuantityString(R.plurals.endByCount, recurrence.count,
     53                         recurrence.count));
     54             }
     55             endString = sb.toString();
     56         }
     57 
     58         // TODO Implement "Until" portion of string, as well as custom settings
     59         int interval = recurrence.interval <= 1 ? 1 : recurrence.interval;
     60         switch (recurrence.freq) {
     61             case EventRecurrence.DAILY:
     62                 return r.getQuantityString(R.plurals.daily, interval, interval) + endString;
     63             case EventRecurrence.WEEKLY: {
     64                 if (recurrence.repeatsOnEveryWeekDay()) {
     65                     return r.getString(R.string.every_weekday) + endString;
     66                 } else {
     67                     String string;
     68 
     69                     int dayOfWeekLength = DateUtils.LENGTH_MEDIUM;
     70                     if (recurrence.bydayCount == 1) {
     71                         dayOfWeekLength = DateUtils.LENGTH_LONG;
     72                     }
     73 
     74                     StringBuilder days = new StringBuilder();
     75 
     76                     // Do one less iteration in the loop so the last element is added out of the
     77                     // loop. This is done so the comma is not placed after the last item.
     78 
     79                     if (recurrence.bydayCount > 0) {
     80                         int count = recurrence.bydayCount - 1;
     81                         for (int i = 0 ; i < count ; i++) {
     82                             days.append(dayToString(recurrence.byday[i], dayOfWeekLength));
     83                             days.append(", ");
     84                         }
     85                         days.append(dayToString(recurrence.byday[count], dayOfWeekLength));
     86 
     87                         string = days.toString();
     88                     } else {
     89                         // There is no "BYDAY" specifier, so use the day of the
     90                         // first event.  For this to work, the setStartDate()
     91                         // method must have been used by the caller to set the
     92                         // date of the first event in the recurrence.
     93                         if (recurrence.startDate == null) {
     94                             return null;
     95                         }
     96 
     97                         int day = EventRecurrence.timeDay2Day(recurrence.startDate.weekDay);
     98                         string = dayToString(day, DateUtils.LENGTH_LONG);
     99                     }
    100                     return r.getQuantityString(R.plurals.weekly, interval, interval, string)
    101                             + endString;
    102                 }
    103             }
    104             case EventRecurrence.MONTHLY: {
    105                 if (recurrence.bydayCount == 1) {
    106                     int weekday = recurrence.startDate.weekDay;
    107                     // Cache this stuff so we won't have to redo work again later.
    108                     cacheMonthRepeatStrings(r, weekday);
    109                     int dayNumber = (recurrence.startDate.monthDay - 1) / 7;
    110                     StringBuilder sb = new StringBuilder();
    111                     sb.append(r.getString(R.string.monthly));
    112                     sb.append(" (");
    113                     sb.append(mMonthRepeatByDayOfWeekStrs[weekday][dayNumber]);
    114                     sb.append(")");
    115                     sb.append(endString);
    116                     return sb.toString();
    117                 }
    118                 return r.getString(R.string.monthly) + endString;
    119             }
    120             case EventRecurrence.YEARLY:
    121                 return r.getString(R.string.yearly_plain) + endString;
    122         }
    123 
    124         return null;
    125     }
    126 
    127     private static void cacheMonthRepeatStrings(Resources r, int weekday) {
    128         if (mMonthRepeatByDayOfWeekIds == null) {
    129             mMonthRepeatByDayOfWeekIds = new int[7];
    130             mMonthRepeatByDayOfWeekIds[0] = R.array.repeat_by_nth_sun;
    131             mMonthRepeatByDayOfWeekIds[1] = R.array.repeat_by_nth_mon;
    132             mMonthRepeatByDayOfWeekIds[2] = R.array.repeat_by_nth_tues;
    133             mMonthRepeatByDayOfWeekIds[3] = R.array.repeat_by_nth_wed;
    134             mMonthRepeatByDayOfWeekIds[4] = R.array.repeat_by_nth_thurs;
    135             mMonthRepeatByDayOfWeekIds[5] = R.array.repeat_by_nth_fri;
    136             mMonthRepeatByDayOfWeekIds[6] = R.array.repeat_by_nth_sat;
    137         }
    138         if (mMonthRepeatByDayOfWeekStrs == null) {
    139             mMonthRepeatByDayOfWeekStrs = new String[7][];
    140         }
    141         if (mMonthRepeatByDayOfWeekStrs[weekday] == null) {
    142             mMonthRepeatByDayOfWeekStrs[weekday] =
    143                     r.getStringArray(mMonthRepeatByDayOfWeekIds[weekday]);
    144         }
    145     }
    146 
    147     /**
    148      * Converts day of week to a String.
    149      * @param day a EventRecurrence constant
    150      * @return day of week as a string
    151      */
    152     private static String dayToString(int day, int dayOfWeekLength) {
    153         return DateUtils.getDayOfWeekString(dayToUtilDay(day), dayOfWeekLength);
    154     }
    155 
    156     /**
    157      * Converts EventRecurrence's day of week to DateUtil's day of week.
    158      * @param day of week as an EventRecurrence value
    159      * @return day of week as a DateUtil value.
    160      */
    161     private static int dayToUtilDay(int day) {
    162         switch (day) {
    163         case EventRecurrence.SU: return Calendar.SUNDAY;
    164         case EventRecurrence.MO: return Calendar.MONDAY;
    165         case EventRecurrence.TU: return Calendar.TUESDAY;
    166         case EventRecurrence.WE: return Calendar.WEDNESDAY;
    167         case EventRecurrence.TH: return Calendar.THURSDAY;
    168         case EventRecurrence.FR: return Calendar.FRIDAY;
    169         case EventRecurrence.SA: return Calendar.SATURDAY;
    170         default: throw new IllegalArgumentException("bad day argument: " + day);
    171         }
    172     }
    173 }
    174