/** * Copyright (c) 2012 Todoroo Inc * * See the file "LICENSE" for the full license governing this code. */ package com.todoroo.astrid.ui; import java.text.ParseException; import java.util.Date; import android.app.Dialog; import android.content.Context; import android.content.res.Configuration; import android.text.Html; import android.text.Spanned; import android.text.TextUtils; import android.util.DisplayMetrics; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.TextView; import com.google.ical.values.Frequency; import com.google.ical.values.RRule; import com.timsu.astrid.R; import com.todoroo.andlib.data.Property; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.activity.AstridActivity; import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.repeats.RepeatTaskCompleteListener; import com.todoroo.astrid.ui.DateAndTimeDialog.DateAndTimeDialogListener; import com.todoroo.astrid.utility.Flags; /** * Helper class that creates a dialog to confirm the results of a quick add markup * @author Sam * */ public class DateChangedAlerts { /** Preference key for how many of these helper dialogs we've shown */ public static final String PREF_NUM_HELPERS_SHOWN = "pref_num_date_helpers"; //$NON-NLS-1$ /** Preference key for whether or not we should show such dialogs */ public static final int PREF_SHOW_HELPERS = R.string.p_showSmartConfirmation_key; /** Start showing the option to hide future notifs after this many confirmation dialogs */ public static final int HIDE_CHECKBOX_AFTER_SHOWS = 3; public static void showQuickAddMarkupDialog(final AstridActivity activity, Task task, String originalText) { if (!Preferences.getBoolean(PREF_SHOW_HELPERS, true)) return; final Dialog d = new Dialog(activity, R.style.ReminderDialog); final long taskId = task.getId(); final boolean editable = task.isEditable(); d.setContentView(R.layout.astrid_reminder_view); Button okButton = (Button) d.findViewById(R.id.reminder_complete); okButton.setText(R.string.DLG_ok); d.findViewById(R.id.reminder_snooze).setVisibility(View.GONE); ((TextView) d.findViewById(R.id.reminder_title)).setText(activity.getString(R.string.TLA_quickadd_confirm_title, originalText)); Spanned speechBubbleText = constructSpeechBubbleTextForQuickAdd(activity, task); ((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText, TextView.BufferType.SPANNABLE); setupOkAndDismissButtons(d); setupHideCheckbox(d); d.findViewById(R.id.reminder_edit).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { d.dismiss(); activity.onTaskListItemClicked(taskId, editable); } }); setupDialogLayoutParams(activity, d); d.setOwnerActivity(activity); d.show(); } public static void showRepeatChangedDialog(final AstridActivity activity, Task task) { if (!Preferences.getBoolean(PREF_SHOW_HELPERS, true)) return; final Dialog d = new Dialog(activity, R.style.ReminderDialog); d.setContentView(R.layout.astrid_reminder_view); Button okButton = (Button) d.findViewById(R.id.reminder_complete); okButton.setText(R.string.DLG_ok); d.findViewById(R.id.reminder_snooze).setVisibility(View.GONE); d.findViewById(R.id.reminder_edit).setVisibility(View.GONE); ((TextView) d.findViewById(R.id.reminder_title)).setText(activity.getString(R.string.TLA_repeat_scheduled_title, task.getValue(Task.TITLE))); String speechBubbleText = constructSpeechBubbleTextForRepeat(activity, task); ((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText); setupOkAndDismissButtons(d); setupHideCheckbox(d); setupDialogLayoutParams(activity, d); d.setOwnerActivity(activity); d.show(); } public static final Property<?>[] REPEAT_RESCHEDULED_PROPERTIES = new Property<?>[] { Task.ID, Task.TITLE, Task.DUE_DATE, Task.HIDE_UNTIL, Task.REPEAT_UNTIL }; public static void showRepeatTaskRescheduledDialog(final AstridActivity activity, final Task task, final long oldDueDate, final long newDueDate, final boolean lastTime) { if (!Preferences.getBoolean(PREF_SHOW_HELPERS, true)) return; final Dialog d = new Dialog(activity, R.style.ReminderDialog); d.setContentView(R.layout.astrid_reminder_view); Button okButton = (Button) d.findViewById(R.id.reminder_complete); Button undoButton = (Button) d.findViewById(R.id.reminder_edit); Button keepGoing = (Button) d.findViewById(R.id.reminder_snooze); if (!lastTime) { keepGoing.setVisibility(View.GONE); } else { keepGoing.setText(R.string.repeat_keep_going); keepGoing.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { long startDate = 0; DateAndTimeDialog picker = new DateAndTimeDialog(activity, startDate, R.layout.repeat_until_dialog, R.string.repeat_until_title); picker.setDateAndTimeDialogListener(new DateAndTimeDialogListener() { @Override public void onDateAndTimeSelected(long date) { d.dismiss(); task.setValue(Task.REPEAT_UNTIL, date); RepeatTaskCompleteListener.rescheduleTask(task, newDueDate); Flags.set(Flags.REFRESH); } @Override public void onDateAndTimeCancelled() { // } }); picker.show(); } }); } okButton.setText(R.string.DLG_ok); undoButton.setText(R.string.DLG_undo); int titleResource = lastTime ? R.string.repeat_rescheduling_dialog_title_last_time : R.string.repeat_rescheduling_dialog_title; ((TextView) d.findViewById(R.id.reminder_title)).setText( activity.getString(titleResource, task.getValue(Task.TITLE))); String oldDueDateString = getRelativeDateAndTimeString(activity, oldDueDate); String newDueDateString = getRelativeDateAndTimeString(activity, newDueDate); String repeatUntilDateString = getRelativeDateAndTimeString(activity, task.getValue(Task.REPEAT_UNTIL)); int encouragementResource = lastTime ? R.array.repeat_encouragement_last_time : R.array.repeat_encouragement; String[] encouragements = activity.getResources().getStringArray(encouragementResource); String encouragement = encouragements[(int) (Math.random()*encouragements.length)]; String speechBubbleText; if (lastTime) speechBubbleText = activity.getString(R.string.repeat_rescheduling_dialog_bubble_last_time, repeatUntilDateString, encouragement); else if (!TextUtils.isEmpty(oldDueDateString)) speechBubbleText = activity.getString(R.string.repeat_rescheduling_dialog_bubble, encouragement, oldDueDateString, newDueDateString); else speechBubbleText = activity.getString(R.string.repeat_rescheduling_dialog_bubble_no_date, encouragement, newDueDateString); ((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText); setupOkAndDismissButtons(d); setupHideCheckbox(d); undoButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { d.dismiss(); task.setValue(Task.DUE_DATE, oldDueDate); task.setValue(Task.COMPLETION_DATE, 0L); long hideUntil = task.getValue(Task.HIDE_UNTIL); if (hideUntil > 0) task.setValue(Task.HIDE_UNTIL, hideUntil - (newDueDate - oldDueDate)); PluginServices.getTaskService().save(task); Flags.set(Flags.REFRESH); } }); setupDialogLayoutParams(activity, d); d.setOwnerActivity(activity); d.show(); } private static void setupOkAndDismissButtons(final Dialog d) { d.findViewById(R.id.reminder_complete).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { d.dismiss(); } }); d.findViewById(R.id.dismiss).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { d.dismiss(); } }); } private static void setupHideCheckbox(final Dialog d) { int numShows = Preferences.getInt(PREF_NUM_HELPERS_SHOWN, 0); numShows++; if (numShows >= HIDE_CHECKBOX_AFTER_SHOWS) { CheckBox checkbox = (CheckBox) d.findViewById(R.id.reminders_should_show); checkbox.setVisibility(View.VISIBLE); checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Preferences.setBoolean(PREF_SHOW_HELPERS, !isChecked); } }); } Preferences.setInt(PREF_NUM_HELPERS_SHOWN, numShows); } private static void setupDialogLayoutParams(Context context, Dialog d) { LayoutParams params = d.getWindow().getAttributes(); params.width = LayoutParams.FILL_PARENT; params.height = LayoutParams.WRAP_CONTENT; Configuration config = context.getResources().getConfiguration(); int size = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; if (AndroidUtilities.getSdkVersion() >= 9 && size == Configuration.SCREENLAYOUT_SIZE_XLARGE || size == Configuration.SCREENLAYOUT_SIZE_LARGE) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); params.width = metrics.widthPixels / 2; } d.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); } @SuppressWarnings("nls") private static Spanned constructSpeechBubbleTextForQuickAdd(Context context, Task task) { String[] priorityStrings = context.getResources().getStringArray(R.array.TLA_priority_strings); int[] colorsArray = new int[] { R.color.importance_1, R.color.importance_2, R.color.importance_3, R.color.importance_4 }; String title = task.getValue(Task.TITLE); long date = task.getValue(Task.DUE_DATE); String dueString = ""; if (!TextUtils.isEmpty(task.getValue(Task.RECURRENCE))) { dueString = getRecurrenceString(context, task); } if (TextUtils.isEmpty(dueString)) { dueString = getRelativeDateAndTimeString(context, date); } if (!TextUtils.isEmpty(dueString)) dueString = context.getString(R.string.TLA_quickadd_confirm_speech_bubble_date, dueString); int priority = task.getValue(Task.IMPORTANCE); if (priority >= priorityStrings.length) priority = priorityStrings.length - 1; String priorityString = priorityStrings[priority]; int color = context.getResources().getColor(colorsArray[priority]) - 0xff000000; priorityString = String.format("<font color=\"#%s\">%s</font>", Integer.toHexString(color), priorityString); String fullString = context.getString(R.string.TLA_quickadd_confirm_speech_bubble, title, dueString, priorityString); return Html.fromHtml(fullString); } private static String constructSpeechBubbleTextForRepeat(Context context, Task task) { String recurrence = getRecurrenceString(context, task); return context.getString(R.string.TLA_repeat_scheduled_speech_bubble, recurrence); } @SuppressWarnings("nls") private static String getRelativeDateAndTimeString(Context context, long date) { String dueString = date > 0 ? DateUtilities.getRelativeDay(context, date, false) : ""; if(Task.hasDueTime(date)) dueString = String.format("%s at %s", dueString, //$NON-NLS-1$ DateUtilities.getTimeString(context, new Date(date))); return dueString; } @SuppressWarnings("nls") private static String getRecurrenceString(Context context, Task task) { try { RRule rrule = new RRule(task.sanitizedRecurrence()); String[] dateAbbrev = context.getResources().getStringArray( R.array.repeat_interval); String frequency = ""; Frequency freq = rrule.getFreq(); switch(freq) { case DAILY: frequency = dateAbbrev[0].toLowerCase(); break; case WEEKLY: frequency = dateAbbrev[1].toLowerCase(); break; case MONTHLY: frequency = dateAbbrev[2].toLowerCase(); break; case HOURLY: frequency = dateAbbrev[3].toLowerCase(); break; case MINUTELY: frequency = dateAbbrev[4].toLowerCase(); break; case YEARLY: frequency = dateAbbrev[5].toLowerCase(); } if (!TextUtils.isEmpty(frequency)) { String date = String.format("%s %s", rrule.getInterval(), frequency); //$NON-NLS-1$ return String.format(context.getString(R.string.repeat_detail_duedate), date).toLowerCase(); // Every freq int } } catch (ParseException e) { // Eh } return ""; } }