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

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.TimeZone;
24 25
25 public class InputDialogContainer { 26 public class InputDialogContainer {
26 27
27 interface InputActionDelegate { 28 interface InputActionDelegate {
28 void cancelDateTimeDialog(); 29 void cancelDateTimeDialog();
29 void replaceDateTime(int dialogType, 30 void replaceDateTime(double value);
30 int year, int month, int day, int hour, int minute, int second, int milli, int week);
31 } 31 }
32 32
33 // Default values used in Time representations of selected date/time before formatting. 33 // Default values used in Time representations of selected date/time before formatting.
34 // They are never displayed to the user. 34 // They are never displayed to the user.
35 private static final int YEAR_DEFAULT = 1970; 35 private static final int YEAR_DEFAULT = 1970;
36 private static final int MONTH_DEFAULT = 0; 36 private static final int MONTH_DEFAULT = 0;
37 private static final int MONTHDAY_DEFAULT = 1; 37 private static final int MONTHDAY_DEFAULT = 1;
38 private static final int HOUR_DEFAULT = 0; 38 private static final int HOUR_DEFAULT = 0;
39 private static final int MINUTE_DEFAULT = 0; 39 private static final int MINUTE_DEFAULT = 0;
40 private static final int WEEK_DEFAULT = 0; 40 private static final int WEEK_DEFAULT = 0;
41 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; 42 private static int sTextInputTypeDate;
53 private static int sTextInputTypeDateTime; 43 private static int sTextInputTypeDateTime;
54 private static int sTextInputTypeDateTimeLocal; 44 private static int sTextInputTypeDateTimeLocal;
55 private static int sTextInputTypeMonth; 45 private static int sTextInputTypeMonth;
56 private static int sTextInputTypeTime; 46 private static int sTextInputTypeTime;
57 private static int sTextInputTypeWeek; 47 private static int sTextInputTypeWeek;
58 48
59 private final Context mContext; 49 private final Context mContext;
60 50
61 // Prevents sending two notifications (from onClick and from onDismiss) 51 // Prevents sending two notifications (from onClick and from onDismiss)
(...skipping 18 matching lines...) Expand all
80 return type == sTextInputTypeDate || type == sTextInputTypeTime 70 return type == sTextInputTypeDate || type == sTextInputTypeTime
81 || type == sTextInputTypeDateTime || type == sTextInputTypeDateT imeLocal 71 || type == sTextInputTypeDateTime || type == sTextInputTypeDateT imeLocal
82 || type == sTextInputTypeMonth || type == sTextInputTypeWeek; 72 || type == sTextInputTypeMonth || type == sTextInputTypeWeek;
83 } 73 }
84 74
85 InputDialogContainer(Context context, InputActionDelegate inputActionDelegat e) { 75 InputDialogContainer(Context context, InputActionDelegate inputActionDelegat e) {
86 mContext = context; 76 mContext = context;
87 mInputActionDelegate = inputActionDelegate; 77 mInputActionDelegate = inputActionDelegate;
88 } 78 }
89 79
90 private Time normalizeTime(int year, int month, int monthDay, 80 void showDialog(final int dialogType, double dialogValue,
91 int hour, int minute, int second) { 81 double min, double max, double step) {
92 Time result = new Time();
93 if (year == 0 && month == 0 && monthDay == 0 && hour == 0 &&
94 minute == 0 && second == 0) {
95 Calendar cal = Calendar.getInstance();
96 result.set(cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE),
97 cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.DATE),
98 cal.get(Calendar.MONTH), cal.get(Calendar.YEAR));
99 } else {
100 result.set(second, minute, hour, monthDay, month, year);
101 }
102 return result;
103 }
104
105 void showDialog(final int dialogType, int year, int month, int monthDay,
106 int hour, int minute, int second, int milli, int week,
107 double min, double max, double step) {
108 if (isDialogShowing()) mDialog.dismiss(); 82 if (isDialogShowing()) mDialog.dismiss();
109 83
110 // Java Date dialogs like longs but Blink prefers doubles.. 84 // Java Date dialogs like longs but Blink prefers doubles..
111 // Both parameters mean different things depending on the type 85 // Both parameters mean different things depending on the type
112 // For input type=month min and max come as number on months since 1970 86 // 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 87 // 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. 88 // In any case the cast here is safe given the above restrictions.
115 long minTime = (long) min; 89 long minTime = (long) min;
116 long maxTime = (long) max; 90 long maxTime = (long) max;
117 int stepTime = (int) step; 91 int stepTime = (int) step;
118 92
119 if (milli > 1000) { 93 Calendar cal;
120 second += milli / 1000; 94 // If |dialogValue| is NaN it means an empty value. We will show the cur rent time.
121 milli %= 1000; 95 if (Double.isNaN(dialogValue)) {
Miguel Garcia 2013/11/26 16:07:08 I would really like to see a test that checks that
keishi 2013/11/27 06:58:37 I separated out the double to year/month/date... c
Miguel Garcia 2013/11/27 11:17:24 Here is an example you can base the test on https
keishi 2013/11/29 03:30:14 Thanks I was able to add a test (InputDialogContai
96 cal = Calendar.getInstance();
Miguel Garcia 2013/11/26 16:07:08 How do you pass Nan via JNI BTW?
keishi 2013/11/27 06:58:37 I'm not sure what you mean. NaN is passed from C++
Miguel Garcia 2013/11/27 11:17:24 Nevermind this works out of the box as you say On
97 cal.set(Calendar.MILLISECOND, 0);
98 } else {
99 cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
100 if (dialogType == sTextInputTypeMonth) {
Miguel Garcia 2013/11/26 16:07:08 please document why month is special.
keishi 2013/11/27 06:58:37 Done.
101 cal.set(Calendar.YEAR, (int) (dialogValue / 12));
102 cal.set(Calendar.MONTH, (int) (dialogValue % 12));
103 } else {
104 cal.setTimeInMillis((long) dialogValue);
105 }
122 } 106 }
123 Time time = normalizeTime(year, month, monthDay, hour, minute, second);
124 if (dialogType == sTextInputTypeDate) { 107 if (dialogType == sTextInputTypeDate) {
125 DatePickerDialog dialog = new DatePickerDialog(mContext, 108 DatePickerDialog dialog = new DatePickerDialog(mContext,
126 new DateListener(dialogType), time.year, time.month, time.mo nthDay); 109 new DateListener(dialogType),
110 cal.get(Calendar.YEAR),
111 cal.get(Calendar.MONTH),
112 cal.get(Calendar.DAY_OF_MONTH));
127 DateDialogNormalizer.normalize(dialog.getDatePicker(), dialog, 113 DateDialogNormalizer.normalize(dialog.getDatePicker(), dialog,
128 time.year, time.month, time.monthDay, 0, 0, minTime, maxTime ); 114 cal.get(Calendar.YEAR),
115 cal.get(Calendar.MONTH),
116 cal.get(Calendar.DAY_OF_MONTH),
117 0, 0,
118 minTime, maxTime);
129 119
130 dialog.setTitle(mContext.getText(R.string.date_picker_dialog_title)) ; 120 dialog.setTitle(mContext.getText(R.string.date_picker_dialog_title)) ;
131 mDialog = dialog; 121 mDialog = dialog;
132 } else if (dialogType == sTextInputTypeTime) { 122 } else if (dialogType == sTextInputTypeTime) {
133 mDialog = new MultiFieldTimePickerDialog( 123 mDialog = new MultiFieldTimePickerDialog(
134 mContext, 0 /* theme */ , 124 mContext, 0 /* theme */ ,
135 time.hour, time.minute, time.second, milli, 125 cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
126 cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND),
136 (int) minTime, (int) maxTime, stepTime, 127 (int) minTime, (int) maxTime, stepTime,
137 DateFormat.is24HourFormat(mContext), 128 DateFormat.is24HourFormat(mContext),
138 new FullTimeListener(dialogType)); 129 new FullTimeListener(dialogType));
139 } else if (dialogType == sTextInputTypeDateTime || 130 } else if (dialogType == sTextInputTypeDateTime ||
140 dialogType == sTextInputTypeDateTimeLocal) { 131 dialogType == sTextInputTypeDateTimeLocal) {
141 mDialog = new DateTimePickerDialog(mContext, 132 mDialog = new DateTimePickerDialog(mContext,
142 new DateTimeListener(dialogType), 133 new DateTimeListener(dialogType),
143 time.year, time.month, time.monthDay, 134 cal.get(Calendar.YEAR),
144 time.hour, time.minute, DateFormat.is24HourFormat(mContext), 135 cal.get(Calendar.MONTH),
145 minTime, maxTime); 136 cal.get(Calendar.DAY_OF_MONTH),
137 cal.get(Calendar.HOUR_OF_DAY),
138 cal.get(Calendar.MINUTE),
139 DateFormat.is24HourFormat(mContext), minTime, maxTime);
146 } else if (dialogType == sTextInputTypeMonth) { 140 } else if (dialogType == sTextInputTypeMonth) {
147 mDialog = new MonthPickerDialog(mContext, new MonthOrWeekListener(di alogType), 141 mDialog = new MonthPickerDialog(mContext, new MonthOrWeekListener(di alogType),
148 time.year, time.month, minTime, maxTime); 142 cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), minTime, ma xTime);
149 } else if (dialogType == sTextInputTypeWeek) { 143 } else if (dialogType == sTextInputTypeWeek) {
150 if (week == 0) { 144 int year = WeekPicker.getISOWeekYearForDate(cal);
151 Calendar cal = Calendar.getInstance(); 145 int week = WeekPicker.getWeekForDate(cal);
152 year = WeekPicker.getISOWeekYearForDate(cal);
153 week = WeekPicker.getWeekForDate(cal);
154 }
155 mDialog = new WeekPickerDialog(mContext, new MonthOrWeekListener(dia logType), 146 mDialog = new WeekPickerDialog(mContext, new MonthOrWeekListener(dia logType),
156 year, week, minTime, maxTime); 147 year, week, minTime, maxTime);
157 } 148 }
158 149
159 mDialog.setButton(DialogInterface.BUTTON_POSITIVE, 150 mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
160 mContext.getText(R.string.date_picker_dialog_set), 151 mContext.getText(R.string.date_picker_dialog_set),
161 (DialogInterface.OnClickListener) mDialog); 152 (DialogInterface.OnClickListener) mDialog);
162 153
163 mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, 154 mDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
164 mContext.getText(android.R.string.cancel), 155 mContext.getText(android.R.string.cancel),
165 (DialogInterface.OnClickListener) null); 156 (DialogInterface.OnClickListener) null);
166 157
167 mDialog.setButton(DialogInterface.BUTTON_NEUTRAL, 158 mDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
168 mContext.getText(R.string.date_picker_dialog_clear), 159 mContext.getText(R.string.date_picker_dialog_clear),
169 new DialogInterface.OnClickListener() { 160 new DialogInterface.OnClickListener() {
170 @Override 161 @Override
171 public void onClick(DialogInterface dialog, int which) { 162 public void onClick(DialogInterface dialog, int which) {
172 mDialogAlreadyDismissed = true; 163 mDialogAlreadyDismissed = true;
173 mInputActionDelegate.replaceDateTime(dialogType, 0, 0, 0 , 0, 0, 0, 0, 0); 164 mInputActionDelegate.replaceDateTime(Double.NaN);
174 } 165 }
175 }); 166 });
176 167
177 mDialog.setOnDismissListener( 168 mDialog.setOnDismissListener(
178 new OnDismissListener() { 169 new OnDismissListener() {
179 @Override 170 @Override
180 public void onDismiss(final DialogInterface dialog) { 171 public void onDismiss(final DialogInterface dialog) {
181 if (!mDialogAlreadyDismissed) { 172 if (!mDialogAlreadyDismissed) {
182 mDialogAlreadyDismissed = true; 173 mDialogAlreadyDismissed = true;
183 mInputActionDelegate.cancelDateTimeDialog(); 174 mInputActionDelegate.cancelDateTimeDialog();
(...skipping 16 matching lines...) Expand all
200 private class DateListener implements OnDateSetListener { 191 private class DateListener implements OnDateSetListener {
201 private final int mDialogType; 192 private final int mDialogType;
202 193
203 DateListener(int dialogType) { 194 DateListener(int dialogType) {
204 mDialogType = dialogType; 195 mDialogType = dialogType;
205 } 196 }
206 197
207 @Override 198 @Override
208 public void onDateSet(DatePicker view, int year, int month, int monthDay ) { 199 public void onDateSet(DatePicker view, int year, int month, int monthDay ) {
209 if (!mDialogAlreadyDismissed) { 200 if (!mDialogAlreadyDismissed) {
210 setFieldDateTimeValue(mDialogType, 201 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")) ;
211 year, month, monthDay, 202 cal.clear();
212 HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT, 203 cal.set(Calendar.YEAR, year);
213 HTML_DATE_FORMAT); 204 cal.set(Calendar.MONTH, month);
205 cal.set(Calendar.DAY_OF_MONTH, monthDay);
206 setFieldDateTimeValue((double) cal.getTimeInMillis());
214 } 207 }
215 } 208 }
216 } 209 }
217
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 210
235 private class FullTimeListener implements OnMultiFieldTimeSetListener { 211 private class FullTimeListener implements OnMultiFieldTimeSetListener {
236 private final int mDialogType; 212 private final int mDialogType;
237 FullTimeListener(int dialogType) { 213 FullTimeListener(int dialogType) {
238 mDialogType = dialogType; 214 mDialogType = dialogType;
239 } 215 }
240 216
241 @Override 217 @Override
242 public void onTimeSet(int hourOfDay, int minute, int second, int milli) { 218 public void onTimeSet(int hourOfDay, int minute, int second, int milli) {
243 if (!mDialogAlreadyDismissed) { 219 if (!mDialogAlreadyDismissed) {
244 setFieldDateTimeValue(mDialogType, 220 setFieldDateTimeValue(
245 YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT, 221 (double) ((hourOfDay * 60 + minute) * 60 + second) * 100 0 + milli);
Miguel Garcia 2013/11/26 16:07:08 Use TimeUnit(HOUR).toMillis() + TimeUnit.MINUTE(mi
keishi 2013/11/27 06:58:37 Done.
246 hourOfDay, minute, second, milli, WEEK_DEFAULT, HTML_TIM E_FORMAT);
247 } 222 }
Miguel Garcia 2013/11/26 16:07:08 You are not setting mDialogAlreadyDismissed in the
keishi 2013/11/27 06:58:37 Done.
248 } 223 }
249 } 224 }
250 225
251 private class DateTimeListener implements OnDateTimeSetListener { 226 private class DateTimeListener implements OnDateTimeSetListener {
252 private final boolean mLocal; 227 private final boolean mLocal;
253 private final int mDialogType; 228 private final int mDialogType;
254 229
255 public DateTimeListener(int dialogType) { 230 public DateTimeListener(int dialogType) {
256 mLocal = dialogType == sTextInputTypeDateTimeLocal; 231 mLocal = dialogType == sTextInputTypeDateTimeLocal;
257 mDialogType = dialogType; 232 mDialogType = dialogType;
258 } 233 }
259 234
260 @Override 235 @Override
261 public void onDateTimeSet(DatePicker dateView, TimePicker timeView, 236 public void onDateTimeSet(DatePicker dateView, TimePicker timeView,
262 int year, int month, int monthDay, 237 int year, int month, int monthDay,
263 int hourOfDay, int minute) { 238 int hourOfDay, int minute) {
264 if (!mDialogAlreadyDismissed) { 239 if (!mDialogAlreadyDismissed) {
265 setFieldDateTimeValue(mDialogType, year, month, monthDay, 240 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")) ;
266 hourOfDay, minute, WEEK_DEFAULT, 241 cal.clear();
267 mLocal ? HTML_DATE_TIME_LOCAL_FORMAT : HTML_DATE_TIME_FO RMAT); 242 cal.set(Calendar.YEAR, year);
243 cal.set(Calendar.MONTH, month);
244 cal.set(Calendar.DAY_OF_MONTH, monthDay);
245 cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
246 cal.set(Calendar.MINUTE, minute);
247 setFieldDateTimeValue((double) cal.getTimeInMillis());
268 } 248 }
269 } 249 }
270 } 250 }
271 251
272 private class MonthOrWeekListener implements TwoFieldDatePickerDialog.OnValu eSetListener { 252 private class MonthOrWeekListener implements TwoFieldDatePickerDialog.OnValu eSetListener {
273 private final int mDialogType; 253 private final int mDialogType;
274 254
275 MonthOrWeekListener(int dialogType) { 255 MonthOrWeekListener(int dialogType) {
276 mDialogType = dialogType; 256 mDialogType = dialogType;
277 } 257 }
278 258
279 @Override 259 @Override
280 public void onValueSet(int year, int positionInYear) { 260 public void onValueSet(double value) {
281 if (!mDialogAlreadyDismissed) { 261 if (!mDialogAlreadyDismissed) {
282 if (mDialogType == sTextInputTypeMonth) { 262 setFieldDateTimeValue(value);
283 setFieldDateTimeValue(mDialogType, year, positionInYear, MON THDAY_DEFAULT,
284 HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT,
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 } 263 }
291 } 264 }
292 } 265 }
293 266
294 private void setFieldDateTimeValue(int dialogType, 267 private void setFieldDateTimeValue(double value) {
295 int year, int month, int monthDay, int hourOfDay,
296 int minute, int week, String dateFormat) {
297 // Prevents more than one callback being sent to the native 268 // Prevents more than one callback being sent to the native
298 // side when the dialog triggers multiple events. 269 // side when the dialog triggers multiple events.
299 mDialogAlreadyDismissed = true; 270 mDialogAlreadyDismissed = true;
300 271
301 mInputActionDelegate.replaceDateTime(dialogType, 272 mInputActionDelegate.replaceDateTime(value);
302 year, month, monthDay, hourOfDay, minute, 0 /* second */, 0 /* milli */, week);
303 }
304
305 private void setFieldDateTimeValue(int dialogType,
306 int year, int month, int monthDay, int hourOfDay,
307 int minute, int second, int milli, int week, String dateFormat) {
308 // Prevents more than one callback being sent to the native
309 // side when the dialog triggers multiple events.
310 mDialogAlreadyDismissed = true;
311
312 mInputActionDelegate.replaceDateTime(
313 dialogType, year, month, monthDay, hourOfDay, minute, second, milli, week);
314 } 273 }
315 } 274 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698