blob: e5bdb4b95f85c3b5f2ee920c7333a034c3bb2cb9 [file] [log] [blame]
Erik8d69cd02010-06-23 17:32:51 -07001/*
2 * Copyright (C) 2010 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 */
Erikfbce65e2010-08-16 12:43:13 -070016package com.android.calendar.event;
17
Andy McFaddenfea9af52011-05-13 15:40:10 -070018import com.android.calendar.CalendarEventModel.ReminderEntry;
Erikfbce65e2010-08-16 12:43:13 -070019import com.android.calendar.R;
Erik8d69cd02010-06-23 17:32:51 -070020
21import android.app.Activity;
22import android.content.Context;
23import android.content.res.Resources;
24import android.util.Log;
25import android.view.LayoutInflater;
26import android.view.View;
RoboErik8b5743c2011-09-27 16:07:09 -070027import android.widget.AdapterView.OnItemSelectedListener;
Erik8d69cd02010-06-23 17:32:51 -070028import android.widget.ArrayAdapter;
29import android.widget.ImageButton;
30import android.widget.LinearLayout;
31import android.widget.Spinner;
32
33import java.util.ArrayList;
34
35public class EventViewUtils {
Andy McFadden9645d9c2011-05-16 15:28:15 -070036 private static final String TAG = "EventViewUtils";
Erik8d69cd02010-06-23 17:32:51 -070037
38 private EventViewUtils() {
39 }
40
41 // Constructs a label given an arbitrary number of minutes. For example,
42 // if the given minutes is 63, then this returns the string "63 minutes".
43 // As another example, if the given minutes is 120, then this returns
44 // "2 hours".
Erikfbce65e2010-08-16 12:43:13 -070045 public static String constructReminderLabel(Context context, int minutes, boolean abbrev) {
Erik8d69cd02010-06-23 17:32:51 -070046 Resources resources = context.getResources();
47 int value, resId;
48
49 if (minutes % 60 != 0) {
50 value = minutes;
51 if (abbrev) {
52 resId = R.plurals.Nmins;
53 } else {
54 resId = R.plurals.Nminutes;
55 }
56 } else if (minutes % (24 * 60) != 0) {
57 value = minutes / 60;
58 resId = R.plurals.Nhours;
59 } else {
60 value = minutes / (24 * 60);
61 resId = R.plurals.Ndays;
62 }
63
64 String format = resources.getQuantityString(resId, value);
65 return String.format(format, value);
66 }
67
68 /**
69 * Finds the index of the given "minutes" in the "values" list.
70 *
71 * @param values the list of minutes corresponding to the spinner choices
72 * @param minutes the minutes to search for in the values list
73 * @return the index of "minutes" in the "values" list
74 */
Erikfbce65e2010-08-16 12:43:13 -070075 public static int findMinutesInReminderList(ArrayList<Integer> values, int minutes) {
Erik8d69cd02010-06-23 17:32:51 -070076 int index = values.indexOf(minutes);
77 if (index == -1) {
78 // This should never happen.
Andy McFadden9645d9c2011-05-16 15:28:15 -070079 Log.e(TAG, "Cannot find minutes (" + minutes + ") in list");
Erik8d69cd02010-06-23 17:32:51 -070080 return 0;
81 }
82 return index;
83 }
84
Andy McFaddenfea9af52011-05-13 15:40:10 -070085 /**
Andy McFadden9645d9c2011-05-16 15:28:15 -070086 * Finds the index of the given method in the "methods" list. If the method isn't present
87 * (perhaps because we don't think it's allowed for this calendar), we return zero (the
88 * first item in the list).
89 * <p>
90 * With the current definitions, this effectively converts DEFAULT and unsupported method
91 * types to ALERT.
92 *
93 * @param values the list of minutes corresponding to the spinner choices
94 * @param method the method to search for in the values list
95 * @return the index of the method in the "values" list
96 */
97 public static int findMethodInReminderList(ArrayList<Integer> values, int method) {
98 int index = values.indexOf(method);
99 if (index == -1) {
100 // If not allowed, or undefined, just use the first entry in the list.
101 //Log.d(TAG, "Cannot find method (" + method + ") in allowed list");
102 index = 0;
103 }
104 return index;
105 }
106
107 /**
Andy McFaddenfea9af52011-05-13 15:40:10 -0700108 * Extracts reminder minutes info from UI elements.
109 *
Andy McFadden9645d9c2011-05-16 15:28:15 -0700110 * @param reminderItems UI elements (layouts with spinners) that hold array indices.
111 * @param reminderMinuteValues Maps array index to time in minutes.
112 * @param reminderMethodValues Maps array index to alert method constant.
Andy McFaddenfea9af52011-05-13 15:40:10 -0700113 * @return Array with reminder data.
114 */
Andy McFadden9645d9c2011-05-16 15:28:15 -0700115 public static ArrayList<ReminderEntry> reminderItemsToReminders(
116 ArrayList<LinearLayout> reminderItems, ArrayList<Integer> reminderMinuteValues,
117 ArrayList<Integer> reminderMethodValues) {
Erik8d69cd02010-06-23 17:32:51 -0700118 int len = reminderItems.size();
Andy McFadden9645d9c2011-05-16 15:28:15 -0700119 ArrayList<ReminderEntry> reminders = new ArrayList<ReminderEntry>(len);
Erik8d69cd02010-06-23 17:32:51 -0700120 for (int index = 0; index < len; index++) {
121 LinearLayout layout = reminderItems.get(index);
Andy McFadden9645d9c2011-05-16 15:28:15 -0700122 Spinner minuteSpinner = (Spinner) layout.findViewById(R.id.reminder_minutes_value);
123 Spinner methodSpinner = (Spinner) layout.findViewById(R.id.reminder_method_value);
124 int minutes = reminderMinuteValues.get(minuteSpinner.getSelectedItemPosition());
125 int method = reminderMethodValues.get(methodSpinner.getSelectedItemPosition());
126 reminders.add(ReminderEntry.valueOf(minutes, method));
Erik8d69cd02010-06-23 17:32:51 -0700127 }
Andy McFadden9645d9c2011-05-16 15:28:15 -0700128 return reminders;
Erik8d69cd02010-06-23 17:32:51 -0700129 }
130
Andy McFaddenae5bcce2011-04-14 09:28:08 -0700131 /**
Andy McFaddenfea9af52011-05-13 15:40:10 -0700132 * If "minutes" is not currently present in "values", we add an appropriate new entry
133 * to values and labels.
Andy McFaddenae5bcce2011-04-14 09:28:08 -0700134 */
Erikfbce65e2010-08-16 12:43:13 -0700135 public static void addMinutesToList(Context context, ArrayList<Integer> values,
Erik8d69cd02010-06-23 17:32:51 -0700136 ArrayList<String> labels, int minutes) {
137 int index = values.indexOf(minutes);
138 if (index != -1) {
139 return;
140 }
141
142 // The requested "minutes" does not exist in the list, so insert it
143 // into the list.
144
145 String label = constructReminderLabel(context, minutes, false);
146 int len = values.size();
147 for (int i = 0; i < len; i++) {
148 if (minutes < values.get(i)) {
149 values.add(i, minutes);
150 labels.add(i, label);
151 return;
152 }
153 }
154
155 values.add(minutes);
156 labels.add(len, label);
157 }
158
Andy McFaddenae5bcce2011-04-14 09:28:08 -0700159 /**
Andy McFadden9645d9c2011-05-16 15:28:15 -0700160 * Remove entries from the method list that aren't allowed for this calendar.
161 *
162 * @param values List of known method values.
163 * @param labels List of known method labels.
164 * @param allowedMethods Has the form "0,1,3", indicating method constants from Reminders.
165 */
166 public static void reduceMethodList(ArrayList<Integer> values, ArrayList<String> labels,
167 String allowedMethods)
168 {
169 // Parse "allowedMethods".
170 String[] allowedStrings = allowedMethods.split(",");
171 int[] allowedValues = new int[allowedStrings.length];
172
173 for (int i = 0; i < allowedValues.length; i++) {
174 try {
175 allowedValues[i] = Integer.parseInt(allowedStrings[i], 10);
176 } catch (NumberFormatException nfe) {
177 Log.w(TAG, "Bad allowed-strings list: '" + allowedStrings[i] +
178 "' in '" + allowedMethods + "'");
179 return;
180 }
181 }
182
183 // Walk through the method list, removing entries that aren't in the allowed list.
184 for (int i = values.size() - 1; i >= 0; i--) {
185 int val = values.get(i);
186 int j;
187
188 for (j = allowedValues.length - 1; j >= 0; j--) {
189 if (val == allowedValues[j]) {
190 break;
191 }
192 }
193 if (j < 0) {
194 values.remove(i);
195 labels.remove(i);
196 }
197 }
198 }
199
200 /**
201 * Set the list of labels on a reminder spinner.
202 */
203 private static void setReminderSpinnerLabels(Activity activity, Spinner spinner,
204 ArrayList<String> labels) {
205 Resources res = activity.getResources();
206 spinner.setPrompt(res.getString(R.string.reminders_label));
207 int resource = android.R.layout.simple_spinner_item;
208 ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, resource, labels);
209 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
210 spinner.setAdapter(adapter);
211 }
212
213 /**
RoboErik8b5743c2011-09-27 16:07:09 -0700214 * Adds a reminder to the displayed list of reminders. The values/labels
215 * arrays must not change after calling here, or the spinners we created
216 * might index into the wrong entry. Returns true if successfully added
217 * reminder, false if no reminders can be added.
Michael Chan99704a22011-11-11 10:24:37 -0800218 *
RoboErik8b5743c2011-09-27 16:07:09 -0700219 * onItemSelected allows a listener to be set for any changes to the
220 * spinners in the reminder. If a listener is set it will store the
221 * initial position of the spinner into the spinner's tag for comparison
222 * with any new position setting.
Andy McFaddenae5bcce2011-04-14 09:28:08 -0700223 */
RoboErik8b5743c2011-09-27 16:07:09 -0700224 public static boolean addReminder(Activity activity, View view, View.OnClickListener listener,
225 ArrayList<LinearLayout> items, ArrayList<Integer> minuteValues,
226 ArrayList<String> minuteLabels, ArrayList<Integer> methodValues,
227 ArrayList<String> methodLabels, ReminderEntry newReminder, int maxReminders,
228 OnItemSelectedListener onItemSelected) {
Erik8d69cd02010-06-23 17:32:51 -0700229
Andy McFadden9645d9c2011-05-16 15:28:15 -0700230 if (items.size() >= maxReminders) {
Erik8d69cd02010-06-23 17:32:51 -0700231 return false;
232 }
233
234 LayoutInflater inflater = activity.getLayoutInflater();
Erik79f22812010-06-23 16:55:38 -0700235 LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminder_items_container);
Erik8d69cd02010-06-23 17:32:51 -0700236 LinearLayout reminderItem = (LinearLayout) inflater.inflate(R.layout.edit_reminder_item,
237 null);
238 parent.addView(reminderItem);
239
Erik8d69cd02010-06-23 17:32:51 -0700240 ImageButton reminderRemoveButton;
241 reminderRemoveButton = (ImageButton) reminderItem.findViewById(R.id.reminder_remove);
242 reminderRemoveButton.setOnClickListener(listener);
243
Andy McFadden9645d9c2011-05-16 15:28:15 -0700244 /*
245 * The spinner has the default set of labels from the string resource file, but we
246 * want to drop in our custom set of labels because it may have additional entries.
247 */
248 Spinner spinner = (Spinner) reminderItem.findViewById(R.id.reminder_minutes_value);
249 setReminderSpinnerLabels(activity, spinner, minuteLabels);
250
Andy McFaddenfea9af52011-05-13 15:40:10 -0700251 int index = findMinutesInReminderList(minuteValues, newReminder.getMinutes());
Erik8d69cd02010-06-23 17:32:51 -0700252 spinner.setSelection(index);
253
RoboErik8b5743c2011-09-27 16:07:09 -0700254 if (onItemSelected != null) {
255 spinner.setTag(index);
256 spinner.setOnItemSelectedListener(onItemSelected);
257 }
258
Andy McFadden9645d9c2011-05-16 15:28:15 -0700259 /*
260 * Configure the alert-method spinner. Methods not supported by the current Calendar
261 * will not be shown.
262 */
263 spinner = (Spinner) reminderItem.findViewById(R.id.reminder_method_value);
264 setReminderSpinnerLabels(activity, spinner, methodLabels);
265
266 index = findMethodInReminderList(methodValues, newReminder.getMethod());
267 spinner.setSelection(index);
268
RoboErik8b5743c2011-09-27 16:07:09 -0700269 if (onItemSelected != null) {
270 spinner.setTag(index);
271 spinner.setOnItemSelectedListener(onItemSelected);
272 }
273
Erik8d69cd02010-06-23 17:32:51 -0700274 items.add(reminderItem);
275
276 return true;
277 }
Sara Ting06f3d6d2012-03-23 17:19:22 -0700278
279 /**
280 * Enables/disables the 'add reminder' button depending on the current number of
281 * reminders.
282 */
283 public static void updateAddReminderButton(View view, ArrayList<LinearLayout> reminders,
284 int maxReminders) {
285 View reminderAddButton = view.findViewById(R.id.reminder_add);
286 if (reminderAddButton != null) {
287 if (reminders.size() >= maxReminders) {
288 reminderAddButton.setEnabled(false);
289 reminderAddButton.setVisibility(View.GONE);
290 } else {
291 reminderAddButton.setEnabled(true);
292 reminderAddButton.setVisibility(View.VISIBLE);
293 }
294 }
295 }
Erik8d69cd02010-06-23 17:32:51 -0700296}