Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 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 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 19 | import android.content.Context; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 20 | import android.content.res.Resources; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 21 | import android.text.format.DateUtils; |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 22 | import android.text.format.Time; |
| 23 | import android.util.TimeFormatException; |
| 24 | |
| 25 | import com.android.calendarcommon2.EventRecurrence; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 26 | |
| 27 | import java.util.Calendar; |
| 28 | |
| 29 | public class EventRecurrenceFormatter |
| 30 | { |
Sam Blitzstein | 86693b2 | 2013-05-01 16:03:10 -0700 | [diff] [blame] | 31 | |
| 32 | private static int[] mMonthRepeatByDayOfWeekIds; |
| 33 | private static String[][] mMonthRepeatByDayOfWeekStrs; |
| 34 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 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 | |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 58 | // TODO Implement "Until" portion of string, as well as custom settings |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 59 | int interval = recurrence.interval <= 1 ? 1 : recurrence.interval; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 60 | switch (recurrence.freq) { |
| 61 | case EventRecurrence.DAILY: |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 62 | return r.getQuantityString(R.plurals.daily, interval, interval) + endString; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 63 | case EventRecurrence.WEEKLY: { |
| 64 | if (recurrence.repeatsOnEveryWeekDay()) { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 65 | return r.getString(R.string.every_weekday) + endString; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 66 | } else { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 67 | String string; |
| 68 | |
| 69 | int dayOfWeekLength = DateUtils.LENGTH_MEDIUM; |
| 70 | if (recurrence.bydayCount == 1) { |
| 71 | dayOfWeekLength = DateUtils.LENGTH_LONG; |
| 72 | } |
| 73 | |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 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. |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 78 | |
| 79 | if (recurrence.bydayCount > 0) { |
| 80 | int count = recurrence.bydayCount - 1; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 81 | for (int i = 0 ; i < count ; i++) { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 82 | days.append(dayToString(recurrence.byday[i], dayOfWeekLength)); |
| 83 | days.append(", "); |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 84 | } |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 85 | days.append(dayToString(recurrence.byday[count], dayOfWeekLength)); |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 86 | |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 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); |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 99 | } |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 100 | return r.getQuantityString(R.plurals.weekly, interval, interval, string) |
| 101 | + endString; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 102 | } |
| 103 | } |
| 104 | case EventRecurrence.MONTHLY: { |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 105 | if (recurrence.bydayCount == 1) { |
Sam Blitzstein | 86693b2 | 2013-05-01 16:03:10 -0700 | [diff] [blame] | 106 | int weekday = recurrence.startDate.weekDay; |
| 107 | // Cache this stuff so we won't have to redo work again later. |
| 108 | cacheMonthRepeatStrings(r, weekday); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 109 | int dayNumber = (recurrence.startDate.monthDay - 1) / 7; |
Sam Blitzstein | 86693b2 | 2013-05-01 16:03:10 -0700 | [diff] [blame] | 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(); |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 117 | } |
| 118 | return r.getString(R.string.monthly) + endString; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 119 | } |
| 120 | case EventRecurrence.YEARLY: |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 121 | return r.getString(R.string.yearly_plain) + endString; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | return null; |
| 125 | } |
| 126 | |
Sam Blitzstein | 86693b2 | 2013-05-01 16:03:10 -0700 | [diff] [blame] | 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 | |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 147 | /** |
| 148 | * Converts day of week to a String. |
| 149 | * @param day a EventRecurrence constant |
| 150 | * @return day of week as a string |
| 151 | */ |
Michael Chan | b21c638 | 2013-03-14 02:53:30 -0700 | [diff] [blame] | 152 | private static String dayToString(int day, int dayOfWeekLength) { |
| 153 | return DateUtils.getDayOfWeekString(dayToUtilDay(day), dayOfWeekLength); |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 154 | } |
| 155 | |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 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) { |
Erik | fed57ec | 2010-03-10 15:51:33 -0800 | [diff] [blame] | 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; |
Ken Shirriff | 5442a16 | 2010-02-26 16:06:04 -0800 | [diff] [blame] | 170 | default: throw new IllegalArgumentException("bad day argument: " + day); |
| 171 | } |
| 172 | } |
| 173 | } |