Home | History | Annotate | Download | only in event
      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  */
     16 package com.android.calendar.event;
     17 
     18 import com.android.calendar.CalendarEventModel.ReminderEntry;
     19 import com.android.calendar.R;
     20 
     21 import android.app.Activity;
     22 import android.content.Context;
     23 import android.content.res.Resources;
     24 import android.util.Log;
     25 import android.view.LayoutInflater;
     26 import android.view.View;
     27 import android.widget.AdapterView.OnItemSelectedListener;
     28 import android.widget.ArrayAdapter;
     29 import android.widget.ImageButton;
     30 import android.widget.LinearLayout;
     31 import android.widget.Spinner;
     32 
     33 import java.util.ArrayList;
     34 
     35 public class EventViewUtils {
     36     private static final String TAG = "EventViewUtils";
     37 
     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".
     45     public static String constructReminderLabel(Context context, int minutes, boolean abbrev) {
     46         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      */
     75     public static int findMinutesInReminderList(ArrayList<Integer> values, int minutes) {
     76         int index = values.indexOf(minutes);
     77         if (index == -1) {
     78             // This should never happen.
     79             Log.e(TAG, "Cannot find minutes (" + minutes + ") in list");
     80             return 0;
     81         }
     82         return index;
     83     }
     84 
     85     /**
     86      * 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     /**
    108      * Extracts reminder minutes info from UI elements.
    109      *
    110      * @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.
    113      * @return Array with reminder data.
    114      */
    115     public static ArrayList<ReminderEntry> reminderItemsToReminders(
    116             ArrayList<LinearLayout> reminderItems, ArrayList<Integer> reminderMinuteValues,
    117             ArrayList<Integer> reminderMethodValues) {
    118         int len = reminderItems.size();
    119         ArrayList<ReminderEntry> reminders = new ArrayList<ReminderEntry>(len);
    120         for (int index = 0; index < len; index++) {
    121             LinearLayout layout = reminderItems.get(index);
    122             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));
    127         }
    128         return reminders;
    129     }
    130 
    131     /**
    132      * If "minutes" is not currently present in "values", we add an appropriate new entry
    133      * to values and labels.
    134      */
    135     public static void addMinutesToList(Context context, ArrayList<Integer> values,
    136             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 
    159     /**
    160      * 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     /**
    214      * 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.
    218      *
    219      * 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.
    223      */
    224     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) {
    229 
    230         if (items.size() >= maxReminders) {
    231             return false;
    232         }
    233 
    234         LayoutInflater inflater = activity.getLayoutInflater();
    235         LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminder_items_container);
    236         LinearLayout reminderItem = (LinearLayout) inflater.inflate(R.layout.edit_reminder_item,
    237                 null);
    238         parent.addView(reminderItem);
    239 
    240         ImageButton reminderRemoveButton;
    241         reminderRemoveButton = (ImageButton) reminderItem.findViewById(R.id.reminder_remove);
    242         reminderRemoveButton.setOnClickListener(listener);
    243 
    244         /*
    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 
    251         int index = findMinutesInReminderList(minuteValues, newReminder.getMinutes());
    252         spinner.setSelection(index);
    253 
    254         if (onItemSelected != null) {
    255             spinner.setTag(index);
    256             spinner.setOnItemSelectedListener(onItemSelected);
    257         }
    258 
    259         /*
    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 
    269         if (onItemSelected != null) {
    270             spinner.setTag(index);
    271             spinner.setOnItemSelectedListener(onItemSelected);
    272         }
    273 
    274         items.add(reminderItem);
    275 
    276         return true;
    277     }
    278 
    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     }
    296 }
    297