1 #include <Elementary.h>
6 * @defgroup Datefield Datefield
9 * This is a date editfield. it is used to input date and time using keypad
12 typedef struct _Widget_Data Widget_Data;
40 #define YEAR_MAX_LENGTH 4
41 #define DAY_MAX_LENGTH 2
42 #define TIME_MAX_LENGTH 2
44 #define MONTH_MAXIMUM 12
45 #define HOUR_24H_MAXIMUM 23
46 #define HOUR_12H_MAXIMUM 12
47 #define MIN_MAXIMUM 59
52 Evas_Object *date[DATE_MAX];
53 Evas_Object *time[TIME_MAX];
54 Ecore_Event_Handler *handler;
58 int year, month, day, hour, min;
59 int y_max, m_max, d_max;
60 int y_min, m_min, d_min;
63 Eina_Bool time_mode:1;
64 Eina_Bool format_exists:1;
67 void (*func)(void *data, Evas_Object *obj, int value);
71 static const char *widtype = NULL;
73 static void _del_hook(Evas_Object *obj);
74 static void _theme_hook(Evas_Object *obj);
75 static void _sizing_eval(Evas_Object *obj);
76 static void _on_focus_hook(void *data, Evas_Object *obj);
78 static void _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
79 static void _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
80 static void _entry_focused_cb(void *data, Evas_Object *obj, void *event_info);
81 static void _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info);
82 static void _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info);
83 static Eina_Bool _imf_event_commit_cb(void *data, int type, void *event);
84 static void _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value);
86 static void _date_entry_add(Evas_Object *obj);
87 static void _time_entry_add(Evas_Object *obj);
88 static void _date_update(Evas_Object *obj);
89 static Eina_Bool _focus_idler_cb(void *obj);
90 static void _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj);
91 static Eina_Bool _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen);
92 static char* _get_i18n_string(Evas_Object *obj, nl_item item);
93 static int _maximum_day_get(int year, int month);
94 static int _check_date_boundary(Evas_Object *obj, int num, int flag);
97 _del_hook(Evas_Object *obj)
99 Widget_Data *wd = elm_widget_data_get(obj);
102 ecore_event_handler_del(wd->handler);
108 _on_focus_hook(void *data, Evas_Object *obj)
110 Widget_Data *wd = elm_widget_data_get(obj);
111 if (!wd || !wd->base) return ;
113 if (elm_widget_focus_get(obj)) wd->idler = ecore_idler_add(_focus_idler_cb, obj);
117 _theme_hook(Evas_Object *obj)
119 Widget_Data *wd = elm_widget_data_get(obj);
123 if (!wd || !wd->base) return;
125 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
127 _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
129 for (i = 0; i < DATE_MAX; i++)
130 elm_object_style_set(wd->date[i], "datefield/hybrid");
131 for (i = 0; i < TIME_MAX; i++)
132 elm_object_style_set(wd->time[i], "datefield/hybrid");
134 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
136 _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
138 for (i = 0; i < DATE_MAX; i++)
139 elm_object_style_set(wd->date[i], "datefield");
141 for (i = 0; i < TIME_MAX; i++)
142 evas_object_hide(wd->time[i]);
144 else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
146 _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
148 for (i = 0; i < TIME_MAX; i++)
149 elm_object_style_set(wd->time[i], "datefield");
151 for (i = 0; i < DATE_MAX; i++)
152 evas_object_hide(wd->date[i]);
155 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
157 edje_object_part_swallow(wd->base, "elm.swallow.date.year", wd->date[DATE_YEAR]);
158 edje_object_part_swallow(wd->base, "elm.swallow.date.month", wd->date[DATE_MON]);
159 edje_object_part_swallow(wd->base, "elm.swallow.date.day", wd->date[DATE_DAY]);
160 edje_object_part_text_set(wd->base, "elm.text.date.comma", ",");
163 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
165 edje_object_part_swallow(wd->base, "elm.swallow.time.hour", wd->time[TIME_HOUR]);
166 edje_object_part_swallow(wd->base, "elm.swallow.time.min", wd->time[TIME_MIN]);
167 edje_object_part_text_set(wd->base, "elm.text.colon", ":");
170 edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
173 if (wd->format_exists)
174 sprintf(sig, "elm,state,format,%s", elm_datefield_date_format_get(obj));
177 char *str = _get_i18n_string(obj, D_FMT);
180 if (!strcmp(str, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
181 else if (!strcmp(str, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
182 else if (!strcmp(str, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
183 else if (!strcmp(str, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
184 else if (!strcmp(str, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
185 else if (!strcmp(str, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
186 sprintf(sig, "elm,state,format,%s",str);
190 edje_object_signal_emit(wd->base, sig, "elm");
197 _sizing_eval(Evas_Object *obj)
199 Widget_Data *wd = elm_widget_data_get(obj);
200 Evas_Coord minw = -1, minh = -1;
202 edje_object_size_min_calc(wd->base, &minw, &minh);
203 evas_object_size_hint_min_set(obj, minw, minh);
204 evas_object_size_hint_max_set(obj, -1, -1);
208 _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
210 Widget_Data *wd = elm_widget_data_get(data);
213 if (!wd || !wd->base) return ;
218 str = _get_i18n_string(data, PM_STR);
221 edje_object_part_text_set(wd->base, "elm.text.ampm", str);
224 wd->hour += HOUR_12H_MAXIMUM;
228 str = _get_i18n_string(data, AM_STR);
231 edje_object_part_text_set(wd->base, "elm.text.ampm", str);
234 wd->hour -= HOUR_12H_MAXIMUM;
236 evas_object_smart_callback_call(data, "changed", NULL);
240 _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
242 Widget_Data *wd = elm_widget_data_get(data);
245 if (!strcmp(source, "elm.rect.date.year.over"))
246 elm_object_focus(wd->date[DATE_YEAR]);
247 else if (!strcmp(source, "elm.rect.date.month.over"))
248 elm_object_focus(wd->date[DATE_MON]);
249 else if (!strcmp(source, "elm.rect.date.day.over"))
250 elm_object_focus(wd->date[DATE_DAY]);
251 else if (!strcmp(source, "elm.rect.time.hour.over"))
252 elm_object_focus(wd->time[TIME_HOUR]);
253 else if (!strcmp(source, "elm.rect.time.min.over"))
254 elm_object_focus(wd->time[TIME_MIN]);
255 else if (!strcmp(source, "elm.rect.date.left.pad"))
257 switch (wd->date_format)
259 case DATE_FORMAT_YYDDMM:
260 case DATE_FORMAT_YYMMDD:
261 elm_object_focus(wd->date[DATE_YEAR]);
263 case DATE_FORMAT_MMDDYY:
264 case DATE_FORMAT_MMYYDD:
265 elm_object_focus(wd->date[DATE_MON]);
267 case DATE_FORMAT_DDMMYY:
268 case DATE_FORMAT_DDYYMM:
269 elm_object_focus(wd->date[DATE_DAY]);
272 else if (!strcmp(source, "elm.rect.date.right.pad"))
274 switch (wd->date_format)
276 case DATE_FORMAT_MMDDYY:
277 case DATE_FORMAT_DDMMYY:
278 elm_object_focus(wd->date[DATE_YEAR]);
280 case DATE_FORMAT_DDYYMM:
281 case DATE_FORMAT_YYDDMM:
282 elm_object_focus(wd->date[DATE_MON]);
284 case DATE_FORMAT_YYMMDD:
285 case DATE_FORMAT_MMYYDD:
286 elm_object_focus(wd->date[DATE_DAY]);
292 _focus_idler_cb(void *obj)
294 Widget_Data *wd = elm_widget_data_get(obj);
295 Evas_Object *focus_obj;
297 focus_obj = elm_widget_focused_object_get(obj);
298 if (focus_obj == obj)
300 if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
301 elm_object_focus(wd->time[TIME_HOUR]);
303 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
305 switch (wd->date_format)
307 case DATE_FORMAT_YYDDMM:
308 case DATE_FORMAT_YYMMDD:
309 elm_object_focus(wd->date[DATE_YEAR]);
311 case DATE_FORMAT_MMDDYY:
312 case DATE_FORMAT_MMYYDD:
313 elm_object_focus(wd->date[DATE_MON]);
315 case DATE_FORMAT_DDMMYY:
316 case DATE_FORMAT_DDYYMM:
317 elm_object_focus(wd->date[DATE_DAY]);
326 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
328 Widget_Data *wd = elm_widget_data_get(data);
329 if (!wd || !wd->base) return;
333 ecore_idler_del(wd->idler);
337 if (obj == wd->date[DATE_YEAR])
338 edje_object_signal_emit(wd->base, "elm,state,year,focus,in", "elm");
339 else if (obj == wd->date[DATE_MON])
340 edje_object_signal_emit(wd->base, "elm,state,month,focus,in", "elm");
341 else if (obj == wd->date[DATE_DAY])
342 edje_object_signal_emit(wd->base, "elm,state,day,focus,in", "elm");
343 else if (obj == wd->time[TIME_HOUR])
344 edje_object_signal_emit(wd->base, "elm,state,hour,focus,in", "elm");
345 else if (obj == wd->time[TIME_MIN])
346 edje_object_signal_emit(wd->base, "elm,state,min,focus,in", "elm");
350 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
352 Widget_Data *wd = elm_widget_data_get(data);
353 char str[YEAR_MAX_LENGTH+1] = {0,};
357 if (!wd || !wd->base) return;
360 if (obj == wd->date[DATE_YEAR])
362 if (strlen(elm_entry_entry_get(wd->date[DATE_YEAR])))
363 wd->year = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
364 wd->year = _check_date_boundary(data, wd->year, DATE_YEAR);
365 sprintf(str, "%d", wd->year);
366 elm_entry_entry_set(wd->date[DATE_YEAR], str);
367 //check month boundary
368 if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
371 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
374 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
379 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
382 sprintf(str, "%d", wd->day);
383 elm_entry_entry_set(wd->date[DATE_DAY], str);
385 edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
387 else if (obj == wd->date[DATE_MON])
389 if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
392 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
395 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
400 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
403 sprintf(str, "%d", wd->day);
404 elm_entry_entry_set(wd->date[DATE_DAY], str);
406 edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
408 else if (obj == wd->date[DATE_DAY])
410 if (strlen(elm_entry_entry_get(wd->date[DATE_DAY])))
411 wd->day = atoi(elm_entry_entry_get(wd->date[DATE_DAY]));
412 wd->day = _check_date_boundary(data, wd->day, DATE_DAY);
413 sprintf(str, "%d", wd->day);
414 elm_entry_entry_set(wd->date[DATE_DAY], str);
415 edje_object_signal_emit(wd->base, "elm,state,day,focus,out", "elm");
417 else if (obj == wd->time[TIME_HOUR])
419 if (strlen(elm_entry_entry_get(wd->time[TIME_HOUR])))
420 num = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
423 if (!wd->time_mode) // 24 mode
425 if (num > HOUR_24H_MAXIMUM) num = HOUR_24H_MAXIMUM;
430 if (num > HOUR_24H_MAXIMUM || num == 0)
432 num = HOUR_12H_MAXIMUM;
435 else if (num > HOUR_12H_MAXIMUM)
437 num -= HOUR_12H_MAXIMUM;
440 wd->hour = (wd->pm == EINA_TRUE)? num + HOUR_12H_MAXIMUM : num;
441 if ((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
444 i18n_str = _get_i18n_string(data, PM_STR);
447 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
453 i18n_str = _get_i18n_string(data, AM_STR);
456 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
461 sprintf(str, "%02d", num);
462 elm_entry_entry_set(wd->time[TIME_HOUR], str);
463 edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
465 else if (obj == wd->time[TIME_MIN])
467 if (strlen(elm_entry_entry_get(wd->time[TIME_MIN])))
468 wd->min = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
469 if (wd->min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
471 sprintf(str, "%02d", wd->min);
472 elm_entry_entry_set(wd->time[TIME_MIN], str);
473 edje_object_signal_emit(wd->base, "elm,state,min,focus,out", "elm");
475 evas_object_smart_callback_call(data, "changed", NULL);
479 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
481 Widget_Data *wd = elm_widget_data_get(obj);
484 if (focus_obj == wd->date[DATE_YEAR])
486 switch (wd->date_format)
488 case DATE_FORMAT_DDMMYY:
489 case DATE_FORMAT_MMDDYY:
491 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
492 elm_object_focus(wd->time[TIME_HOUR]);
493 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
494 elm_object_unfocus(wd->date[DATE_YEAR]);
497 case DATE_FORMAT_DDYYMM:
498 case DATE_FORMAT_YYMMDD:
499 elm_object_focus(wd->date[DATE_MON]);
501 case DATE_FORMAT_MMYYDD:
502 case DATE_FORMAT_YYDDMM:
503 elm_object_focus(wd->date[DATE_DAY]);
506 else if (focus_obj == wd->date[DATE_MON])
508 switch (wd->date_format)
510 case DATE_FORMAT_DDYYMM:
511 case DATE_FORMAT_YYDDMM:
513 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
514 elm_object_focus(wd->time[TIME_HOUR]);
515 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
516 elm_object_unfocus(wd->date[DATE_MON]);
519 case DATE_FORMAT_DDMMYY:
520 case DATE_FORMAT_MMYYDD:
521 elm_object_focus(wd->date[DATE_YEAR]);
523 case DATE_FORMAT_MMDDYY:
524 case DATE_FORMAT_YYMMDD:
525 elm_object_focus(wd->date[DATE_DAY]);
528 else if (focus_obj == wd->date[DATE_DAY])
530 switch (wd->date_format)
532 case DATE_FORMAT_YYMMDD:
533 case DATE_FORMAT_MMYYDD:
535 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
536 elm_object_focus(wd->time[TIME_HOUR]);
537 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
538 elm_object_unfocus(wd->date[DATE_DAY]);
541 case DATE_FORMAT_DDYYMM:
542 case DATE_FORMAT_MMDDYY:
543 elm_object_focus(wd->date[DATE_YEAR]);
545 case DATE_FORMAT_DDMMYY:
546 case DATE_FORMAT_YYDDMM:
547 elm_object_focus(wd->date[DATE_MON]);
550 else if (focus_obj == wd->time[TIME_HOUR])
551 elm_object_focus(wd->time[TIME_MIN]);
552 else if (focus_obj == wd->time[TIME_MIN])
553 elm_object_unfocus(wd->time[TIME_MIN]);
557 _check_date_boundary(Evas_Object *obj, int num, int flag)
559 Widget_Data *wd = elm_widget_data_get(obj);
560 if (flag == DATE_YEAR)
562 if (num > wd->y_max) num = wd->y_max;
563 else if (num < wd->y_min) num = wd->y_min;
567 else if (flag == DATE_MON)
569 if (wd->year == wd->y_max && num > wd->m_max) num = wd->m_max;
570 else if (wd->year == wd->y_min && num < wd->m_min) num = wd->m_min;
571 else if (num > MONTH_MAXIMUM) num = MONTH_MAXIMUM;
572 else if (num <= 0) num = 1;
576 else if (flag == DATE_DAY)
578 int day_of_month = _maximum_day_get(wd->year, wd->month);
579 if (wd->year == wd->y_max && wd->month == wd->m_max && num > wd->d_max) num = wd->d_max;
580 else if (wd->year == wd->y_min && wd->month == wd->m_min && num < wd->d_min) num = wd->d_min;
581 else if (num > day_of_month) num = day_of_month;
582 else if (num <= 0) num = 1;
589 _get_i18n_string(Evas_Object *obj, nl_item item)
591 Widget_Data *wd = elm_widget_data_get(obj);
596 if (!wd) return NULL;
598 fmt = nl_langinfo(item);
599 if (!fmt) return NULL;
604 str = calloc(7, sizeof(char));
607 if (fmt[i] == '%' && fmt[i+1])
612 case 'Y': case 'M': case 'D': case 'y': case 'm': case 'd':
613 str[j++] = tolower(fmt[i]);
614 str[j++] = tolower(fmt[i]);
625 str = calloc(strlen(fmt)+1, sizeof(char));
630 str = calloc(3, sizeof(char));
631 if (item == AM_STR) strcpy(str, "AM");
632 else if (item == PM_STR) strcpy(str, "PM");
635 case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: case ABMON_5: case ABMON_6:
636 case ABMON_7: case ABMON_8: case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
637 str = calloc(strlen(fmt)+1, sizeof(char));
641 if (fmt[i] >= '1' && fmt[i] <= '9')
643 if (fmt[i+1] >= '1' && fmt[i+1] <= '9')
655 _maximum_day_get(int year, int month)
657 int day_of_month = 0;
658 if (year == 0 || month == 0) return 0;
670 if ((!(year % 4) && (year % 100)) || !(year % 400))
685 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
687 Widget_Data *wd = elm_widget_data_get(obj);
689 if (!wd) return EINA_FALSE;
691 if (focus_obj == wd->date[DATE_YEAR] && strlen == YEAR_MAX_LENGTH)
692 wd->editing = EINA_FALSE;
693 else if (focus_obj == wd->date[DATE_MON])
694 wd->editing = EINA_FALSE;
695 else if (focus_obj == wd->date[DATE_DAY])
697 if (strlen == DAY_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 3)
698 wd->editing = EINA_FALSE;
700 else if (focus_obj == wd->time[TIME_HOUR])
702 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
703 wd->editing = EINA_FALSE;
705 else if (focus_obj == wd->time[TIME_MIN])
707 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 5)
708 wd->editing = EINA_FALSE;
714 _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info)
716 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
718 if (!strcmp(ev->keyname, "BackSpace"))
719 elm_entry_entry_set(obj, "");
723 _imf_event_commit_cb(void *data, int type, void *event)
725 Widget_Data *wd = elm_widget_data_get(data);
726 Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event;
727 Evas_Object *focus_obj;
728 char str[YEAR_MAX_LENGTH+1] = {0,};
730 if (!wd) return ECORE_CALLBACK_PASS_ON;
731 if (!elm_widget_focus_get(data)) return ECORE_CALLBACK_PASS_ON;
733 focus_obj = elm_widget_focused_object_get(data);
736 elm_entry_entry_set(focus_obj, "");
737 wd->editing = EINA_TRUE;
739 if (focus_obj == wd->date[DATE_MON])
742 wd->month = atoi(ev->str);
743 i18n_str = _get_i18n_string(data, ABMON_1+wd->month-1);
746 elm_entry_entry_set(focus_obj, i18n_str);
752 strcpy(str, elm_entry_entry_get(focus_obj));
753 str[strlen(str)] = ev->str[0];
754 elm_entry_entry_set(focus_obj, str);
757 if (_check_input_done(data, focus_obj, strlen(str)))
758 _entry_focus_move(data, focus_obj);
760 return ECORE_CALLBACK_DONE;
764 _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value)
766 Widget_Data *wd = elm_widget_data_get(data);
771 wd->func(wd->func_data, data, value);
775 _date_update(Evas_Object *obj)
777 Widget_Data *wd = elm_widget_data_get(obj);
778 char str[YEAR_MAX_LENGTH+1] = {0,};
781 if (!wd || !wd->base) return;
783 sprintf(str, "%d", wd->year);
784 elm_entry_entry_set(wd->date[DATE_YEAR], str);
786 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
789 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
793 sprintf(str, "%d", wd->day);
794 elm_entry_entry_set(wd->date[DATE_DAY], str);
796 if (!wd->time_mode) //24 mode
797 sprintf(str, "%d", wd->hour);
800 if (wd->hour >= HOUR_12H_MAXIMUM)
803 i18n_str = _get_i18n_string(obj, PM_STR);
806 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
813 i18n_str = _get_i18n_string(obj, AM_STR);
816 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
821 if (wd->hour > HOUR_12H_MAXIMUM)
822 sprintf(str, "%02d", wd->hour - HOUR_12H_MAXIMUM);
823 else if (wd->hour == 0)
824 sprintf(str, "%02d", HOUR_12H_MAXIMUM);
826 sprintf(str, "%02d", wd->hour);
828 elm_entry_entry_set(wd->time[TIME_HOUR], str);
829 sprintf(str, "%02d", wd->min);
830 elm_entry_entry_set(wd->time[TIME_MIN], str);
834 _date_entry_add(Evas_Object *obj)
836 Widget_Data *wd = elm_widget_data_get(obj);
837 static Elm_Entry_Filter_Limit_Size filter_data, filter_data2;
842 for (i = 0; i < DATE_MAX; i++)
844 wd->date[i] = elm_entry_add(obj);
845 elm_entry_single_line_set(wd->date[i], EINA_TRUE);
846 elm_entry_context_menu_disabled_set(wd->date[i], EINA_TRUE);
847 if (i == DATE_MON) elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_MONTH);
848 else elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
849 evas_object_size_hint_weight_set(wd->date[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
850 evas_object_size_hint_align_set(wd->date[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
851 evas_object_smart_callback_add(wd->date[i], "focused", _entry_focused_cb, obj);
852 evas_object_smart_callback_add(wd->date[i], "unfocused", _entry_unfocused_cb, obj);
853 evas_object_event_callback_add(wd->date[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
854 elm_widget_sub_object_add(obj, wd->date[i]);
857 filter_data.max_char_count = 0;
858 filter_data.max_byte_count = YEAR_MAX_LENGTH;
859 elm_entry_text_filter_append(wd->date[DATE_YEAR], elm_entry_filter_limit_size, &filter_data);
860 filter_data2.max_char_count = 0;
861 filter_data2.max_byte_count = DAY_MAX_LENGTH;
862 elm_entry_text_filter_append(wd->date[DATE_YEAR], elm_entry_filter_limit_size, &filter_data2);
866 _time_entry_add(Evas_Object *obj)
868 Widget_Data *wd = elm_widget_data_get(obj);
869 static Elm_Entry_Filter_Limit_Size filter_data;
874 filter_data.max_char_count = 0;
875 filter_data.max_byte_count = TIME_MAX_LENGTH;
876 for (i = 0; i < TIME_MAX; i++)
878 wd->time[i] = elm_entry_add(obj);
879 elm_entry_single_line_set(wd->time[i], EINA_TRUE);
880 elm_entry_context_menu_disabled_set(wd->time[i], EINA_TRUE);
881 elm_entry_input_panel_layout_set(wd->time[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
882 elm_entry_text_filter_append(wd->time[i], elm_entry_filter_limit_size, &filter_data);
883 evas_object_size_hint_weight_set(wd->time[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
884 evas_object_size_hint_align_set(wd->time[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
885 evas_object_smart_callback_add(wd->time[i], "focused", _entry_focused_cb, obj);
886 evas_object_smart_callback_add(wd->time[i], "unfocused", _entry_unfocused_cb, obj);
887 evas_object_event_callback_add(wd->time[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
888 elm_widget_sub_object_add(obj, wd->time[i]);
893 * Add a new datefield object
894 * The date format and strings are based on current locale
896 * @param parent The parent object
897 * @return The new object or NULL if it cannot be created
902 elm_datefield_add(Evas_Object *parent)
908 e = evas_object_evas_get(parent);
910 wd = ELM_NEW(Widget_Data);
911 obj = elm_widget_add(e);
912 ELM_SET_WIDTYPE(widtype, "datefield");
913 elm_widget_type_set(obj, "datefield");
914 elm_widget_sub_object_add(parent, obj);
915 elm_widget_data_set(obj, wd);
916 elm_widget_del_hook_set(obj, _del_hook);
917 elm_widget_theme_hook_set(obj, _theme_hook);
918 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
919 elm_widget_can_focus_set(obj, EINA_TRUE);
921 wd->base = edje_object_add(e);
922 elm_widget_resize_object_set(obj, wd->base);
923 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.left.pad", _signal_rect_mouse_down, obj);
924 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.year.over", _signal_rect_mouse_down, obj);
925 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.month.over", _signal_rect_mouse_down, obj);
926 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.day.over", _signal_rect_mouse_down, obj);
927 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.right.pad", _signal_rect_mouse_down, obj);
929 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.hour.over", _signal_rect_mouse_down, obj);
930 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.min.over", _signal_rect_mouse_down, obj);
931 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "elm.rect.time.ampm.over", _signal_ampm_clicked, obj);
933 wd->handler = ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, obj);
934 _date_entry_add(obj);
935 _time_entry_add(obj);
943 wd->year = wd->y_min;
947 wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
948 wd->time_mode = EINA_TRUE;
956 * set layout for the datefield
958 * @param obj The datefield object
959 * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
964 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
966 ELM_CHECK_WIDTYPE(obj, widtype);
967 Widget_Data *wd = elm_widget_data_get(obj);
970 if (layout < ELM_DATEFIELD_LAYOUT_TIME ||layout > ELM_DATEFIELD_LAYOUT_DATEANDTIME) return;
972 if (wd->layout != layout)
981 * get layout of the datefield
983 * @param obj The datefield object
984 * @return layout of the datefield
988 EAPI Elm_Datefield_Layout
989 elm_datefield_layout_get(const Evas_Object *obj)
991 ELM_CHECK_WIDTYPE(obj, widtype) 0;
992 Widget_Data *wd = elm_widget_data_get(obj);
1000 * Set selected date of the datefield
1002 * @param obj The datefield object
1003 * @param year The year to set
1004 * @param month The month to set
1005 * @param day The day to set
1006 * @param hour The hours to set (24hour mode - 0~23)
1007 * @param min The minutes to set (0~59)
1009 * @ingroup Datefield
1012 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
1014 ELM_CHECK_WIDTYPE(obj, widtype);
1015 Widget_Data *wd = elm_widget_data_get(obj);
1019 wd->year = _check_date_boundary(obj, year, DATE_YEAR);
1020 wd->month = _check_date_boundary(obj, month, DATE_MON);
1021 wd->day = _check_date_boundary(obj, day, DATE_DAY);
1023 if (hour > HOUR_24H_MAXIMUM) wd->hour = HOUR_24H_MAXIMUM;
1024 else if (hour < 0) wd->hour = 0;
1025 else wd->hour = hour;
1027 if (min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
1028 else if (min < 0) wd->min = 0;
1035 * Get selected date of the datefield
1037 * @param obj The datefield object
1038 * @param year The pointer to the variable get the selected year
1039 * @param month The pointer to the variable get the selected month
1040 * @param day The pointer to the variable get the selected day
1041 * @param hour The pointer to the variable get the selected hour (24hour mode)
1042 * @param hour The pointer to the variable get the selected min
1044 * @ingroup Datefield
1047 elm_datefield_date_get(const Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
1049 ELM_CHECK_WIDTYPE(obj, widtype);
1050 Widget_Data *wd = elm_widget_data_get(obj);
1067 * Set upper boundary of the datefield
1069 * @param obj The datefield object
1070 * @param year The year to set
1071 * @param month The month to set
1072 * @param day The day to set
1073 * @return TRUE/FALSE
1075 * @ingroup Datefield
1078 elm_datefield_date_max_set(Evas_Object *obj, int year, int month, int day)
1080 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1081 Widget_Data *wd = elm_widget_data_get(obj);
1083 Eina_Bool update = EINA_FALSE;
1085 if (!wd) return EINA_FALSE;
1086 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1087 day_of_month = _maximum_day_get(year, month);
1088 if (day < 1 || day > day_of_month) return EINA_FALSE;
1094 if (wd->year > wd->y_max)
1096 wd->year = wd->y_max;
1099 if (wd->year == wd->y_max && wd->month > wd->m_max)
1101 wd->month = wd->m_max;
1104 if (wd->year == wd->y_max && wd->month == wd->m_max && wd->day > wd->d_max)
1106 wd->day = wd->d_max;
1110 if (update) _date_update(obj);
1115 * Get upper boundary of the datefield
1117 * @param obj The datefield object
1118 * @param year The pointer to the variable get the maximum year
1119 * @param month The pointer to the variable get the maximum month
1120 * @param day The pointer to the variable get the maximum day
1122 * @ingroup Datefield
1125 elm_datefield_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
1127 ELM_CHECK_WIDTYPE(obj, widtype);
1128 Widget_Data *wd = elm_widget_data_get(obj);
1141 * Set lower boundary of the datefield
1143 * @param obj The datefield object
1144 * @param year The year to set
1145 * @param month The month to set
1146 * @param day The day to set
1147 * @return TRUE/FALSE
1149 * @ingroup Datepicker
1152 elm_datefield_date_min_set(Evas_Object *obj, int year, int month, int day)
1154 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1155 Widget_Data *wd = elm_widget_data_get(obj);
1157 Eina_Bool update = EINA_FALSE;
1159 if (!wd) return EINA_FALSE;
1160 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1161 day_of_month = _maximum_day_get(year, month);
1162 if (day < 1 || day > day_of_month) return EINA_FALSE;
1168 if (wd->year < wd->y_min)
1170 wd->year = wd->y_min;
1173 if (wd->year == wd->y_min && wd->month < wd->m_min)
1175 wd->month = wd->m_min;
1178 if (wd->year == wd->y_min && wd->month == wd->m_min && wd->day < wd->d_min)
1180 wd->day = wd->d_min;
1184 if (update) _date_update(obj);
1189 * Get lower boundary of the datefield
1191 * @param obj The datefield object
1192 * @param year The pointer to the variable get the maximum year
1193 * @param month The pointer to the variable get the maximum month
1194 * @param day The pointer to the variable get the maximum day
1196 * @ingroup Datefield
1199 elm_datefield_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
1201 ELM_CHECK_WIDTYPE(obj, widtype);
1202 Widget_Data *wd = elm_widget_data_get(obj);
1215 * Set if the datefield show hours in military or am/pm mode
1217 * @param obj The datefield object
1218 * @param mode option for the hours mode. If true, it is shown as 12h mode, if false, it is shown as 24h mode. Default value is true
1220 * @ingroup Datefield
1223 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
1225 ELM_CHECK_WIDTYPE(obj, widtype);
1226 Widget_Data *wd = elm_widget_data_get(obj);
1230 if (wd->time_mode != mode)
1232 wd->time_mode = mode;
1233 if (!wd->time_mode) edje_object_signal_emit(wd->base, "elm,state,mode,24h", "elm");
1234 else edje_object_signal_emit(wd->base, "elm,state,mode,12h", "elm");
1240 * get time mode of the datefield
1242 * @param obj The datefield object
1243 * @return time mode (EINA_TRUE: 12hour mode / EINA_FALSE: 24hour mode)
1245 * @ingroup Datefield
1248 elm_datefield_time_mode_get(const Evas_Object *obj)
1250 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1251 Widget_Data *wd = elm_widget_data_get(obj);
1253 if (!wd) return EINA_FALSE;
1255 return wd->time_mode;
1259 * Set date format of datefield
1261 * @param obj The datefield object
1262 * @param fmt The date format, ex) yymmdd. Default value is mmddyy.
1264 * @ingroup Datefield
1267 elm_datefield_date_format_set(Evas_Object *obj, const char *fmt)
1269 ELM_CHECK_WIDTYPE(obj, widtype);
1270 Widget_Data *wd = elm_widget_data_get(obj);
1271 char sig[32] = "elm,state,format,";
1274 if (!wd || !fmt) return;
1279 sig[j++] = tolower(fmt[i++]);
1281 if (j < 32) sig[j] = '\0';
1282 edje_object_signal_emit(wd->base, sig, "elm");
1284 if (strstr(sig, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
1285 else if (strstr(sig, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
1286 else if (strstr(sig, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
1287 else if (strstr(sig, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
1288 else if (strstr(sig, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
1289 else if (strstr(sig, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
1290 wd->format_exists = EINA_TRUE;
1294 * get date format of the datefield
1296 * @param obj The datefield object
1297 * @return date format string. ex) yymmdd
1299 * @ingroup Datefield
1302 elm_datefield_date_format_get(const Evas_Object *obj)
1304 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1305 Widget_Data *wd = elm_widget_data_get(obj);
1307 switch (wd->date_format)
1309 case DATE_FORMAT_YYMMDD: return "yymmdd";
1310 case DATE_FORMAT_YYDDMM: return "yyddmm";
1311 case DATE_FORMAT_MMYYDD: return "mmyydd";
1312 case DATE_FORMAT_MMDDYY: return "mmddyy";
1313 case DATE_FORMAT_DDYYMM: return "ddyymm";
1314 case DATE_FORMAT_DDMMYY: return "ddmmyy";
1320 * Add a callback function for input panel state
1322 * @param obj The datefield object
1323 * @param func The function to be called when the event is triggered (value will be the Ecore_IMF_Input_Panel_State)
1324 * @param data The data pointer to be passed to @p func
1326 * @ingroup Datefield
1329 elm_datefield_input_panel_state_callback_add(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value), void *data)
1331 ELM_CHECK_WIDTYPE(obj, widtype);
1332 Widget_Data *wd = elm_widget_data_get(obj);
1337 if (wd->func && (wd->func != pEventCallbackFunc))
1338 elm_datefield_input_panel_state_callback_del(obj, wd->func);
1340 if (wd->func != pEventCallbackFunc)
1342 wd->func = pEventCallbackFunc;
1343 wd->func_data = data;
1345 for (i = 0; i < DATE_MAX; i++)
1346 ecore_imf_context_input_panel_event_callback_add(
1347 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1349 for (i = 0; i < TIME_MAX; i++)
1350 ecore_imf_context_input_panel_event_callback_add(
1351 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1356 * Delete a callback function for input panel state
1358 * @param obj The datefield object
1359 * @param func The function to be called when the event is triggered
1361 * @ingroup Datefield
1364 elm_datefield_input_panel_state_callback_del(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value))
1366 ELM_CHECK_WIDTYPE(obj, widtype);
1367 Widget_Data *wd = elm_widget_data_get(obj);
1372 if (wd->func && wd->func == pEventCallbackFunc)
1374 for (i = 0; i < DATE_MAX; i++)
1375 ecore_imf_context_input_panel_event_callback_del(
1376 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1378 for (i = 0; i < TIME_MAX; i++)
1379 ecore_imf_context_input_panel_event_callback_del(
1380 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1383 wd->func_data = NULL;