Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java b/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java |
| index bca0f01b39ea86a09228f2609fa261fbfba54414..b26e7454e515a54d64ae78c849f97a56b9d0b53b 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java |
| +++ b/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java |
| @@ -15,7 +15,12 @@ import android.content.DialogInterface.OnDismissListener; |
| import android.text.TextUtils; |
| import android.text.format.DateFormat; |
| import android.text.format.Time; |
| +import android.view.View; |
| +import android.widget.AdapterView; |
| import android.widget.DatePicker; |
| +import android.widget.ListView; |
| +import android.widget.SimpleAdapter; |
| +import android.widget.TextView; |
| import android.widget.TimePicker; |
| import org.chromium.content.browser.input.DateTimePickerDialog.OnDateTimeSetListener; |
| @@ -23,17 +28,22 @@ import org.chromium.content.browser.input.MultiFieldTimePickerDialog.OnMultiFiel |
| import org.chromium.content.browser.input.TwoFieldDatePickerDialog; |
| import org.chromium.content.R; |
| +import java.util.Arrays; |
| import java.text.ParseException; |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.Date; |
| +import java.util.List; |
| +import java.util.Map; |
| +import java.util.HashMap; |
| +import java.util.TimeZone; |
| +import java.util.ArrayList; |
| public class InputDialogContainer { |
| interface InputActionDelegate { |
| void cancelDateTimeDialog(); |
| - void replaceDateTime(int dialogType, |
| - int year, int month, int day, int hour, int minute, int second, int milli, int week); |
| + void replaceDateTime(double value); |
| } |
| // Default values used in Time representations of selected date/time before formatting. |
| @@ -45,22 +55,12 @@ public class InputDialogContainer { |
| private static final int MINUTE_DEFAULT = 0; |
| private static final int WEEK_DEFAULT = 0; |
| - // Date formats as accepted by Time.format. |
| - private static final String HTML_DATE_FORMAT = "%Y-%m-%d"; |
| - private static final String HTML_TIME_FORMAT = "%H:%M"; |
| - // For datetime we always send selected time as UTC, as we have no timezone selector. |
| - // This is consistent with other browsers. |
| - private static final String HTML_DATE_TIME_FORMAT = "%Y-%m-%dT%H:%MZ"; |
| - private static final String HTML_DATE_TIME_LOCAL_FORMAT = "%Y-%m-%dT%H:%M"; |
| - private static final String HTML_MONTH_FORMAT = "%Y-%m"; |
| - private static final String HTML_WEEK_FORMAT = "%Y-%w"; |
| - |
| - private static int sTextInputTypeDate; |
| - private static int sTextInputTypeDateTime; |
| - private static int sTextInputTypeDateTimeLocal; |
| - private static int sTextInputTypeMonth; |
| - private static int sTextInputTypeTime; |
| - private static int sTextInputTypeWeek; |
| + public static int sTextInputTypeDate; |
| + public static int sTextInputTypeDateTime; |
| + public static int sTextInputTypeDateTimeLocal; |
| + public static int sTextInputTypeMonth; |
| + public static int sTextInputTypeTime; |
| + public static int sTextInputTypeWeek; |
| private Context mContext; |
| @@ -93,26 +93,91 @@ public class InputDialogContainer { |
| mInputActionDelegate = inputActionDelegate; |
| } |
| - private Time normalizeTime(int year, int month, int monthDay, |
| - int hour, int minute, int second) { |
| + private Time currentTime() { |
| Time result = new Time(); |
| - if (year == 0 && month == 0 && monthDay == 0 && hour == 0 && |
| - minute == 0 && second == 0) { |
| - Calendar cal = Calendar.getInstance(); |
| - result.set(cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE), |
| - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.DATE), |
| - cal.get(Calendar.MONTH), cal.get(Calendar.YEAR)); |
| - } else { |
| - result.set(second, minute, hour, monthDay, month, year); |
| - } |
| + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); |
| + result.set(cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE), |
| + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.DATE), |
| + cal.get(Calendar.MONTH), cal.get(Calendar.YEAR)); |
| return result; |
| } |
| - void showDialog(final int dialogType, int year, int month, int monthDay, |
| - int hour, int minute, int second, int milli, int week, |
| - double min, double max, double step) { |
| - if (isDialogShowing()) mDialog.dismiss(); |
| + void showSuggestionDialog(final int dialogType, |
| + final double value, |
| + final double min, final double max, final double step, |
| + DateTimeSuggestion[] suggestions) { |
| + ListView suggestionListView = new ListView(mContext); |
| + final DateTimeSuggestionListAdapter adapter = |
| + new DateTimeSuggestionListAdapter(mContext, Arrays.asList(suggestions)); |
| + suggestionListView.setAdapter(adapter); |
| + suggestionListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { |
| + @Override |
| + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
| + if (position == adapter.getCount() - 1) { |
| + dismissDialog(); |
| + showPickerDialog(dialogType, value, min, max, step); |
| + } else { |
| + double suggestionValue = adapter.getItem(position).value; |
| + mInputActionDelegate.replaceDateTime(suggestionValue); |
| + dismissDialog(); |
| + mDialogAlreadyDismissed = true; |
| + } |
| + } |
| + }); |
| + |
| + int dialogTitleId = R.string.date_picker_dialog_title; |
| + if (dialogType == sTextInputTypeTime) { |
| + dialogTitleId = R.string.time_picker_dialog_title; |
| + } else if (dialogType == sTextInputTypeDateTime || |
| + dialogType == sTextInputTypeDateTimeLocal) { |
| + dialogTitleId = R.string.date_time_picker_dialog_title; |
| + } else if (dialogType == sTextInputTypeMonth) { |
| + dialogTitleId = R.string.month_picker_dialog_title; |
| + } else if (dialogType == sTextInputTypeWeek) { |
| + dialogTitleId = R.string.week_picker_dialog_title; |
| + } |
| + |
| + mDialog = new AlertDialog.Builder(mContext) |
| + .setTitle(dialogTitleId) |
| + .setView(suggestionListView) |
| + .setOnDismissListener(new DialogInterface.OnDismissListener() { |
| + @Override |
| + public void onDismiss(DialogInterface dialog) { |
| + if (mDialog == dialog && !mDialogAlreadyDismissed) { |
| + mDialogAlreadyDismissed = true; |
| + mInputActionDelegate.cancelDateTimeDialog(); |
| + } |
| + } |
| + }) |
| + .setNegativeButton(mContext.getText(android.R.string.cancel), |
| + new DialogInterface.OnClickListener() { |
| + @Override |
| + public void onClick(DialogInterface dialog, int which) { |
| + dismissDialog(); |
| + } |
| + }) |
| + .create(); |
| + |
| + mDialogAlreadyDismissed = false; |
| + mDialog.show(); |
| + } |
| + void showDialog(final int type, final double value, |
| + double min, double max, double step, |
| + DateTimeSuggestion[] suggestions) { |
| + // When the web page asks to show a dialog while there is one already open, |
| + // dismiss the old one. |
| + dismissDialog(); |
| + if (suggestions == null) { |
| + showPickerDialog(type, value, min, max, step); |
| + } else { |
| + showSuggestionDialog(type, value, |
|
newt (away)
2013/11/04 17:35:55
can this fit on one line?
keishi
2013/11/05 07:23:42
Done.
|
| + min, max, step, suggestions); |
| + } |
| + } |
| + |
| + void showPickerDialog(final int dialogType, final double value, |
| + double min, double max, double step) { |
| // Java Date dialogs like longs but Blink prefers doubles.. |
| // Both parameters mean different things depending on the type |
| // For input type=month min and max come as number on months since 1970 |
| @@ -122,11 +187,15 @@ public class InputDialogContainer { |
| long maxTime = (long) max; |
| int stepTime = (int) step; |
| - if (milli > 1000) { |
| - second += milli / 1000; |
| - milli %= 1000; |
| + Time time; |
| + int milli = 0; |
| + if (Double.isNaN(value)) { |
| + time = currentTime(); |
| + } else { |
| + time = new Time(); |
| + time.set((long) value); |
| + milli = (int) value % 1000; |
|
newt (away)
2013/11/04 17:35:55
This should be:
milli = ((long) value) % 1000
keishi
2013/11/05 07:23:42
Done.
|
| } |
| - Time time = normalizeTime(year, month, monthDay, hour, minute, second); |
| if (dialogType == sTextInputTypeDate) { |
| DatePickerDialog dialog = new DatePickerDialog(mContext, |
| new DateListener(dialogType), time.year, time.month, time.monthDay); |
| @@ -153,11 +222,12 @@ public class InputDialogContainer { |
| mDialog = new MonthPickerDialog(mContext, new MonthOrWeekListener(dialogType), |
| time.year, time.month, minTime, maxTime); |
| } else if (dialogType == sTextInputTypeWeek) { |
| - if (week == 0) { |
| - Calendar cal = Calendar.getInstance(); |
| - year = WeekPicker.getISOWeekYearForDate(cal); |
| - week = WeekPicker.getWeekForDate(cal); |
| + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); |
| + if (value > 0) { |
| + cal.setTimeInMillis((long) value); |
| } |
| + int year = WeekPicker.getISOWeekYearForDate(cal); |
| + int week = WeekPicker.getWeekForDate(cal); |
| mDialog = new WeekPickerDialog(mContext, new MonthOrWeekListener(dialogType), |
| year, week, minTime, maxTime); |
| } |
| @@ -176,7 +246,7 @@ public class InputDialogContainer { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| mDialogAlreadyDismissed = true; |
| - mInputActionDelegate.replaceDateTime(dialogType, 0, 0, 0, 0, 0, 0, 0, 0); |
| + mInputActionDelegate.replaceDateTime(Double.NaN); |
| } |
| }); |
| @@ -212,27 +282,12 @@ public class InputDialogContainer { |
| @Override |
| public void onDateSet(DatePicker view, int year, int month, int monthDay) { |
| if (!mDialogAlreadyDismissed) { |
| - setFieldDateTimeValue(mDialogType, |
| - year, month, monthDay, |
| - HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT, |
| - HTML_DATE_FORMAT); |
| - } |
| - } |
| - } |
| - |
| - private class TimeListener implements OnTimeSetListener { |
| - private final int mDialogType; |
| - |
| - TimeListener(int dialogType) { |
| - mDialogType = dialogType; |
| - } |
| - |
| - @Override |
| - public void onTimeSet(TimePicker view, int hourOfDay, int minute) { |
| - if (!mDialogAlreadyDismissed) { |
| - setFieldDateTimeValue(mDialogType, |
| - YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT, |
| - hourOfDay, minute, WEEK_DEFAULT, HTML_TIME_FORMAT); |
| + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); |
| + cal.clear(); |
| + cal.set(Calendar.YEAR, year); |
| + cal.set(Calendar.MONTH, month); |
| + cal.set(Calendar.DAY_OF_MONTH, monthDay); |
| + setFieldDateTimeValue((double) cal.getTimeInMillis()); |
| } |
| } |
| } |
| @@ -246,9 +301,8 @@ public class InputDialogContainer { |
| @Override |
| public void onTimeSet(int hourOfDay, int minute, int second, int milli) { |
| if (!mDialogAlreadyDismissed) { |
| - setFieldDateTimeValue(mDialogType, |
| - YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT, |
| - hourOfDay, minute, second, milli, WEEK_DEFAULT, HTML_TIME_FORMAT); |
| + setFieldDateTimeValue( |
| + (double) ((hourOfDay * 60 + minute) * 60 + second) * 1000 + milli); |
| } |
| } |
| } |
| @@ -267,9 +321,14 @@ public class InputDialogContainer { |
| int year, int month, int monthDay, |
| int hourOfDay, int minute) { |
| if (!mDialogAlreadyDismissed) { |
| - setFieldDateTimeValue(mDialogType, year, month, monthDay, |
| - hourOfDay, minute, WEEK_DEFAULT, |
| - mLocal ? HTML_DATE_TIME_LOCAL_FORMAT : HTML_DATE_TIME_FORMAT); |
| + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); |
| + cal.clear(); |
| + cal.set(Calendar.YEAR, year); |
| + cal.set(Calendar.MONTH, month); |
| + cal.set(Calendar.DAY_OF_MONTH, monthDay); |
| + cal.set(Calendar.HOUR_OF_DAY, hourOfDay); |
| + cal.set(Calendar.MINUTE, minute); |
| + setFieldDateTimeValue((double) cal.getTimeInMillis()); |
| } |
| } |
| } |
| @@ -282,39 +341,18 @@ public class InputDialogContainer { |
| } |
| @Override |
| - public void onValueSet(int year, int positionInYear) { |
| + public void onValueSet(double value) { |
| if (!mDialogAlreadyDismissed) { |
| - if (mDialogType == sTextInputTypeMonth) { |
| - setFieldDateTimeValue(mDialogType, year, positionInYear, MONTHDAY_DEFAULT, |
| - HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT, |
| - HTML_MONTH_FORMAT); |
| - } else { |
| - setFieldDateTimeValue(mDialogType, year, MONTH_DEFAULT, MONTHDAY_DEFAULT, |
| - HOUR_DEFAULT, MINUTE_DEFAULT, positionInYear, HTML_WEEK_FORMAT); |
| - } |
| + setFieldDateTimeValue(value); |
| } |
| } |
| } |
| - private void setFieldDateTimeValue(int dialogType, |
| - int year, int month, int monthDay, int hourOfDay, |
| - int minute, int week, String dateFormat) { |
| - // Prevents more than one callback being sent to the native |
| - // side when the dialog triggers multiple events. |
| - mDialogAlreadyDismissed = true; |
| - |
| - mInputActionDelegate.replaceDateTime(dialogType, |
| - year, month, monthDay, hourOfDay, minute, 0 /* second */, 0 /* milli */, week); |
| - } |
| - |
| - private void setFieldDateTimeValue(int dialogType, |
| - int year, int month, int monthDay, int hourOfDay, |
| - int minute, int second, int milli, int week, String dateFormat) { |
| + private void setFieldDateTimeValue(double value) { |
| // Prevents more than one callback being sent to the native |
| // side when the dialog triggers multiple events. |
| mDialogAlreadyDismissed = true; |
| - mInputActionDelegate.replaceDateTime( |
| - dialogType, year, month, monthDay, hourOfDay, minute, second, milli, week); |
| + mInputActionDelegate.replaceDateTime(value); |
| } |
| } |