fixup! Replacing deprecated 'efl-assist' with 'efl-extension'
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / browser / inputpicker / InputPicker.cc
1 // Copyright 2014 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "InputPicker.h"
6
7 #include "base/path_service.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/time/time.h"
11 #include "common/web_contents_utils.h"
12 #include "content/common/paths_efl.h"
13 #include "content/public/browser/web_contents.h"
14 #include "eweb_view.h"
15
16 #include <math.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include <Elementary.h>
21 #if defined(OS_TIZEN)
22 #include <vconf/vconf.h>
23 #include <dlfcn.h>
24 #include <efl_extension.h>
25 extern void* EflExtensionHandle;
26 #endif
27
28 namespace content {
29
30 static const unsigned maxDatetimeLength = 32;
31 static const unsigned maxDateStringLength = 10;
32 static const char defaultDatetimeFormat[] = "%Y/%m/%d %H:%M";
33
34 struct InputPicker::Layout {
35   Layout(Evas_Object *ewkView)
36     : ewk_view_(ewkView)
37     , parent(elm_object_top_widget_get(elm_object_parent_widget_get(ewk_view_)))
38     , popup(0)
39     , layout(0)
40     , datePicker(0)
41     , time_picker(0)
42     , color_picker(0)
43     , color_rect(0)
44     , dataListEditField(0)
45     , initial_r(0)
46     , initial_g(0)
47     , initial_b(0)
48     , datetime_local(false) {
49     evas_object_focus_set(ewk_view_, false);
50
51     /* FIXME : Workaround. OSP requirement.
52        OSP want to block own touch event while webkit internal picker is running. */
53     evas_object_smart_callback_call(ewk_view_, "input,picker,show", 0);
54   }
55
56   bool BuildColorSelector();
57   bool CreateColorSelector();
58   bool CreateOKButton();
59   void SetPopupSize(int width, int height);
60
61   base::FilePath GetLayoutFilePath() {
62     base::FilePath edj_dir;
63     base::FilePath control_edj;
64     PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
65     control_edj = edj_dir.Append(FILE_PATH_LITERAL("control.edj"));
66     return control_edj;
67   }
68
69   ~Layout() {
70     /* FIXME : Workaround. OSP requirement.
71        OSP want to block own touch event while webkit internal picker is running. */
72     evas_object_smart_callback_call(ewk_view_, "input,picker,hide", 0);
73
74     evas_object_focus_set(ewk_view_, true);
75   }
76
77   Evas_Object* ewk_view_;
78   Evas_Object* parent;
79   Evas_Object* popup;
80   Evas_Object* layout;
81   Evas_Object* datePicker;
82   Evas_Object* time_picker;
83   Evas_Object* color_picker;
84   Evas_Object* color_rect;
85   Evas_Object* okButton;
86   Evas_Object* dataListEditField;
87   int initial_r;
88   int initial_g;
89   int initial_b;
90   bool datetime_local;
91 };
92
93 bool InputPicker::Layout::BuildColorSelector() {
94   /* add color palette widget */
95   color_picker = elm_colorselector_add(layout);
96   if (!color_picker)
97     return false;
98
99   elm_colorselector_mode_set(color_picker, ELM_COLORSELECTOR_PALETTE);
100   evas_object_size_hint_fill_set(color_picker, EVAS_HINT_FILL, EVAS_HINT_FILL);
101   evas_object_size_hint_weight_set(color_picker, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
102
103 #if defined(OS_TIZEN_TV)
104   elm_colorselector_color_set(color_picker, initial_r, initial_g, initial_b, 255);
105 #else
106   Eina_List* color_list = const_cast<Eina_List*>
107       (elm_colorselector_palette_items_get(color_picker));
108   Eina_List* list = 0;
109   void* item = 0;
110   int r = 0;
111   int g = 0;
112   int b = 0;
113   int a = 0;
114   Elm_Object_Item* it = NULL;
115
116   EINA_LIST_FOREACH(color_list, list, item) {
117     if (item) {
118       elm_colorselector_palette_item_color_get((Elm_Object_Item*)item, &r, &g, &b, &a);
119       if (r == initial_r && g == initial_g && b == initial_b) {
120         it = (Elm_Object_Item*)item;
121         break;
122       }
123     }
124   }
125
126   if (!it)
127     it = (Elm_Object_Item*)eina_list_nth(color_list, 0);
128
129   elm_object_item_signal_emit((Elm_Object_Item*)it, "elm,state,selected", "elm");
130 #endif
131
132   elm_object_part_content_set(layout, "colorpalette", color_picker);
133   return true;
134 }
135
136 bool InputPicker::Layout::CreateOKButton() {
137   okButton = elm_button_add(popup);
138   if (!okButton)
139     return false;
140
141   elm_object_style_set(okButton, "popup");
142   elm_object_text_set(okButton, "OK");
143   elm_object_part_content_set(popup, "button1", okButton);
144   evas_object_focus_set(okButton, true);
145   return true;
146 }
147
148 void InputPicker::Layout::SetPopupSize(int width, int height) {
149   if(popup) {
150     evas_object_resize(popup, width, height);
151     evas_object_move(popup, 0, 0);
152   }
153 }
154
155 bool InputPicker::Layout::CreateColorSelector() {
156   popup = elm_popup_add(parent);
157   if (!popup)
158     return false;
159
160   elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
161   elm_object_part_text_set(popup, "title,text", "Select color");
162   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
163
164   base::FilePath control_edj = GetLayoutFilePath();
165
166   layout = elm_layout_add(popup);
167   if (!layout)
168     return false;
169
170   elm_layout_file_set(layout, control_edj.AsUTF8Unsafe().c_str(),
171       "colorselector_popup_layout");
172   evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
173   evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
174
175   color_rect = evas_object_rectangle_add(evas_object_evas_get(layout));
176
177   if (color_rect) {
178     evas_object_size_hint_weight_set(color_rect,
179     EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
180     evas_object_show(color_rect);
181     evas_object_color_set(color_rect, initial_r, initial_g, initial_b, 255);
182     elm_object_part_content_set(layout, "rect", color_rect);
183   }
184
185   BuildColorSelector();
186
187   evas_object_show(layout);
188   elm_object_content_set(popup, layout);
189   return CreateOKButton();
190 }
191
192 struct ColorPopupUserData {
193   InputPicker* inputPicker;
194   Evas_Object* colorRect;
195   Evas_Object* color;
196   Evas_Object* colorAccessObject;
197 };
198
199 struct Input_Date {
200   int year;
201   int mon;
202   int day;
203   int hour;
204   int min;
205   int sec;
206 };
207
208 struct Input_Date_Str {
209   char year[maxDateStringLength];
210   char mon[maxDateStringLength];
211   char day[maxDateStringLength];
212   char hour[maxDateStringLength];
213   char min[maxDateStringLength];
214   char sec[maxDateStringLength];
215 };
216
217 static char* datetimeFormat() {
218 #if defined(OS_TIZEN)
219   char* datetimeFormat = NULL;
220   char* regionFormat = NULL;
221   char* language = NULL;
222   char buf[256] = { 0, };
223   int timeValue = 0;
224   int isHour24 = 0;
225   int returnValue = 0;
226
227   language = getenv("LANGUAGE");
228   setenv("LANGUAGE", "en_US", 1);
229
230   regionFormat = vconf_get_str(VCONFKEY_REGIONFORMAT);
231   if (!regionFormat)
232     return 0;
233
234   returnValue = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &timeValue);
235   if (returnValue < 0)
236     isHour24 = 0;
237   else if (timeValue == VCONFKEY_TIME_FORMAT_12 ||
238       timeValue == VCONFKEY_TIME_FORMAT_24)
239     isHour24 = timeValue - 1;
240
241   if (isHour24)
242     snprintf(buf, sizeof(buf), "%s_DTFMT_24HR", regionFormat);
243   else
244     snprintf(buf, sizeof(buf), "%s_DTFMT_12HR", regionFormat);
245
246   free(regionFormat);
247
248   // FIXME: Workaround fix for region format.
249   int bufLength = strlen(buf);
250   for (int i = 0; i < bufLength - 4; i++) {
251     if (buf[i] == 'u' && buf[i + 1] == 't' && buf[i + 2] == 'f') {
252       if (buf[i + 3] == '8') {
253         // utf8 -> UTF-8
254         for (int j = bufLength; j > i + 3; j--)
255           buf[j] = buf[j - 1];
256         buf[i + 3] = '-';
257         buf[bufLength + 1] = '\0';
258       } else if (buf[i + 3] == '-' && buf[i + 4] == '8') {
259         // utf-8 -> UTF-8
260       } else {
261         break;
262       }
263
264       buf[i] = 'U';
265       buf[i + 1] = 'T';
266       buf[i + 2] = 'F';
267       break;
268     }
269   }
270
271   datetimeFormat = dgettext("dt_fmt", buf);
272
273   if(!language || !strcmp(language, ""))
274     unsetenv("LANGUAGE");
275   else
276     setenv("LANGUAGE", language, 1);
277
278   // FIXME: Workaround fix for not supported dt_fmt.
279   // Use default format if dt_fmt string is not exist.
280   if (strlen(datetimeFormat) == strlen(buf) &&
281       !strncmp(datetimeFormat, buf, strlen(buf))) {
282     return 0;
283   }
284
285   return strdup(datetimeFormat);
286 #else
287   return NULL;
288 #endif
289 }
290
291 InputPicker::InputPicker(EWebView& web_view_)
292     : web_view_(web_view_)
293     , ewk_view_(web_view_.evas_object())
294     , picker_layout_(0)
295     , data_list_(0) {
296 }
297
298 InputPicker::~InputPicker() {
299   if (picker_layout_) {
300     if (picker_layout_->popup)
301       evas_object_del(picker_layout_->popup);
302     delete picker_layout_;
303   }
304 }
305
306 void InputPicker::SetPopupSize(int width, int height) {
307   if (picker_layout_)
308     picker_layout_->SetPopupSize(width, height);
309 }
310
311 #if defined(OS_TIZEN_MOBILE)
312 void InputPicker::endEditingCallback(
313     void* data, Evas_Object* obj, void* event_info)
314 {
315   InputPicker* inputPicker = static_cast<InputPicker*>(data);
316   if (inputPicker)
317     inputPicker->removeDatetimePickerDelayed();
318 }
319 #endif
320
321 void InputPicker::showDatePicker(ui::TextInputType input_type, double input_date)
322 {
323   web_view_.ExecuteEditCommand("Unselect", 0);
324
325   time_t timep;
326   struct tm tm;
327   struct tm* currentTime;
328
329   if (!std::isfinite(input_date)) {
330     time(&timep);
331     currentTime = localtime(&timep);
332   } else if (input_type == ui::TEXT_INPUT_TYPE_MONTH) {
333     // when type is month, input_date is number of month since epoch
334     unsigned int year = floor(input_date / 12.0) + 1970.0;
335     unsigned int month = input_date - (year - 1970) * 12 + 1;
336     CHECK(month <= 12);
337
338     char date[12];
339     snprintf(date, 12, "%d-%d", year, month);
340
341     char* last_char = strptime(date, "%Y-%m", &tm);
342     DCHECK(last_char);
343
344     currentTime = &tm;
345   } else {
346     // in all other cases, input_date is number of milliseconds since epoch
347     base::Time doubleT = base::Time::FromDoubleT(input_date/1000);
348     timep = doubleT.ToTimeT();
349     currentTime = gmtime(&timep);
350   }
351
352   switch (input_type) {
353     case ui::TEXT_INPUT_TYPE_DATE:
354       showDatePopup(currentTime);
355       break;
356     case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD:
357     case ui::TEXT_INPUT_TYPE_DATE_TIME:
358       showDatetimePopup(currentTime, false /*datetime*/);
359       break;
360     case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL:
361       showDatetimePopup(currentTime, true /* datetime_local */);
362       break;
363     case ui::TEXT_INPUT_TYPE_TIME:
364       showTimePopup(currentTime);
365       break;
366     case ui::TEXT_INPUT_TYPE_WEEK:
367       showWeekPopup(currentTime);
368       break;
369     case ui::TEXT_INPUT_TYPE_MONTH:
370       showMonthPopup(currentTime);
371       break;
372     default:
373       break;
374   }
375 }
376
377 void InputPicker::ColorPickerKeyUpCallback(void* data, Evas*, Evas_Object* obj, void* event_info) {
378   Evas_Event_Key_Up* key_struct = static_cast<Evas_Event_Key_Up*>(event_info);
379   if (!web_contents_utils::MapsToHWBackKey(key_struct->keyname))
380     return;
381
382   HandleBackKeyColorPicker(data, obj, event_info);
383 }
384
385 void InputPicker::ShowColorPicker(int r, int g, int b, int alpha) {
386   if (picker_layout_) {
387     elm_colorselector_color_set(picker_layout_->color_picker, r, g, b, alpha);
388     evas_object_focus_set(picker_layout_->okButton, true);
389     evas_object_show(picker_layout_->layout);
390     return;
391   }
392
393   picker_layout_ = new InputPicker::Layout(ewk_view_);
394
395   picker_layout_->initial_r = r;
396   picker_layout_->initial_g = g;
397   picker_layout_->initial_b = b;
398
399   picker_layout_->CreateColorSelector();
400
401   evas_object_smart_callback_add(picker_layout_->color_picker,
402       "color,item,selected",
403       SelectedColorCallback,
404       picker_layout_->color_rect);
405 #if defined(OS_TIZEN)
406   eext_object_event_callback_add(picker_layout_->popup, EEXT_CALLBACK_BACK,
407       HandleBackKeyColorPicker, this);
408 #endif
409   evas_object_event_callback_add(picker_layout_->popup, EVAS_CALLBACK_KEY_UP,
410                                  ColorPickerKeyUpCallback, this);
411
412   evas_object_smart_callback_add(
413       picker_layout_->okButton,
414       "clicked",
415       ColorPickerCallback,
416       this);
417
418   evas_object_show(picker_layout_->popup);
419 }
420
421 void InputPicker::HideColorPicker() {
422   if (!picker_layout_)
423     return;
424
425   web_view_.web_contents().DidEndColorChooser();
426
427   if (picker_layout_->popup) {
428     evas_object_del(picker_layout_->popup);
429     picker_layout_->popup = 0;
430   }
431
432   delete picker_layout_;
433   picker_layout_ = 0;
434 }
435
436 void InputPicker::SelectedColorCallback(
437     void* data, Evas_Object* obj, void* event_info) {
438   int r = 0;
439   int g = 0;
440   int b = 0;
441   int a = 0;
442
443   Elm_Object_Item *color_it = static_cast<Elm_Object_Item *>(event_info);
444   elm_colorselector_palette_item_color_get(color_it, &r, &g, &b, &a);
445   evas_object_color_set(static_cast<Evas_Object*>(data), r, g, b, a);
446 }
447
448 void InputPicker::ColorPickerCallback(
449     void* data,  Evas_Object* obj, void* event_info) {
450   InputPicker* inputPicker = static_cast<InputPicker*>(data);
451
452   int r(0), g(0), b(0), a(0);
453   evas_object_color_get(inputPicker->picker_layout_->color_rect, &r, &g, &b, &a);
454
455   inputPicker->web_view_.web_contents().DidChooseColorInColorChooser(
456       SkColorSetARGB(a, r, g, b));
457   inputPicker->HideColorPicker();
458 }
459
460 void InputPicker::HandleBackKeyColorPicker(
461     void* data,  Evas_Object* obj, void* event_info) {
462   InputPicker* inputPicker = static_cast<InputPicker*>(data);
463
464   int r = inputPicker->picker_layout_->initial_r;
465   int g = inputPicker->picker_layout_->initial_g;
466   int b = inputPicker->picker_layout_->initial_b;
467   int a = 255;
468
469   inputPicker->web_view_.web_contents().DidChooseColorInColorChooser(
470       SkColorSetARGB(a, r, g, b));
471
472   inputPicker->HideColorPicker();
473 }
474
475 void InputPicker::showDatePopup(struct tm* currentTime) {
476   if (picker_layout_) {
477     // Just update the value.
478     elm_datetime_value_set(picker_layout_->datePicker, currentTime);
479     evas_object_focus_set(picker_layout_->okButton, true);
480     return;
481   }
482
483   picker_layout_ = new InputPicker::Layout(ewk_view_);
484   CreatePopupLayout(dgettext("WebKit","IDS_WEBVIEW_HEADER_SET_DATE"),
485       currentTime);
486
487   picker_layout_->CreateOKButton();
488
489   evas_object_smart_callback_add(
490       picker_layout_->okButton, "clicked", datePopupCallback, this);
491   elm_object_content_set(picker_layout_->popup, picker_layout_->layout);
492   evas_object_show(picker_layout_->popup);
493 }
494
495 void InputPicker::showWeekPopup(struct tm* currentTime) {
496   if (picker_layout_) {
497     // Just update the value.
498     elm_datetime_value_set(picker_layout_->datePicker, currentTime);
499     evas_object_focus_set(picker_layout_->okButton, true);
500     return;
501   }
502
503   picker_layout_ = new InputPicker::Layout(ewk_view_);
504   CreatePopupLayout(dgettext("WebKit","IDS_WEBVIEW_HEADER_SET_WEEK"),
505       currentTime);
506
507   picker_layout_->CreateOKButton();
508
509   evas_object_smart_callback_add(
510       picker_layout_->okButton, "clicked", weekPopupCallback, this);
511   elm_object_content_set(picker_layout_->popup, picker_layout_->layout);
512   evas_object_show(picker_layout_->popup);
513 }
514
515 void InputPicker::showTimePopup(struct tm* currentTime) {
516   if (picker_layout_) {
517     // Just update the value.
518     elm_datetime_value_set(picker_layout_->time_picker, currentTime);
519     evas_object_focus_set(picker_layout_->okButton, true);
520     return;
521   }
522
523   picker_layout_ = new InputPicker::Layout(ewk_view_);
524   CreateTimePopupLayout(dgettext("WebKit","IDS_WEBVIEW_HEADER_SET_TIME"),
525       currentTime);
526
527   picker_layout_->CreateOKButton();
528
529   evas_object_smart_callback_add(
530       picker_layout_->okButton, "clicked", timePopupCallback, this);
531   elm_object_content_set(picker_layout_->popup, picker_layout_->layout);
532   evas_object_show(picker_layout_->popup);
533 }
534
535 void InputPicker::showMonthPopup(struct tm* currentTime) {
536   if (picker_layout_) {
537     // Just update the value.
538     elm_datetime_value_set(picker_layout_->datePicker, currentTime);
539     evas_object_focus_set(picker_layout_->okButton, true);
540     return;
541   }
542
543   picker_layout_ = new InputPicker::Layout(ewk_view_);
544   CreatePopupLayout(dgettext("WebKit","IDS_WEBVIEW_HEADER_SET_MONTH"),
545       currentTime);
546
547   picker_layout_->CreateOKButton();
548
549   evas_object_smart_callback_add(
550       picker_layout_->okButton, "clicked", monthPopupCallback, this);
551   elm_object_content_set(picker_layout_->popup, picker_layout_->layout);
552   evas_object_show(picker_layout_->popup);
553 }
554
555 void InputPicker::showDatetimePopup(struct tm* currentTime, bool datetime_local) {
556   if (picker_layout_) {
557     // Just update the value.
558     picker_layout_->datetime_local = datetime_local;
559
560     elm_datetime_value_set(picker_layout_->datePicker, currentTime);
561     evas_object_focus_set(picker_layout_->okButton, true);
562     return;
563   }
564
565   picker_layout_ = new InputPicker::Layout(ewk_view_);
566   picker_layout_->datetime_local = datetime_local;
567
568   CreateDateTimePopupLayout(
569       dgettext("WebKit","IDS_WEBVIEW_HEADER_SET_DATE_AND_TIME"), currentTime);
570
571   picker_layout_->CreateOKButton();
572
573   evas_object_smart_callback_add(
574       picker_layout_->okButton, "clicked", datetimePopupCallback, this);
575   evas_object_smart_callback_add(
576       picker_layout_->datePicker, "changed", datetimeChangedCallback, this);
577   evas_object_smart_callback_add(
578       picker_layout_->time_picker, "changed", datetimeChangedCallback, this);
579
580   elm_object_content_set(picker_layout_->popup, picker_layout_->layout);
581   evas_object_show(picker_layout_->popup);
582
583 }
584
585 Eina_Bool InputPicker::removeDatetimePicker(void* data) {
586   InputPicker* inputPicker = static_cast<InputPicker*>(data);
587   inputPicker->web_view_.web_contents().DidCancelDialog();
588
589   if (!inputPicker->picker_layout_)
590     return ECORE_CALLBACK_CANCEL;
591
592   inputPicker->web_view_.ExecuteEditCommand("Unselect", 0);
593
594   inputPicker->deletePopupLayout();
595   delete inputPicker->picker_layout_;
596   inputPicker->picker_layout_ = 0;
597
598   return ECORE_CALLBACK_CANCEL;
599 }
600
601 void InputPicker::removeDatetimePickerDelayed() {
602   ecore_timer_add(0.1, removeDatetimePicker, this);
603 }
604
605 void InputPicker::DatePickerKeyUpCallback(void* data, Evas*, Evas_Object* obj, void* event_info) {
606   Evas_Event_Key_Up* key_struct = static_cast<Evas_Event_Key_Up*>(event_info);
607   if (!web_contents_utils::MapsToHWBackKey(key_struct->keyname))
608     return;
609
610   HandleBackKeyDatePicker(data, obj, event_info);
611 }
612
613 void InputPicker::CreatePopupLayout(const char* title, struct tm* currentTime) {
614   picker_layout_->popup = elm_popup_add(picker_layout_->parent);
615   evas_object_size_hint_weight_set(
616       picker_layout_->popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
617   elm_object_part_text_set(picker_layout_->popup, "title,text", title);
618
619 #if defined(OS_TIZEN)
620   if (EflExtensionHandle) {
621     void (*webkit_eext_object_event_callback_add)(
622         Evas_Object *, Eext_Callback_Type , Eext_Event_Cb func, void *);
623     webkit_eext_object_event_callback_add = (void (*)(
624         Evas_Object *,
625         Eext_Callback_Type ,
626         Eext_Event_Cb func,
627         void *)) dlsym(EflExtensionHandle, "eext_object_event_callback_add");
628     (*webkit_eext_object_event_callback_add)(
629         picker_layout_->popup, EEXT_CALLBACK_BACK, HandleBackKeyDatePicker, this);
630   }
631 #endif
632   evas_object_event_callback_add(picker_layout_->popup, EVAS_CALLBACK_KEY_UP,
633                                  DatePickerKeyUpCallback, this);
634
635   base::FilePath edj_dir;
636   base::FilePath control_edj;
637   PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
638   control_edj = edj_dir.Append(FILE_PATH_LITERAL("control.edj"));
639
640
641   picker_layout_->layout = elm_layout_add(picker_layout_->popup);
642   elm_layout_file_set(
643       picker_layout_->layout,
644       control_edj.AsUTF8Unsafe().c_str(),
645       "date_popup");
646   evas_object_size_hint_weight_set(
647       picker_layout_->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
648
649   picker_layout_->datePicker = elm_datetime_add(picker_layout_->layout);
650   elm_object_part_content_set(
651       picker_layout_->layout,
652       "elm.swallow.datetime",
653       picker_layout_->datePicker);
654
655   char* format = datetimeFormat();
656   if (format) {
657     elm_datetime_format_set(picker_layout_->datePicker, format);
658     free(format);
659   } else {
660     elm_datetime_format_set(picker_layout_->datePicker, defaultDatetimeFormat);
661   }
662
663   elm_datetime_value_set(picker_layout_->datePicker, currentTime);
664
665 #if defined(OS_TIZEN_TV)
666   elm_object_signal_emit(picker_layout_->layout,"TV","align,swallow.datetime");
667 #endif
668 #if defined(OS_TIZEN_MOBILE)
669   evas_object_smart_callback_add(
670       picker_layout_->datePicker, "edit,end", endEditingCallback, 0);
671 #endif
672 }
673
674 void InputPicker::CreateDateTimePopupLayout(const char* title, struct tm* currentTime) {
675   picker_layout_->popup = elm_popup_add(picker_layout_->parent);
676   elm_object_scale_set(picker_layout_->popup, 0.7);
677   evas_object_size_hint_weight_set(
678       picker_layout_->popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
679   elm_object_part_text_set(picker_layout_->popup, "title,text", title);
680
681 #if defined(OS_TIZEN)
682   if (EflExtensionHandle) {
683     void (*webkit_eext_object_event_callback_add)(
684         Evas_Object *, Eext_Callback_Type , Eext_Event_Cb func, void *);
685     webkit_eext_object_event_callback_add = (void (*)(
686         Evas_Object *,
687         Eext_Callback_Type ,
688         Eext_Event_Cb func,
689         void *)) dlsym(EflExtensionHandle, "eext_object_event_callback_add");
690     (*webkit_eext_object_event_callback_add)(
691         picker_layout_->popup, EEXT_CALLBACK_BACK, HandleBackKeyDatePicker, this);
692   }
693 #endif
694   evas_object_event_callback_add(picker_layout_->popup, EVAS_CALLBACK_KEY_UP,
695                                  DatePickerKeyUpCallback, this);
696
697   base::FilePath edj_dir;
698   base::FilePath control_edj;
699   PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
700   control_edj = edj_dir.Append(FILE_PATH_LITERAL("control.edj"));
701
702
703   picker_layout_->layout = elm_layout_add(picker_layout_->popup);
704   elm_layout_file_set(
705       picker_layout_->layout,
706       control_edj.AsUTF8Unsafe().c_str(),
707       "datetime_popup");
708   evas_object_size_hint_weight_set(
709       picker_layout_->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
710
711   picker_layout_->time_picker = elm_datetime_add(picker_layout_->layout);
712   elm_object_part_content_set(
713       picker_layout_->layout,
714       "elm.swallow.datetime",
715       picker_layout_->time_picker);
716
717   picker_layout_->datePicker = elm_datetime_add(picker_layout_->layout);
718   elm_object_part_content_set(
719       picker_layout_->layout,
720       "elm.swallow.datetime2",
721       picker_layout_->datePicker);
722
723   elm_object_style_set(picker_layout_->time_picker, "time_layout");
724
725   char* format = datetimeFormat();
726   if (format) {
727     elm_datetime_format_set(picker_layout_->datePicker, format);
728     elm_datetime_format_set(picker_layout_->time_picker, format);
729     free(format);
730   } else {
731     elm_datetime_format_set(picker_layout_->datePicker, defaultDatetimeFormat);
732     elm_datetime_format_set(picker_layout_->time_picker, defaultDatetimeFormat);
733   }
734
735   elm_datetime_value_set(picker_layout_->datePicker, currentTime);
736   elm_datetime_value_set(picker_layout_->time_picker, currentTime);
737
738 #if defined(OS_TIZEN_MOBILE)
739   evas_object_smart_callback_add(
740       picker_layout_->datePicker, "edit,end", endEditingCallback, 0);
741 #endif
742 }
743
744 void InputPicker::CreateTimePopupLayout(const char* title, struct tm* currentTime) {
745   picker_layout_->popup = elm_popup_add(picker_layout_->parent);
746   evas_object_size_hint_weight_set(
747       picker_layout_->popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
748   elm_object_part_text_set(picker_layout_->popup, "title,text", title);
749
750 #if defined(OS_TIZEN)
751   if (EflExtensionHandle) {
752     void (*webkit_eext_object_event_callback_add)(
753         Evas_Object *, Eext_Callback_Type , Eext_Event_Cb func, void *);
754     webkit_eext_object_event_callback_add = (void (*)(
755         Evas_Object *,
756         Eext_Callback_Type ,
757         Eext_Event_Cb func,
758         void *)) dlsym(EflExtensionHandle, "eext_object_event_callback_add");
759     (*webkit_eext_object_event_callback_add)(
760         picker_layout_->popup, EEXT_CALLBACK_BACK, HandleBackKeyDatePicker, this);
761   }
762 #endif
763   evas_object_event_callback_add(picker_layout_->popup, EVAS_CALLBACK_KEY_UP,
764                                  DatePickerKeyUpCallback, this);
765
766   base::FilePath edj_dir;
767   base::FilePath control_edj;
768   PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
769   control_edj = edj_dir.Append(FILE_PATH_LITERAL("control.edj"));
770
771
772   picker_layout_->layout = elm_layout_add(picker_layout_->popup);
773   elm_layout_file_set(
774       picker_layout_->layout,
775       control_edj.AsUTF8Unsafe().c_str(),
776       "date_popup");
777   evas_object_size_hint_weight_set(
778       picker_layout_->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
779
780   picker_layout_->time_picker = elm_datetime_add(picker_layout_->layout);
781   elm_object_part_content_set(
782       picker_layout_->layout,
783       "elm.swallow.datetime",
784       picker_layout_->time_picker);
785
786   elm_object_style_set(picker_layout_->time_picker, "time_layout");
787
788   char* format = datetimeFormat();
789   if (format) {
790     elm_datetime_format_set(picker_layout_->time_picker, format);
791     free(format);
792   } else {
793     elm_datetime_format_set(picker_layout_->time_picker, defaultDatetimeFormat);
794   }
795
796   elm_datetime_value_set(picker_layout_->time_picker, currentTime);
797
798 #if defined(OS_TIZEN_TV)
799   elm_object_signal_emit(picker_layout_->layout,"TV","align,swallow.datetime");
800 #endif
801 #if defined(OS_TIZEN_MOBILE)
802   evas_object_smart_callback_add(
803       picker_layout_->time_picker, "edit,end", endEditingCallback, 0);
804 #endif
805 }
806
807 void InputPicker::deletePopupLayout() {
808   if(picker_layout_->popup){
809     evas_object_del(picker_layout_->popup);
810     picker_layout_->popup = 0;
811   }
812 }
813
814 void InputPicker::datePopupCallback(
815     void* data,  Evas_Object* obj, void* event_info) {
816   struct tm currentTime;
817   memset(&currentTime, 0, sizeof(struct tm));
818
819   InputPicker* inputPicker = static_cast<InputPicker*>(data);
820
821   elm_datetime_value_get(inputPicker->picker_layout_->datePicker, &currentTime);
822   mktime(&currentTime);
823
824   char dateStr[20] = { 0, };
825   strftime(dateStr, 20, "%F" , &currentTime);
826
827   inputPicker->web_view_.web_contents().DidReplaceDateTime(std::string(dateStr));
828   inputPicker->web_view_.ExecuteEditCommand("Unselect", 0);
829
830   inputPicker->deletePopupLayout();
831   delete inputPicker->picker_layout_;
832   inputPicker->picker_layout_ = 0;
833 }
834
835 void InputPicker::weekPopupCallback(
836     void* data,  Evas_Object* obj, void* event_info) {
837   struct tm currentTime;
838   memset(&currentTime, 0, sizeof(struct tm));
839
840   InputPicker* inputPicker = static_cast<InputPicker*>(data);
841
842   elm_datetime_value_get(inputPicker->picker_layout_->datePicker, &currentTime);
843   mktime(&currentTime);
844
845   char dateStr[20] = { 0, };
846   strftime(dateStr, 20, "%G-W%V", &currentTime);
847
848   inputPicker->web_view_.web_contents().DidReplaceDateTime(std::string(dateStr));
849   inputPicker->web_view_.ExecuteEditCommand("Unselect", 0);
850
851   inputPicker->deletePopupLayout();
852   delete inputPicker->picker_layout_;
853   inputPicker->picker_layout_ = 0;
854 }
855
856 void InputPicker::timePopupCallback(
857     void* data,  Evas_Object* obj, void* event_info) {
858   struct tm currentTime;
859   memset(&currentTime, 0, sizeof(struct tm));
860
861   InputPicker* inputPicker = static_cast<InputPicker*>(data);
862
863   elm_datetime_value_get(inputPicker->picker_layout_->time_picker, &currentTime);
864   mktime(&currentTime);
865
866   char dateStr[20] = { 0, };
867   strftime(dateStr, 20, "%R", &currentTime);
868
869   inputPicker->web_view_.web_contents().DidReplaceDateTime(std::string(dateStr));
870   inputPicker->web_view_.ExecuteEditCommand("Unselect", 0);
871
872   inputPicker->deletePopupLayout();
873   delete inputPicker->picker_layout_;
874   inputPicker->picker_layout_ = 0;
875 }
876
877 void InputPicker::monthPopupCallback(
878     void* data,  Evas_Object* obj, void* event_info) {
879   struct tm currentTime;
880   memset(&currentTime, 0, sizeof(struct tm));
881
882   InputPicker* inputPicker = static_cast<InputPicker*>(data);
883   mktime(&currentTime);
884
885   elm_datetime_value_get(inputPicker->picker_layout_->datePicker, &currentTime);
886
887   char dateStr[20] = { 0, };
888   strftime(dateStr, 20, "%Y-%m", &currentTime);
889
890   inputPicker->web_view_.web_contents().DidReplaceDateTime(std::string(dateStr));
891   inputPicker->web_view_.ExecuteEditCommand("Unselect", 0);
892
893   inputPicker->deletePopupLayout();
894   delete inputPicker->picker_layout_;
895   inputPicker->picker_layout_ = 0;
896 }
897
898 void InputPicker::datetimePopupCallback(
899     void* data,  Evas_Object* obj, void* event_info) {
900   struct tm currentTime;
901   memset(&currentTime, 0, sizeof(struct tm));
902
903   InputPicker* inputPicker = static_cast<InputPicker*>(data);
904
905   elm_datetime_value_get(inputPicker->picker_layout_->datePicker, &currentTime);
906   mktime(&currentTime);
907
908   char dateStr[50] = { 0, };
909   if (inputPicker->picker_layout_->datetime_local)
910     strftime(dateStr, 50, "%FT%R", &currentTime);
911   else
912     strftime(dateStr, 50, "%FT%RZ", &currentTime);
913
914   inputPicker->web_view_.web_contents().DidReplaceDateTime(std::string(dateStr));
915   inputPicker->web_view_.ExecuteEditCommand("Unselect", 0);
916
917   inputPicker->deletePopupLayout();
918   delete inputPicker->picker_layout_;
919   inputPicker->picker_layout_ = 0;
920 }
921
922 void InputPicker::datetimeChangedCallback(
923     void* data,  Evas_Object* obj, void* event_info) {
924   struct tm currentTime;
925   memset(&currentTime, 0, sizeof(struct tm));
926
927   InputPicker* inputPicker = static_cast<InputPicker*>(data);
928   if (obj == inputPicker->picker_layout_->datePicker) {
929     elm_datetime_value_get(inputPicker->picker_layout_->datePicker, &currentTime);
930     elm_datetime_value_set(inputPicker->picker_layout_->time_picker, &currentTime);
931   } else if (obj == inputPicker->picker_layout_->time_picker) {
932     elm_datetime_value_get(inputPicker->picker_layout_->time_picker, &currentTime);
933     elm_datetime_value_set(inputPicker->picker_layout_->datePicker, &currentTime);
934   }
935 }
936
937 void InputPicker::HandleBackKeyDatePicker(
938     void* data, Evas_Object* obj, void* event_info) {
939   removeDatetimePicker(data);
940 }
941
942 } // namespace content