Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java

Issue 85643002: Transfer date/time value to chooser as double (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@doubledate2
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.content.browser.input; 5 package org.chromium.content.browser.input;
6 6
7 import android.app.AlertDialog; 7 import android.app.AlertDialog;
8 import android.app.DatePickerDialog; 8 import android.app.DatePickerDialog;
9 import android.app.DatePickerDialog.OnDateSetListener; 9 import android.app.DatePickerDialog.OnDateSetListener;
10 import android.app.TimePickerDialog.OnTimeSetListener; 10 import android.app.TimePickerDialog.OnTimeSetListener;
11 import android.content.Context; 11 import android.content.Context;
12 import android.content.DialogInterface; 12 import android.content.DialogInterface;
13 import android.content.DialogInterface.OnDismissListener; 13 import android.content.DialogInterface.OnDismissListener;
14 import android.text.format.DateFormat; 14 import android.text.format.DateFormat;
15 import android.text.format.Time; 15 import android.text.format.Time;
16 import android.widget.DatePicker; 16 import android.widget.DatePicker;
17 import android.widget.TimePicker; 17 import android.widget.TimePicker;
18 18
19 import org.chromium.content.R; 19 import org.chromium.content.R;
20 import org.chromium.content.browser.input.DateTimePickerDialog.OnDateTimeSetList ener; 20 import org.chromium.content.browser.input.DateTimePickerDialog.OnDateTimeSetList ener;
21 import org.chromium.content.browser.input.MultiFieldTimePickerDialog.OnMultiFiel dTimeSetListener; 21 import org.chromium.content.browser.input.MultiFieldTimePickerDialog.OnMultiFiel dTimeSetListener;
22 22
23 import java.util.Calendar; 23 import java.util.Calendar;
24 import java.util.Date;
25 import java.util.GregorianCalendar;
26 import java.util.TimeZone;
27 import java.util.concurrent.TimeUnit;
24 28
25 public class InputDialogContainer { 29 public class InputDialogContainer {
26 30
27 interface InputActionDelegate { 31 interface InputActionDelegate {
28 void cancelDateTimeDialog(); 32 void cancelDateTimeDialog();
29 void replaceDateTime(int dialogType, 33 void replaceDateTime(double value);
30 int year, int month, int day, int hour, int minute, int second, int milli, int week);
31 } 34 }
32 35
33 // Default values used in Time representations of selected date/time before formatting.
34 // They are never displayed to the user.
35 private static final int YEAR_DEFAULT = 1970;
36 private static final int MONTH_DEFAULT = 0;
37 private static final int MONTHDAY_DEFAULT = 1;
38 private static final int HOUR_DEFAULT = 0;
39 private static final int MINUTE_DEFAULT = 0;
40 private static final int WEEK_DEFAULT = 0;
41
42 // Date formats as accepted by Time.format.
43 private static final String HTML_DATE_FORMAT = "%Y-%m-%d";
44 private static final String HTML_TIME_FORMAT = "%H:%M";
45 // For datetime we always send selected time as UTC, as we have no timezone selector.
46 // This is consistent with other browsers.
47 private static final String HTML_DATE_TIME_FORMAT = "%Y-%m-%dT%H:%MZ";
48 private static final String HTML_DATE_TIME_LOCAL_FORMAT = "%Y-%m-%dT%H:%M";
49 private static final String HTML_MONTH_FORMAT = "%Y-%m";
50 private static final String HTML_WEEK_FORMAT = "%Y-%w";
51
52 private static int sTextInputTypeDate; 36 private static int sTextInputTypeDate;
53 private static int sTextInputTypeDateTime; 37 private static int sTextInputTypeDateTime;
54 private static int sTextInputTypeDateTimeLocal; 38 private static int sTextInputTypeDateTimeLocal;
55 private static int sTextInputTypeMonth; 39 private static int sTextInputTypeMonth;
56 private static int sTextInputTypeTime; 40 private static int sTextInputTypeTime;
57 private static int sTextInputTypeWeek; 41 private static int sTextInputTypeWeek;
58 42
59 private final Context mContext; 43 private final Context mContext;
60 44
61 // Prevents sending two notifications (from onClick and from onDismiss) 45 // Prevents sending two notifications (from onClick and from onDismiss)
(...skipping 18 matching lines...) Expand all
80 return type == sTextInputTypeDate || type == sTextInputTypeTime 64 return type == sTextInputTypeDate || type == sTextInputTypeTime
81 || type == sTextInputTypeDateTime || type == sTextInputTypeDateT imeLocal 65 || type == sTextInputTypeDateTime || type == sTextInputTypeDateT imeLocal
82 || type == sTextInputTypeMonth || type == sTextInputTypeWeek; 66 || type == sTextInputTypeMonth || type == sTextInputTypeWeek;
83 } 67 }
84 68
85 InputDialogContainer(Context context, InputActionDelegate inputActionDelegat e) { 69 InputDialogContainer(Context context, InputActionDelegate inputActionDelegat e) {
86 mContext = context; 70 mContext = context;
87 mInputActionDelegate = inputActionDelegate; 71 mInputActionDelegate = inputActionDelegate;
88 } 72 }
89 73
90 private Time normalizeTime(int year, int month, int monthDay, 74 void showDialog(final int dialogType, double dialogValue,
91 int hour, int minute, int second) { 75 double min, double max, double step) {
92 Time result = new Time(); 76 Calendar cal;
93 if (year == 0 && month == 0 && monthDay == 0 && hour == 0 && 77 // |dialogValue|, |min|, |max| mean different things depending on the |d ialogType|.
94 minute == 0 && second == 0) { 78 // For input type=month is the number of months since 1970.
95 Calendar cal = Calendar.getInstance(); 79 // For input type=time it is milliseconds since midnight.
96 result.set(cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE), 80 // For other types they are just milliseconds since 1970.
97 cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.DATE), 81 // If |dialogValue| is NaN it means an empty value. We will show the cur rent time.
98 cal.get(Calendar.MONTH), cal.get(Calendar.YEAR)); 82 if (Double.isNaN(dialogValue)) {
83 cal = Calendar.getInstance();
84 cal.set(Calendar.MILLISECOND, 0);
99 } else { 85 } else {
100 result.set(second, minute, hour, monthDay, month, year); 86 if (dialogType == sTextInputTypeMonth) {
87 cal = MonthPicker.createDateFromValue(dialogValue);
88 } else if (dialogType == sTextInputTypeWeek) {
89 cal = WeekPicker.createDateFromValue(dialogValue);
90 } else {
91 GregorianCalendar gregorianCalendar =
92 new GregorianCalendar(TimeZone.getTimeZone("UTC"));
93 // According to the HTML spec we only use the Gregorian calendar
94 // so we ignore the Julian/Gregorian transition.
95 gregorianCalendar.setGregorianChange(new Date(Long.MIN_VALUE));
96 gregorianCalendar.setTimeInMillis((long) dialogValue);
97 cal = gregorianCalendar;
98 }
101 } 99 }
102 return result; 100 if (dialogType == sTextInputTypeDate) {
101 showDialog(dialogType,
102 cal.get(Calendar.YEAR),
103 cal.get(Calendar.MONTH),
104 cal.get(Calendar.DAY_OF_MONTH),
105 0, 0, 0, 0, 0, min, max, step);
106 } else if (dialogType == sTextInputTypeTime) {
107 showDialog(dialogType, 0, 0, 0,
108 cal.get(Calendar.HOUR_OF_DAY),
109 cal.get(Calendar.MINUTE),
110 0, 0, 0, min, max, step);
111 } else if (dialogType == sTextInputTypeDateTime ||
112 dialogType == sTextInputTypeDateTimeLocal) {
113 showDialog(dialogType,
114 cal.get(Calendar.YEAR),
115 cal.get(Calendar.MONTH),
116 cal.get(Calendar.DAY_OF_MONTH),
117 cal.get(Calendar.HOUR_OF_DAY),
118 cal.get(Calendar.MINUTE),
119 cal.get(Calendar.SECOND),
120 cal.get(Calendar.MILLISECOND),
121 0, min, max, step);
122 } else if (dialogType == sTextInputTypeMonth) {
123 showDialog(dialogType, cal.get(Calendar.YEAR), cal.get(Calendar.MONT H), 0,
124 0, 0, 0, 0, 0, min, max, step);
125 } else if (dialogType == sTextInputTypeWeek) {
126 int year = WeekPicker.getISOWeekYearForDate(cal);
127 int week = WeekPicker.getWeekForDate(cal);
128 showDialog(dialogType, year, 0, 0, 0, 0, 0, 0, week, min, max, step) ;
129 }
103 } 130 }
104 131
105 void showDialog(final int dialogType, int year, int month, int monthDay, 132 void showDialog(final int dialogType,
106 int hour, int minute, int second, int milli, int week, 133 int year, int month, int monthDay,
107 double min, double max, double step) { 134 int hourOfDay, int minute, int second, int millis, int week,
135 double min, double max, double step) {
108 if (isDialogShowing()) mDialog.dismiss(); 136 if (isDialogShowing()) mDialog.dismiss();
109 137
110 // Java Date dialogs like longs but Blink prefers doubles..
111 // Both parameters mean different things depending on the type
112 // For input type=month min and max come as number on months since 1970
113 // For other types (including type=time) they are just milliseconds sinc e 1970
114 // In any case the cast here is safe given the above restrictions.
115 long minTime = (long) min;
116 long maxTime = (long) max;
117 int stepTime = (int) step; 138 int stepTime = (int) step;
118 139
119 if (milli > 1000) {
120 second += milli / 1000;
121 milli %= 1000;
122 }
123 Time time = normalizeTime(year, month, monthDay, hour, minute, second);
124 if (dialogType == sTextInputTypeDate) { 140 if (dialogType == sTextInputTypeDate) {
125 DatePickerDialog dialog = new DatePickerDialog(mContext, 141 DatePickerDialog dialog = new DatePickerDialog(mContext,
126 new DateListener(dialogType), time.year, time.month, time.mo nthDay); 142 new DateListener(dialogType),
143 year, month, monthDay);
127 DateDialogNormalizer.normalize(dialog.getDatePicker(), dialog, 144 DateDialogNormalizer.normalize(dialog.getDatePicker(), dialog,
128 time.year, time.month, time.monthDay, 0, 0, minTime, maxTime ); 145 year, month, monthDay,
146 0, 0,
147 (long) min, (long) max);
129 148
130 dialog.setTitle(mContext.getText(R.string.date_picker_dialog_title)) ; 149 dialog.setTitle(mContext.getText(R.string.date_picker_dialog_title)) ;
131 mDialog = dialog; 150 mDialog = dialog;
132 } else if (dialogType == sTextInputTypeTime) { 151 } else if (dialogType == sTextInputTypeTime) {
133 mDialog = new MultiFieldTimePickerDialog( 152 mDialog = new MultiFieldTimePickerDialog(
134 mContext, 0 /* theme */ , 153 mContext, 0 /* theme */ ,
135 time.hour, time.minute, time.second, milli, 154 hourOfDay, minute, second, millis,
136 (int) minTime, (int) maxTime, stepTime, 155 (int) min, (int) max, stepTime,
137 DateFormat.is24HourFormat(mContext), 156 DateFormat.is24HourFormat(mContext),
138 new FullTimeListener(dialogType)); 157 new FullTimeListener(dialogType));
139 } else if (dialogType == sTextInputTypeDateTime || 158 } else if (dialogType == sTextInputTypeDateTime ||
140 dialogType == sTextInputTypeDateTimeLocal) { 159 dialogType == sTextInputTypeDateTimeLocal) {
141 mDialog = new DateTimePickerDialog(mContext, 160 mDialog = new DateTimePickerDialog(mContext,
142 new DateTimeListener(dialogType), 161 new DateTimeListener(dialogType),
143 time.year, time.month, time.monthDay, 162 year, month, monthDay,
144 time.hour, time.minute, DateFormat.is24HourFormat(mContext), 163 hourOfDay, minute,
145 minTime, maxTime); 164 DateFormat.is24HourFormat(mContext), min, max);
146 } else if (dialogType == sTextInputTypeMonth) { 165 } else if (dialogType == sTextInputTypeMonth) {
147 mDialog = new MonthPickerDialog(mContext, new MonthOrWeekListener(di alogType), 166 mDialog = new MonthPickerDialog(mContext, new MonthOrWeekListener(di alogType),
148 time.year, time.month, minTime, maxTime); 167 year, month, min, max);
149 } else if (dialogType == sTextInputTypeWeek) { 168 } else if (dialogType == sTextInputTypeWeek) {
150 if (week == 0) {
151 Calendar cal = Calendar.getInstance();
152 year = WeekPicker.getISOWeekYearForDate(cal);
153 week = WeekPicker.getWeekForDate(cal);
154 }
155 mDialog = new WeekPickerDialog(mContext, new MonthOrWeekListener(dia logType), 169 mDialog = new WeekPickerDialog(mContext, new MonthOrWeekListener(dia logType),
156 year, week, minTime, maxTime); 170 year, week, min, max);
157 } 171 }
158 172
159 mDialog.setButton(DialogInterface.BUTTON_POSITIVE, 173 mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
160 mContext.getText(R.string.date_picker_dialog_set), 174 mContext.getText(R.string.date_picker_dialog_set),
161 (DialogInterface.OnClickListener) mDialog); 175 (DialogInterface.OnClickListener) mDialog);
162 176
163 mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, 177 mDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
164 mContext.getText(android.R.string.cancel), 178 mContext.getText(android.R.string.cancel),
165 (DialogInterface.OnClickListener) null); 179 (DialogInterface.OnClickListener) null);
166 180
167 mDialog.setButton(DialogInterface.BUTTON_NEUTRAL, 181 mDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
168 mContext.getText(R.string.date_picker_dialog_clear), 182 mContext.getText(R.string.date_picker_dialog_clear),
169 new DialogInterface.OnClickListener() { 183 new DialogInterface.OnClickListener() {
170 @Override 184 @Override
171 public void onClick(DialogInterface dialog, int which) { 185 public void onClick(DialogInterface dialog, int which) {
172 mDialogAlreadyDismissed = true; 186 mDialogAlreadyDismissed = true;
173 mInputActionDelegate.replaceDateTime(dialogType, 0, 0, 0 , 0, 0, 0, 0, 0); 187 mInputActionDelegate.replaceDateTime(Double.NaN);
174 } 188 }
175 }); 189 });
176 190
177 mDialog.setOnDismissListener( 191 mDialog.setOnDismissListener(
178 new OnDismissListener() { 192 new OnDismissListener() {
179 @Override 193 @Override
180 public void onDismiss(final DialogInterface dialog) { 194 public void onDismiss(final DialogInterface dialog) {
181 if (!mDialogAlreadyDismissed) { 195 if (!mDialogAlreadyDismissed) {
182 mDialogAlreadyDismissed = true; 196 mDialogAlreadyDismissed = true;
183 mInputActionDelegate.cancelDateTimeDialog(); 197 mInputActionDelegate.cancelDateTimeDialog();
(...skipping 15 matching lines...) Expand all
199 213
200 private class DateListener implements OnDateSetListener { 214 private class DateListener implements OnDateSetListener {
201 private final int mDialogType; 215 private final int mDialogType;
202 216
203 DateListener(int dialogType) { 217 DateListener(int dialogType) {
204 mDialogType = dialogType; 218 mDialogType = dialogType;
205 } 219 }
206 220
207 @Override 221 @Override
208 public void onDateSet(DatePicker view, int year, int month, int monthDay ) { 222 public void onDateSet(DatePicker view, int year, int month, int monthDay ) {
209 if (!mDialogAlreadyDismissed) { 223 setFieldDateTimeValue(mDialogType, year, month, monthDay, 0, 0, 0, 0 , 0);
210 setFieldDateTimeValue(mDialogType,
211 year, month, monthDay,
212 HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT,
213 HTML_DATE_FORMAT);
214 }
215 } 224 }
216 } 225 }
217 226
218 private class TimeListener implements OnTimeSetListener {
219 private final int mDialogType;
220
221 TimeListener(int dialogType) {
222 mDialogType = dialogType;
223 }
224
225 @Override
226 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
227 if (!mDialogAlreadyDismissed) {
228 setFieldDateTimeValue(mDialogType,
229 YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT,
230 hourOfDay, minute, WEEK_DEFAULT, HTML_TIME_FORMAT);
231 }
232 }
233 }
234
235 private class FullTimeListener implements OnMultiFieldTimeSetListener { 227 private class FullTimeListener implements OnMultiFieldTimeSetListener {
236 private final int mDialogType; 228 private final int mDialogType;
237 FullTimeListener(int dialogType) { 229 FullTimeListener(int dialogType) {
238 mDialogType = dialogType; 230 mDialogType = dialogType;
239 } 231 }
240 232
241 @Override 233 @Override
242 public void onTimeSet(int hourOfDay, int minute, int second, int milli) { 234 public void onTimeSet(int hourOfDay, int minute, int second, int milli) {
243 if (!mDialogAlreadyDismissed) { 235 setFieldDateTimeValue(mDialogType, 0, 0, 0, hourOfDay, minute, secon d, milli, 0);
244 setFieldDateTimeValue(mDialogType,
245 YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT,
246 hourOfDay, minute, second, milli, WEEK_DEFAULT, HTML_TIM E_FORMAT);
247 }
248 } 236 }
249 } 237 }
250 238
251 private class DateTimeListener implements OnDateTimeSetListener { 239 private class DateTimeListener implements OnDateTimeSetListener {
252 private final boolean mLocal; 240 private final boolean mLocal;
253 private final int mDialogType; 241 private final int mDialogType;
254 242
255 public DateTimeListener(int dialogType) { 243 public DateTimeListener(int dialogType) {
256 mLocal = dialogType == sTextInputTypeDateTimeLocal; 244 mLocal = dialogType == sTextInputTypeDateTimeLocal;
257 mDialogType = dialogType; 245 mDialogType = dialogType;
258 } 246 }
259 247
260 @Override 248 @Override
261 public void onDateTimeSet(DatePicker dateView, TimePicker timeView, 249 public void onDateTimeSet(DatePicker dateView, TimePicker timeView,
262 int year, int month, int monthDay, 250 int year, int month, int monthDay,
263 int hourOfDay, int minute) { 251 int hourOfDay, int minute) {
264 if (!mDialogAlreadyDismissed) { 252 setFieldDateTimeValue(mDialogType, year, month, monthDay, hourOfDay, minute, 0, 0, 0);
265 setFieldDateTimeValue(mDialogType, year, month, monthDay,
266 hourOfDay, minute, WEEK_DEFAULT,
267 mLocal ? HTML_DATE_TIME_LOCAL_FORMAT : HTML_DATE_TIME_FO RMAT);
268 }
269 } 253 }
270 } 254 }
271 255
272 private class MonthOrWeekListener implements TwoFieldDatePickerDialog.OnValu eSetListener { 256 private class MonthOrWeekListener implements TwoFieldDatePickerDialog.OnValu eSetListener {
273 private final int mDialogType; 257 private final int mDialogType;
274 258
275 MonthOrWeekListener(int dialogType) { 259 MonthOrWeekListener(int dialogType) {
276 mDialogType = dialogType; 260 mDialogType = dialogType;
277 } 261 }
278 262
279 @Override 263 @Override
280 public void onValueSet(int year, int positionInYear) { 264 public void onValueSet(int year, int positionInYear) {
281 if (!mDialogAlreadyDismissed) { 265 if (mDialogType == sTextInputTypeMonth) {
282 if (mDialogType == sTextInputTypeMonth) { 266 setFieldDateTimeValue(mDialogType, year, positionInYear, 0, 0, 0 , 0, 0, 0);
283 setFieldDateTimeValue(mDialogType, year, positionInYear, MON THDAY_DEFAULT, 267 } else {
284 HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT, 268 setFieldDateTimeValue(mDialogType, year, 0, 0, 0, 0, 0, 0, posit ionInYear);
285 HTML_MONTH_FORMAT);
286 } else {
287 setFieldDateTimeValue(mDialogType, year, MONTH_DEFAULT, MONT HDAY_DEFAULT,
288 HOUR_DEFAULT, MINUTE_DEFAULT, positionInYear, HTML_W EEK_FORMAT);
289 }
290 } 269 }
291 } 270 }
292 } 271 }
293 272
294 private void setFieldDateTimeValue(int dialogType, 273 protected void setFieldDateTimeValue(int dialogType,
295 int year, int month, int monthDay, int hourOfDay, 274 int year, int month, int monthDay,
296 int minute, int week, String dateFormat) { 275 int hourOfDay, int minute, int second, in t millis,
276 int week) {
297 // Prevents more than one callback being sent to the native 277 // Prevents more than one callback being sent to the native
298 // side when the dialog triggers multiple events. 278 // side when the dialog triggers multiple events.
279 if (mDialogAlreadyDismissed)
280 return;
299 mDialogAlreadyDismissed = true; 281 mDialogAlreadyDismissed = true;
300 282
301 mInputActionDelegate.replaceDateTime(dialogType, 283 double value = 0;
302 year, month, monthDay, hourOfDay, minute, 0 /* second */, 0 /* milli */, week); 284 if (dialogType == sTextInputTypeMonth) {
303 } 285 mInputActionDelegate.replaceDateTime((year - 1970) * 12 + month);
304 286 } else if (dialogType == sTextInputTypeWeek) {
305 private void setFieldDateTimeValue(int dialogType, 287 mInputActionDelegate.replaceDateTime(
306 int year, int month, int monthDay, int hourOfDay, 288 WeekPicker.createDateFromWeek(year, week).getTimeInMillis());
307 int minute, int second, int milli, int week, String dateFormat) { 289 } else if (dialogType == sTextInputTypeTime) {
308 // Prevents more than one callback being sent to the native 290 mInputActionDelegate.replaceDateTime(TimeUnit.HOURS.toMillis(hourOfD ay) +
309 // side when the dialog triggers multiple events. 291 TimeUnit.MINUTES.toMillis(minut e) +
310 mDialogAlreadyDismissed = true; 292 TimeUnit.SECONDS.toMillis(secon d) +
311 293 millis);
312 mInputActionDelegate.replaceDateTime( 294 } else {
313 dialogType, year, month, monthDay, hourOfDay, minute, second, milli, week); 295 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
296 cal.clear();
297 cal.set(Calendar.YEAR, year);
298 cal.set(Calendar.MONTH, month);
299 cal.set(Calendar.DAY_OF_MONTH, monthDay);
300 cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
301 cal.set(Calendar.MINUTE, minute);
302 cal.set(Calendar.SECOND, second);
303 cal.set(Calendar.MILLISECOND, millis);
304 mInputActionDelegate.replaceDateTime((double) cal.getTimeInMillis()) ;
305 }
314 } 306 }
315 } 307 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698