| 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..40779907bcbac7d71f2af14d7847ec2e1e9ebe3c 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,90 @@ 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, 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 +186,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) (((long) value) % 1000);
|
| }
|
| - 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 +221,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 +245,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 +281,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 +300,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 +320,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 +340,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);
|
| }
|
| }
|
|
|