blob: e5bdb4b95f85c3b5f2ee920c7333a034c3bb2cb9 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.calendar.event;
import com.android.calendar.CalendarEventModel.ReminderEntry;
import com.android.calendar.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Spinner;
import java.util.ArrayList;
public class EventViewUtils {
private static final String TAG = "EventViewUtils";
private EventViewUtils() {
}
// Constructs a label given an arbitrary number of minutes. For example,
// if the given minutes is 63, then this returns the string "63 minutes".
// As another example, if the given minutes is 120, then this returns
// "2 hours".
public static String constructReminderLabel(Context context, int minutes, boolean abbrev) {
Resources resources = context.getResources();
int value, resId;
if (minutes % 60 != 0) {
value = minutes;
if (abbrev) {
resId = R.plurals.Nmins;
} else {
resId = R.plurals.Nminutes;
}
} else if (minutes % (24 * 60) != 0) {
value = minutes / 60;
resId = R.plurals.Nhours;
} else {
value = minutes / (24 * 60);
resId = R.plurals.Ndays;
}
String format = resources.getQuantityString(resId, value);
return String.format(format, value);
}
/**
* Finds the index of the given "minutes" in the "values" list.
*
* @param values the list of minutes corresponding to the spinner choices
* @param minutes the minutes to search for in the values list
* @return the index of "minutes" in the "values" list
*/
public static int findMinutesInReminderList(ArrayList<Integer> values, int minutes) {
int index = values.indexOf(minutes);
if (index == -1) {
// This should never happen.
Log.e(TAG, "Cannot find minutes (" + minutes + ") in list");
return 0;
}
return index;
}
/**
* Finds the index of the given method in the "methods" list. If the method isn't present
* (perhaps because we don't think it's allowed for this calendar), we return zero (the
* first item in the list).
* <p>
* With the current definitions, this effectively converts DEFAULT and unsupported method
* types to ALERT.
*
* @param values the list of minutes corresponding to the spinner choices
* @param method the method to search for in the values list
* @return the index of the method in the "values" list
*/
public static int findMethodInReminderList(ArrayList<Integer> values, int method) {
int index = values.indexOf(method);
if (index == -1) {
// If not allowed, or undefined, just use the first entry in the list.
//Log.d(TAG, "Cannot find method (" + method + ") in allowed list");
index = 0;
}
return index;
}
/**
* Extracts reminder minutes info from UI elements.
*
* @param reminderItems UI elements (layouts with spinners) that hold array indices.
* @param reminderMinuteValues Maps array index to time in minutes.
* @param reminderMethodValues Maps array index to alert method constant.
* @return Array with reminder data.
*/
public static ArrayList<ReminderEntry> reminderItemsToReminders(
ArrayList<LinearLayout> reminderItems, ArrayList<Integer> reminderMinuteValues,
ArrayList<Integer> reminderMethodValues) {
int len = reminderItems.size();
ArrayList<ReminderEntry> reminders = new ArrayList<ReminderEntry>(len);
for (int index = 0; index < len; index++) {
LinearLayout layout = reminderItems.get(index);
Spinner minuteSpinner = (Spinner) layout.findViewById(R.id.reminder_minutes_value);
Spinner methodSpinner = (Spinner) layout.findViewById(R.id.reminder_method_value);
int minutes = reminderMinuteValues.get(minuteSpinner.getSelectedItemPosition());
int method = reminderMethodValues.get(methodSpinner.getSelectedItemPosition());
reminders.add(ReminderEntry.valueOf(minutes, method));
}
return reminders;
}
/**
* If "minutes" is not currently present in "values", we add an appropriate new entry
* to values and labels.
*/
public static void addMinutesToList(Context context, ArrayList<Integer> values,
ArrayList<String> labels, int minutes) {
int index = values.indexOf(minutes);
if (index != -1) {
return;
}
// The requested "minutes" does not exist in the list, so insert it
// into the list.
String label = constructReminderLabel(context, minutes, false);
int len = values.size();
for (int i = 0; i < len; i++) {
if (minutes < values.get(i)) {
values.add(i, minutes);
labels.add(i, label);
return;
}
}
values.add(minutes);
labels.add(len, label);
}
/**
* Remove entries from the method list that aren't allowed for this calendar.
*
* @param values List of known method values.
* @param labels List of known method labels.
* @param allowedMethods Has the form "0,1,3", indicating method constants from Reminders.
*/
public static void reduceMethodList(ArrayList<Integer> values, ArrayList<String> labels,
String allowedMethods)
{
// Parse "allowedMethods".
String[] allowedStrings = allowedMethods.split(",");
int[] allowedValues = new int[allowedStrings.length];
for (int i = 0; i < allowedValues.length; i++) {
try {
allowedValues[i] = Integer.parseInt(allowedStrings[i], 10);
} catch (NumberFormatException nfe) {
Log.w(TAG, "Bad allowed-strings list: '" + allowedStrings[i] +
"' in '" + allowedMethods + "'");
return;
}
}
// Walk through the method list, removing entries that aren't in the allowed list.
for (int i = values.size() - 1; i >= 0; i--) {
int val = values.get(i);
int j;
for (j = allowedValues.length - 1; j >= 0; j--) {
if (val == allowedValues[j]) {
break;
}
}
if (j < 0) {
values.remove(i);
labels.remove(i);
}
}
}
/**
* Set the list of labels on a reminder spinner.
*/
private static void setReminderSpinnerLabels(Activity activity, Spinner spinner,
ArrayList<String> labels) {
Resources res = activity.getResources();
spinner.setPrompt(res.getString(R.string.reminders_label));
int resource = android.R.layout.simple_spinner_item;
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, resource, labels);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
/**
* Adds a reminder to the displayed list of reminders. The values/labels
* arrays must not change after calling here, or the spinners we created
* might index into the wrong entry. Returns true if successfully added
* reminder, false if no reminders can be added.
*
* onItemSelected allows a listener to be set for any changes to the
* spinners in the reminder. If a listener is set it will store the
* initial position of the spinner into the spinner's tag for comparison
* with any new position setting.
*/
public static boolean addReminder(Activity activity, View view, View.OnClickListener listener,
ArrayList<LinearLayout> items, ArrayList<Integer> minuteValues,
ArrayList<String> minuteLabels, ArrayList<Integer> methodValues,
ArrayList<String> methodLabels, ReminderEntry newReminder, int maxReminders,
OnItemSelectedListener onItemSelected) {
if (items.size() >= maxReminders) {
return false;
}
LayoutInflater inflater = activity.getLayoutInflater();
LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminder_items_container);
LinearLayout reminderItem = (LinearLayout) inflater.inflate(R.layout.edit_reminder_item,
null);
parent.addView(reminderItem);
ImageButton reminderRemoveButton;
reminderRemoveButton = (ImageButton) reminderItem.findViewById(R.id.reminder_remove);
reminderRemoveButton.setOnClickListener(listener);
/*
* The spinner has the default set of labels from the string resource file, but we
* want to drop in our custom set of labels because it may have additional entries.
*/
Spinner spinner = (Spinner) reminderItem.findViewById(R.id.reminder_minutes_value);
setReminderSpinnerLabels(activity, spinner, minuteLabels);
int index = findMinutesInReminderList(minuteValues, newReminder.getMinutes());
spinner.setSelection(index);
if (onItemSelected != null) {
spinner.setTag(index);
spinner.setOnItemSelectedListener(onItemSelected);
}
/*
* Configure the alert-method spinner. Methods not supported by the current Calendar
* will not be shown.
*/
spinner = (Spinner) reminderItem.findViewById(R.id.reminder_method_value);
setReminderSpinnerLabels(activity, spinner, methodLabels);
index = findMethodInReminderList(methodValues, newReminder.getMethod());
spinner.setSelection(index);
if (onItemSelected != null) {
spinner.setTag(index);
spinner.setOnItemSelectedListener(onItemSelected);
}
items.add(reminderItem);
return true;
}
/**
* Enables/disables the 'add reminder' button depending on the current number of
* reminders.
*/
public static void updateAddReminderButton(View view, ArrayList<LinearLayout> reminders,
int maxReminders) {
View reminderAddButton = view.findViewById(R.id.reminder_add);
if (reminderAddButton != null) {
if (reminders.size() >= maxReminders) {
reminderAddButton.setEnabled(false);
reminderAddButton.setVisibility(View.GONE);
} else {
reminderAddButton.setEnabled(true);
reminderAddButton.setVisibility(View.VISIBLE);
}
}
}
}