EventViewUtils.java revision 9645d9c3e9b2cfd35c5fc89f41caf6e99153ba10
1/*
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 */
16package com.android.calendar.event;
17
18import com.android.calendar.CalendarEventModel.ReminderEntry;
19import com.android.calendar.R;
20
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;
27import android.widget.ArrayAdapter;
28import android.widget.ImageButton;
29import android.widget.LinearLayout;
30import android.widget.Spinner;
31
32import java.util.ArrayList;
33
34public class EventViewUtils {
35    private static final String TAG = "EventViewUtils";
36
37    private EventViewUtils() {
38    }
39
40    // Constructs a label given an arbitrary number of minutes. For example,
41    // if the given minutes is 63, then this returns the string "63 minutes".
42    // As another example, if the given minutes is 120, then this returns
43    // "2 hours".
44    public static String constructReminderLabel(Context context, int minutes, boolean abbrev) {
45        Resources resources = context.getResources();
46        int value, resId;
47
48        if (minutes % 60 != 0) {
49            value = minutes;
50            if (abbrev) {
51                resId = R.plurals.Nmins;
52            } else {
53                resId = R.plurals.Nminutes;
54            }
55        } else if (minutes % (24 * 60) != 0) {
56            value = minutes / 60;
57            resId = R.plurals.Nhours;
58        } else {
59            value = minutes / (24 * 60);
60            resId = R.plurals.Ndays;
61        }
62
63        String format = resources.getQuantityString(resId, value);
64        return String.format(format, value);
65    }
66
67    /**
68     * Finds the index of the given "minutes" in the "values" list.
69     *
70     * @param values the list of minutes corresponding to the spinner choices
71     * @param minutes the minutes to search for in the values list
72     * @return the index of "minutes" in the "values" list
73     */
74    public static int findMinutesInReminderList(ArrayList<Integer> values, int minutes) {
75        int index = values.indexOf(minutes);
76        if (index == -1) {
77            // This should never happen.
78            Log.e(TAG, "Cannot find minutes (" + minutes + ") in list");
79            return 0;
80        }
81        return index;
82    }
83
84    /**
85     * Finds the index of the given method in the "methods" list.  If the method isn't present
86     * (perhaps because we don't think it's allowed for this calendar), we return zero (the
87     * first item in the list).
88     * <p>
89     * With the current definitions, this effectively converts DEFAULT and unsupported method
90     * types to ALERT.
91     *
92     * @param values the list of minutes corresponding to the spinner choices
93     * @param method the method to search for in the values list
94     * @return the index of the method in the "values" list
95     */
96    public static int findMethodInReminderList(ArrayList<Integer> values, int method) {
97        int index = values.indexOf(method);
98        if (index == -1) {
99            // If not allowed, or undefined, just use the first entry in the list.
100            //Log.d(TAG, "Cannot find method (" + method + ") in allowed list");
101            index = 0;
102        }
103        return index;
104    }
105
106    /**
107     * Extracts reminder minutes info from UI elements.
108     *
109     * @param reminderItems UI elements (layouts with spinners) that hold array indices.
110     * @param reminderMinuteValues Maps array index to time in minutes.
111     * @param reminderMethodValues Maps array index to alert method constant.
112     * @return Array with reminder data.
113     */
114    public static ArrayList<ReminderEntry> reminderItemsToReminders(
115            ArrayList<LinearLayout> reminderItems, ArrayList<Integer> reminderMinuteValues,
116            ArrayList<Integer> reminderMethodValues) {
117        int len = reminderItems.size();
118        ArrayList<ReminderEntry> reminders = new ArrayList<ReminderEntry>(len);
119        for (int index = 0; index < len; index++) {
120            LinearLayout layout = reminderItems.get(index);
121            Spinner minuteSpinner = (Spinner) layout.findViewById(R.id.reminder_minutes_value);
122            Spinner methodSpinner = (Spinner) layout.findViewById(R.id.reminder_method_value);
123            int minutes = reminderMinuteValues.get(minuteSpinner.getSelectedItemPosition());
124            int method = reminderMethodValues.get(methodSpinner.getSelectedItemPosition());
125            reminders.add(ReminderEntry.valueOf(minutes, method));
126        }
127        return reminders;
128    }
129
130    /**
131     * If "minutes" is not currently present in "values", we add an appropriate new entry
132     * to values and labels.
133     */
134    public static void addMinutesToList(Context context, ArrayList<Integer> values,
135            ArrayList<String> labels, int minutes) {
136        int index = values.indexOf(minutes);
137        if (index != -1) {
138            return;
139        }
140
141        // The requested "minutes" does not exist in the list, so insert it
142        // into the list.
143
144        String label = constructReminderLabel(context, minutes, false);
145        int len = values.size();
146        for (int i = 0; i < len; i++) {
147            if (minutes < values.get(i)) {
148                values.add(i, minutes);
149                labels.add(i, label);
150                return;
151            }
152        }
153
154        values.add(minutes);
155        labels.add(len, label);
156    }
157
158    /**
159     * Remove entries from the method list that aren't allowed for this calendar.
160     *
161     * @param values List of known method values.
162     * @param labels List of known method labels.
163     * @param allowedMethods Has the form "0,1,3", indicating method constants from Reminders.
164     */
165    public static void reduceMethodList(ArrayList<Integer> values, ArrayList<String> labels,
166            String allowedMethods)
167    {
168        // Parse "allowedMethods".
169        String[] allowedStrings = allowedMethods.split(",");
170        int[] allowedValues = new int[allowedStrings.length];
171
172        for (int i = 0; i < allowedValues.length; i++) {
173            try {
174                allowedValues[i] = Integer.parseInt(allowedStrings[i], 10);
175            } catch (NumberFormatException nfe) {
176                Log.w(TAG, "Bad allowed-strings list: '" + allowedStrings[i] +
177                        "' in '" + allowedMethods + "'");
178                return;
179            }
180        }
181
182        // Walk through the method list, removing entries that aren't in the allowed list.
183        for (int i = values.size() - 1; i >= 0; i--) {
184            int val = values.get(i);
185            int j;
186
187            for (j = allowedValues.length - 1; j >= 0; j--) {
188                if (val == allowedValues[j]) {
189                    break;
190                }
191            }
192            if (j < 0) {
193                values.remove(i);
194                labels.remove(i);
195            }
196        }
197    }
198
199    /**
200     * Set the list of labels on a reminder spinner.
201     */
202    private static void setReminderSpinnerLabels(Activity activity, Spinner spinner,
203            ArrayList<String> labels) {
204        Resources res = activity.getResources();
205        spinner.setPrompt(res.getString(R.string.reminders_label));
206        int resource = android.R.layout.simple_spinner_item;
207        ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, resource, labels);
208        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
209        spinner.setAdapter(adapter);
210    }
211
212    /**
213     * Adds a reminder to the displayed list of reminders.
214     *
215     * The values/labels arrays must not change after calling here, or the spinners we
216     * created might index into the wrong entry.
217     *
218     * Returns true if successfully added reminder, false if no reminders can
219     * be added.
220     */
221    public static boolean addReminder(Activity activity, View view,
222            View.OnClickListener listener, ArrayList<LinearLayout> items,
223            ArrayList<Integer> minuteValues, ArrayList<String> minuteLabels,
224            ArrayList<Integer> methodValues, ArrayList<String> methodLabels,
225            ReminderEntry newReminder, int maxReminders) {
226
227        if (items.size() >= maxReminders) {
228            return false;
229        }
230
231        LayoutInflater inflater = activity.getLayoutInflater();
232        LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminder_items_container);
233        LinearLayout reminderItem = (LinearLayout) inflater.inflate(R.layout.edit_reminder_item,
234                null);
235        parent.addView(reminderItem);
236
237        ImageButton reminderRemoveButton;
238        reminderRemoveButton = (ImageButton) reminderItem.findViewById(R.id.reminder_remove);
239        reminderRemoveButton.setOnClickListener(listener);
240
241        /*
242         * The spinner has the default set of labels from the string resource file, but we
243         * want to drop in our custom set of labels because it may have additional entries.
244         */
245        Spinner spinner = (Spinner) reminderItem.findViewById(R.id.reminder_minutes_value);
246        setReminderSpinnerLabels(activity, spinner, minuteLabels);
247
248        int index = findMinutesInReminderList(minuteValues, newReminder.getMinutes());
249        spinner.setSelection(index);
250
251        /*
252         * Configure the alert-method spinner.  Methods not supported by the current Calendar
253         * will not be shown.
254         */
255        spinner = (Spinner) reminderItem.findViewById(R.id.reminder_method_value);
256        setReminderSpinnerLabels(activity, spinner, methodLabels);
257
258        index = findMethodInReminderList(methodValues, newReminder.getMethod());
259        spinner.setSelection(index);
260
261        items.add(reminderItem);
262
263        return true;
264    }
265}
266