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;
41 #define YEAR_MAX_LENGTH 4
42 #define DAY_MAX_LENGTH 2
43 #define TIME_MAX_LENGTH 2
45 #define MONTH_MAXIMUM 12
46 #define HOUR_24H_MAXIMUM 23
47 #define HOUR_12H_MAXIMUM 12
48 #define MIN_MAXIMUM 59
53 Evas_Object *date[DATE_MAX];
54 Evas_Object *time[TIME_MAX];
55 Ecore_Event_Handler *handler;
59 int year, month, day, hour, min;
60 int y_max, m_max, d_max;
61 int y_min, m_min, d_min;
64 Eina_Bool time_mode:1;
65 Eina_Bool format_exists:1;
68 void (*func)(void *data, Evas_Object *obj, int value);
72 static const char *widtype = NULL;
74 static void _del_hook(Evas_Object *obj);
75 static void _theme_hook(Evas_Object *obj);
76 static void _sizing_eval(Evas_Object *obj);
77 static void _on_focus_hook(void *data __UNUSED__, Evas_Object *obj);
79 static void _signal_rect_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source);
80 static void _entry_focused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__);
81 static void _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__);
82 static void _entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj , void *event_info);
83 static Eina_Bool _imf_event_commit_cb(void *data, int type __UNUSED__, void *event);
84 static void _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx __UNUSED__, 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);
103 ecore_idler_del(wd->idler);
109 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
111 Widget_Data *wd = elm_widget_data_get(obj);
112 if (!wd || !wd->base) return ;
114 if ((elm_widget_focus_get(obj))&&(!wd->idler)) wd->idler = ecore_idler_add(_focus_idler_cb, obj);
118 _theme_hook(Evas_Object *obj)
120 Widget_Data *wd = elm_widget_data_get(obj);
125 if (!wd || !wd->base) return;
127 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
129 _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
131 for (i = 0; i < DATE_MAX; i++)
132 elm_object_style_set(wd->date[i], "datefield/hybrid");
133 for (i = 0; i < TIME_MAX-1; i++)
134 elm_object_style_set(wd->time[i], "datefield/hybrid");
136 snprintf(buf, sizeof(buf), "datefield.ampm/%s", elm_widget_style_get(obj));
137 elm_object_style_set(wd->time[TIME_AMPM], buf);
139 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
141 _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
143 for (i = 0; i < DATE_MAX; i++)
144 elm_object_style_set(wd->date[i], "datefield");
146 for (i = 0; i < TIME_MAX; i++)
147 evas_object_hide(wd->time[i]);
149 else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
151 _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
153 for (i = 0; i < TIME_MAX-1; i++)
154 elm_object_style_set(wd->time[i], "datefield");
156 snprintf(buf, sizeof(buf), "datefield.ampm/%s", elm_widget_style_get(obj));
157 elm_object_style_set(wd->time[TIME_AMPM], buf);
159 for (i = 0; i < DATE_MAX; i++)
160 evas_object_hide(wd->date[i]);
163 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
165 edje_object_part_swallow(wd->base, "elm.swallow.date.year", wd->date[DATE_YEAR]);
166 edje_object_part_swallow(wd->base, "elm.swallow.date.month", wd->date[DATE_MON]);
167 edje_object_part_swallow(wd->base, "elm.swallow.date.day", wd->date[DATE_DAY]);
168 edje_object_part_text_set(wd->base, "elm.text.date.comma", ",");
171 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
173 edje_object_part_swallow(wd->base, "elm.swallow.time.hour", wd->time[TIME_HOUR]);
174 edje_object_part_swallow(wd->base, "elm.swallow.time.min", wd->time[TIME_MIN]);
175 edje_object_part_swallow(wd->base, "elm.swallow.time.ampm", wd->time[TIME_AMPM]);
176 edje_object_part_text_set(wd->base, "elm.text.colon", ":");
179 edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
182 if (wd->format_exists)
183 sprintf(sig, "elm,state,format,%s", elm_datefield_date_format_get(obj));
186 char *str = _get_i18n_string(obj, D_FMT);
189 if (!strcmp(str, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
190 else if (!strcmp(str, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
191 else if (!strcmp(str, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
192 else if (!strcmp(str, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
193 else if (!strcmp(str, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
194 else if (!strcmp(str, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
195 sprintf(sig, "elm,state,format,%s",str);
199 edje_object_signal_emit(wd->base, sig, "elm");
206 _sizing_eval(Evas_Object *obj)
208 Widget_Data *wd = elm_widget_data_get(obj);
209 Evas_Coord minw = -1, minh = -1;
211 edje_object_size_min_calc(wd->base, &minw, &minh);
212 evas_object_size_hint_min_set(obj, minw, minh);
213 evas_object_size_hint_max_set(obj, -1, -1);
217 _ampm_clicked_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
219 Widget_Data *wd = elm_widget_data_get(data);
222 if (!wd || !wd->base) return ;
227 str = _get_i18n_string(data, PM_STR);
230 elm_button_label_set(wd->time[TIME_AMPM], str);
233 wd->hour += HOUR_12H_MAXIMUM;
237 str = _get_i18n_string(data, AM_STR);
240 elm_button_label_set(wd->time[TIME_AMPM], str);
243 wd->hour -= HOUR_12H_MAXIMUM;
245 evas_object_smart_callback_call(data, "changed", NULL);
249 _signal_rect_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source)
251 Widget_Data *wd = elm_widget_data_get(data);
254 if (!strcmp(source, "elm.rect.date.year.over"))
255 elm_object_focus(wd->date[DATE_YEAR]);
256 else if (!strcmp(source, "elm.rect.date.month.over"))
257 elm_object_focus(wd->date[DATE_MON]);
258 else if (!strcmp(source, "elm.rect.date.day.over"))
259 elm_object_focus(wd->date[DATE_DAY]);
260 else if (!strcmp(source, "elm.rect.time.hour.over"))
261 elm_object_focus(wd->time[TIME_HOUR]);
262 else if (!strcmp(source, "elm.rect.time.min.over"))
263 elm_object_focus(wd->time[TIME_MIN]);
267 _focus_idler_cb(void *obj)
269 Widget_Data *wd = elm_widget_data_get(obj);
270 Evas_Object *focus_obj;
272 focus_obj = elm_widget_focused_object_get(obj);
273 if (focus_obj == obj)
275 if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
276 elm_object_focus(wd->time[TIME_HOUR]);
278 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
280 switch (wd->date_format)
282 case DATE_FORMAT_YYDDMM:
283 case DATE_FORMAT_YYMMDD:
284 elm_object_focus(wd->date[DATE_YEAR]);
286 case DATE_FORMAT_MMDDYY:
287 case DATE_FORMAT_MMYYDD:
288 elm_object_focus(wd->date[DATE_MON]);
290 case DATE_FORMAT_DDMMYY:
291 case DATE_FORMAT_DDYYMM:
292 elm_object_focus(wd->date[DATE_DAY]);
301 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
303 Widget_Data *wd = elm_widget_data_get(data);
304 if (!wd || !wd->base) return;
308 ecore_idler_del(wd->idler);
312 if (obj == wd->date[DATE_YEAR])
313 edje_object_signal_emit(wd->base, "elm,state,year,focus,in", "elm");
314 else if (obj == wd->date[DATE_MON])
315 edje_object_signal_emit(wd->base, "elm,state,month,focus,in", "elm");
316 else if (obj == wd->date[DATE_DAY])
317 edje_object_signal_emit(wd->base, "elm,state,day,focus,in", "elm");
318 else if (obj == wd->time[TIME_HOUR])
319 edje_object_signal_emit(wd->base, "elm,state,hour,focus,in", "elm");
320 else if (obj == wd->time[TIME_MIN])
321 edje_object_signal_emit(wd->base, "elm,state,min,focus,in", "elm");
325 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
327 Widget_Data *wd = elm_widget_data_get(data);
328 char str[YEAR_MAX_LENGTH+1] = {0,};
332 if (!wd || !wd->base) return;
335 if (obj == wd->date[DATE_YEAR])
337 if (strlen(elm_entry_entry_get(wd->date[DATE_YEAR])))
338 wd->year = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
339 wd->year = _check_date_boundary(data, wd->year, DATE_YEAR);
340 sprintf(str, "%d", wd->year);
341 elm_entry_entry_set(wd->date[DATE_YEAR], str);
342 //check month boundary
343 if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
346 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
349 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
354 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
357 sprintf(str, "%d", wd->day);
358 elm_entry_entry_set(wd->date[DATE_DAY], str);
360 edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
362 else if (obj == wd->date[DATE_MON])
364 if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
367 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
370 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
375 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
378 sprintf(str, "%d", wd->day);
379 elm_entry_entry_set(wd->date[DATE_DAY], str);
381 edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
383 else if (obj == wd->date[DATE_DAY])
385 if (strlen(elm_entry_entry_get(wd->date[DATE_DAY])))
386 wd->day = atoi(elm_entry_entry_get(wd->date[DATE_DAY]));
387 wd->day = _check_date_boundary(data, wd->day, DATE_DAY);
388 sprintf(str, "%d", wd->day);
389 elm_entry_entry_set(wd->date[DATE_DAY], str);
390 edje_object_signal_emit(wd->base, "elm,state,day,focus,out", "elm");
392 else if (obj == wd->time[TIME_HOUR])
394 if (strlen(elm_entry_entry_get(wd->time[TIME_HOUR])))
395 num = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
398 if (!wd->time_mode) // 24 mode
400 if (num > HOUR_24H_MAXIMUM) num = HOUR_24H_MAXIMUM;
405 if (num > HOUR_24H_MAXIMUM || num == 0)
407 num = HOUR_12H_MAXIMUM;
410 else if (num > HOUR_12H_MAXIMUM)
412 num -= HOUR_12H_MAXIMUM;
415 wd->hour = (wd->pm == EINA_TRUE)? num + HOUR_12H_MAXIMUM : num;
416 if ((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
419 i18n_str = _get_i18n_string(data, PM_STR);
422 elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
428 i18n_str = _get_i18n_string(data, AM_STR);
431 elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
436 sprintf(str, "%02d", num);
437 elm_entry_entry_set(wd->time[TIME_HOUR], str);
438 edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
440 else if (obj == wd->time[TIME_MIN])
442 if (strlen(elm_entry_entry_get(wd->time[TIME_MIN])))
443 wd->min = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
444 if (wd->min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
446 sprintf(str, "%02d", wd->min);
447 elm_entry_entry_set(wd->time[TIME_MIN], str);
448 edje_object_signal_emit(wd->base, "elm,state,min,focus,out", "elm");
450 evas_object_smart_callback_call(data, "changed", NULL);
454 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
456 Widget_Data *wd = elm_widget_data_get(obj);
459 if (focus_obj == wd->date[DATE_YEAR])
461 switch (wd->date_format)
463 case DATE_FORMAT_DDMMYY:
464 case DATE_FORMAT_MMDDYY:
466 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
467 elm_object_focus(wd->time[TIME_HOUR]);
468 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
469 elm_object_unfocus(wd->date[DATE_YEAR]);
472 case DATE_FORMAT_DDYYMM:
473 case DATE_FORMAT_YYMMDD:
474 elm_object_focus(wd->date[DATE_MON]);
476 case DATE_FORMAT_MMYYDD:
477 case DATE_FORMAT_YYDDMM:
478 elm_object_focus(wd->date[DATE_DAY]);
481 else if (focus_obj == wd->date[DATE_MON])
483 switch (wd->date_format)
485 case DATE_FORMAT_DDYYMM:
486 case DATE_FORMAT_YYDDMM:
488 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
489 elm_object_focus(wd->time[TIME_HOUR]);
490 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
491 elm_object_unfocus(wd->date[DATE_MON]);
494 case DATE_FORMAT_DDMMYY:
495 case DATE_FORMAT_MMYYDD:
496 elm_object_focus(wd->date[DATE_YEAR]);
498 case DATE_FORMAT_MMDDYY:
499 case DATE_FORMAT_YYMMDD:
500 elm_object_focus(wd->date[DATE_DAY]);
503 else if (focus_obj == wd->date[DATE_DAY])
505 switch (wd->date_format)
507 case DATE_FORMAT_YYMMDD:
508 case DATE_FORMAT_MMYYDD:
510 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
511 elm_object_focus(wd->time[TIME_HOUR]);
512 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
513 elm_object_unfocus(wd->date[DATE_DAY]);
516 case DATE_FORMAT_DDYYMM:
517 case DATE_FORMAT_MMDDYY:
518 elm_object_focus(wd->date[DATE_YEAR]);
520 case DATE_FORMAT_DDMMYY:
521 case DATE_FORMAT_YYDDMM:
522 elm_object_focus(wd->date[DATE_MON]);
525 else if (focus_obj == wd->time[TIME_HOUR])
526 elm_object_focus(wd->time[TIME_MIN]);
527 else if (focus_obj == wd->time[TIME_MIN])
528 elm_object_focus(wd->time[TIME_AMPM]);
529 else if (focus_obj == wd->time[TIME_AMPM])
530 elm_object_unfocus(wd->time[TIME_AMPM]);
534 _check_date_boundary(Evas_Object *obj, int num, int flag)
536 Widget_Data *wd = elm_widget_data_get(obj);
537 if (flag == DATE_YEAR)
539 if ((num > wd->y_max)&&(wd->y_max > wd->y_min)) num = wd->y_max;
540 else if (num < wd->y_min) num = wd->y_min;
544 else if (flag == DATE_MON)
546 if (wd->year == wd->y_max && num > wd->m_max) num = wd->m_max;
547 else if (wd->year == wd->y_min && num < wd->m_min) num = wd->m_min;
548 else if (num > MONTH_MAXIMUM) num = MONTH_MAXIMUM;
549 else if (num <= 0) num = 1;
553 else if (flag == DATE_DAY)
555 int day_of_month = _maximum_day_get(wd->year, wd->month);
556 if (wd->year == wd->y_max && wd->month == wd->m_max && num > wd->d_max) num = wd->d_max;
557 else if (wd->year == wd->y_min && wd->month == wd->m_min && num < wd->d_min) num = wd->d_min;
558 else if (num > day_of_month) num = day_of_month;
559 else if (num <= 0) num = 1;
566 _get_i18n_string(Evas_Object *obj, nl_item item)
568 Widget_Data *wd = elm_widget_data_get(obj);
573 if (!wd) return NULL;
575 fmt = nl_langinfo(item);
576 if (!fmt) return NULL;
581 str = calloc(7, sizeof(char));
584 if (fmt[i] == '%' && fmt[i+1])
589 case 'Y': case 'M': case 'D': case 'y': case 'm': case 'd':
590 str[j++] = tolower(fmt[i]);
591 str[j++] = tolower(fmt[i]);
602 str = calloc(strlen(fmt)+1, sizeof(char));
607 str = calloc(3, sizeof(char));
608 if (item == AM_STR) strcpy(str, "AM");
609 else if (item == PM_STR) strcpy(str, "PM");
612 case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: case ABMON_5: case ABMON_6:
613 case ABMON_7: case ABMON_8: case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
614 str = calloc(strlen(fmt)+1, sizeof(char));
618 if (fmt[i] >= '1' && fmt[i] <= '9')
620 if (fmt[i+1] >= '1' && fmt[i+1] <= '9')
632 _maximum_day_get(int year, int month)
634 int day_of_month = 0;
635 if (year == 0 || month == 0) return 0;
647 if ((!(year % 4) && (year % 100)) || !(year % 400))
662 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
664 Widget_Data *wd = elm_widget_data_get(obj);
666 if (!wd) return EINA_FALSE;
668 if (focus_obj == wd->date[DATE_YEAR] && strlen == YEAR_MAX_LENGTH)
669 wd->editing = EINA_FALSE;
670 else if (focus_obj == wd->date[DATE_MON])
671 wd->editing = EINA_FALSE;
672 else if (focus_obj == wd->date[DATE_DAY])
674 if (strlen == DAY_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 3)
675 wd->editing = EINA_FALSE;
677 else if (focus_obj == wd->time[TIME_HOUR])
679 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
680 wd->editing = EINA_FALSE;
682 else if (focus_obj == wd->time[TIME_MIN])
684 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 5)
685 wd->editing = EINA_FALSE;
691 _entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj , void *event_info)
693 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
695 if (!strcmp(ev->keyname, "BackSpace"))
696 elm_entry_entry_set(obj, "");
700 _imf_event_commit_cb(void *data , int type __UNUSED__, void *event)
702 Widget_Data *wd = elm_widget_data_get(data);
703 Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event;
704 Evas_Object *focus_obj;
705 char str[YEAR_MAX_LENGTH+1] = {0,};
707 if (!wd) return ECORE_CALLBACK_PASS_ON;
708 if (!elm_widget_focus_get(data)) return ECORE_CALLBACK_PASS_ON;
710 focus_obj = elm_widget_focused_object_get(data);
713 elm_entry_entry_set(focus_obj, "");
714 wd->editing = EINA_TRUE;
716 if (focus_obj == wd->date[DATE_MON])
719 wd->month = atoi(ev->str);
720 i18n_str = _get_i18n_string(data, ABMON_1+wd->month-1);
723 elm_entry_entry_set(focus_obj, i18n_str);
729 strcpy(str, elm_entry_entry_get(focus_obj));
730 str[strlen(str)] = ev->str[0];
731 elm_entry_entry_set(focus_obj, str);
734 if (_check_input_done(data, focus_obj, strlen(str)))
735 _entry_focus_move(data, focus_obj);
737 return ECORE_CALLBACK_DONE;
741 _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx __UNUSED__, int value)
743 Widget_Data *wd = elm_widget_data_get(data);
748 wd->func(wd->func_data, data, value);
752 _date_update(Evas_Object *obj)
754 Widget_Data *wd = elm_widget_data_get(obj);
755 char str[YEAR_MAX_LENGTH+1] = {0,};
758 if (!wd || !wd->base) return;
760 sprintf(str, "%d", wd->year);
761 elm_entry_entry_set(wd->date[DATE_YEAR], str);
763 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
766 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
770 sprintf(str, "%d", wd->day);
771 elm_entry_entry_set(wd->date[DATE_DAY], str);
773 if (!wd->time_mode) //24 mode
774 sprintf(str, "%d", wd->hour);
777 if (wd->hour >= HOUR_12H_MAXIMUM)
780 i18n_str = _get_i18n_string(obj, PM_STR);
783 elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
790 i18n_str = _get_i18n_string(obj, AM_STR);
793 elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
798 if (wd->hour > HOUR_12H_MAXIMUM)
799 sprintf(str, "%02d", wd->hour - HOUR_12H_MAXIMUM);
800 else if (wd->hour == 0)
801 sprintf(str, "%02d", HOUR_12H_MAXIMUM);
803 sprintf(str, "%02d", wd->hour);
805 elm_entry_entry_set(wd->time[TIME_HOUR], str);
806 sprintf(str, "%02d", wd->min);
807 elm_entry_entry_set(wd->time[TIME_MIN], str);
811 _date_entry_add(Evas_Object *obj)
813 Widget_Data *wd = elm_widget_data_get(obj);
814 static Elm_Entry_Filter_Limit_Size filter_data, filter_data2;
819 for (i = 0; i < DATE_MAX; i++)
821 wd->date[i] = elm_entry_add(obj);
822 elm_entry_single_line_set(wd->date[i], EINA_TRUE);
823 elm_entry_context_menu_disabled_set(wd->date[i], EINA_TRUE);
824 if (i == DATE_MON) elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_MONTH);
825 else elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
826 evas_object_size_hint_weight_set(wd->date[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
827 evas_object_size_hint_align_set(wd->date[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
828 evas_object_smart_callback_add(wd->date[i], "focused", _entry_focused_cb, obj);
829 evas_object_smart_callback_add(wd->date[i], "unfocused", _entry_unfocused_cb, obj);
830 evas_object_event_callback_add(wd->date[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
831 elm_widget_sub_object_add(obj, wd->date[i]);
834 filter_data.max_char_count = 0;
835 filter_data.max_byte_count = YEAR_MAX_LENGTH;
836 elm_entry_text_filter_append(wd->date[DATE_YEAR], elm_entry_filter_limit_size, &filter_data);
837 filter_data2.max_char_count = 0;
838 filter_data2.max_byte_count = DAY_MAX_LENGTH;
839 elm_entry_text_filter_append(wd->date[DATE_YEAR], elm_entry_filter_limit_size, &filter_data2);
843 _time_entry_add(Evas_Object *obj)
845 Widget_Data *wd = elm_widget_data_get(obj);
846 static Elm_Entry_Filter_Limit_Size filter_data;
851 filter_data.max_char_count = 0;
852 filter_data.max_byte_count = TIME_MAX_LENGTH;
853 for (i = 0; i < TIME_MAX-1; i++)
855 wd->time[i] = elm_entry_add(obj);
856 elm_entry_single_line_set(wd->time[i], EINA_TRUE);
857 elm_entry_context_menu_disabled_set(wd->time[i], EINA_TRUE);
858 elm_entry_input_panel_layout_set(wd->time[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
859 elm_entry_text_filter_append(wd->time[i], elm_entry_filter_limit_size, &filter_data);
860 evas_object_size_hint_weight_set(wd->time[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
861 evas_object_size_hint_align_set(wd->time[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
862 evas_object_smart_callback_add(wd->time[i], "focused", _entry_focused_cb, obj);
863 evas_object_smart_callback_add(wd->time[i], "unfocused", _entry_unfocused_cb, obj);
864 evas_object_event_callback_add(wd->time[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
865 elm_widget_sub_object_add(obj, wd->time[i]);
867 wd->time[TIME_AMPM] = elm_button_add(obj);
868 evas_object_size_hint_weight_set(wd->time[TIME_AMPM], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
869 evas_object_size_hint_align_set(wd->time[TIME_AMPM], EVAS_HINT_FILL, EVAS_HINT_FILL);
870 evas_object_smart_callback_add(wd->time[TIME_AMPM], "clicked", _ampm_clicked_cb, obj);
871 elm_widget_sub_object_add(obj, wd->time[TIME_AMPM]);
875 * Add a new datefield object
876 * The date format and strings are based on current locale
878 * @param parent The parent object
879 * @return The new object or NULL if it cannot be created
884 elm_datefield_add(Evas_Object *parent)
890 e = evas_object_evas_get(parent);
892 wd = ELM_NEW(Widget_Data);
893 obj = elm_widget_add(e);
894 ELM_SET_WIDTYPE(widtype, "datefield");
895 elm_widget_type_set(obj, "datefield");
896 elm_widget_sub_object_add(parent, obj);
897 elm_widget_data_set(obj, wd);
898 elm_widget_del_hook_set(obj, _del_hook);
899 elm_widget_theme_hook_set(obj, _theme_hook);
900 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
901 elm_widget_can_focus_set(obj, EINA_TRUE);
903 wd->base = edje_object_add(e);
904 elm_widget_resize_object_set(obj, wd->base);
905 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.year.over", _signal_rect_mouse_down, obj);
906 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.month.over", _signal_rect_mouse_down, obj);
907 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.day.over", _signal_rect_mouse_down, obj);
909 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.hour.over", _signal_rect_mouse_down, obj);
910 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.min.over", _signal_rect_mouse_down, obj);
912 wd->handler = ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, obj);
913 _date_entry_add(obj);
914 _time_entry_add(obj);
922 wd->year = wd->y_min;
926 wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
927 wd->time_mode = EINA_TRUE;
935 * set layout for the datefield
937 * @param obj The datefield object
938 * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
943 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
945 ELM_CHECK_WIDTYPE(obj, widtype);
946 Widget_Data *wd = elm_widget_data_get(obj);
949 if (layout > ELM_DATEFIELD_LAYOUT_DATEANDTIME) return;
951 if (wd->layout != layout)
960 * get layout of the datefield
962 * @param obj The datefield object
963 * @return layout of the datefield
967 EAPI Elm_Datefield_Layout
968 elm_datefield_layout_get(const Evas_Object *obj)
970 ELM_CHECK_WIDTYPE(obj, widtype) 0;
971 Widget_Data *wd = elm_widget_data_get(obj);
979 * Set selected date of the datefield
981 * @param obj The datefield object
982 * @param year The year to set
983 * @param month The month to set
984 * @param day The day to set
985 * @param hour The hours to set (24hour mode - 0~23)
986 * @param min The minutes to set (0~59)
991 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
993 ELM_CHECK_WIDTYPE(obj, widtype);
994 Widget_Data *wd = elm_widget_data_get(obj);
998 wd->year = _check_date_boundary(obj, year, DATE_YEAR);
999 wd->month = _check_date_boundary(obj, month, DATE_MON);
1000 wd->day = _check_date_boundary(obj, day, DATE_DAY);
1002 if (hour > HOUR_24H_MAXIMUM) wd->hour = HOUR_24H_MAXIMUM;
1003 else if (hour < 0) wd->hour = 0;
1004 else wd->hour = hour;
1006 if (min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
1007 else if (min < 0) wd->min = 0;
1014 * Get selected date of the datefield
1016 * @param obj The datefield object
1017 * @param year The pointer to the variable get the selected year
1018 * @param month The pointer to the variable get the selected month
1019 * @param day The pointer to the variable get the selected day
1020 * @param hour The pointer to the variable get the selected hour (24hour mode)
1021 * @param hour The pointer to the variable get the selected min
1023 * @ingroup Datefield
1026 elm_datefield_date_get(const Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
1028 ELM_CHECK_WIDTYPE(obj, widtype);
1029 Widget_Data *wd = elm_widget_data_get(obj);
1046 * Set upper boundary of the datefield
1048 * @param obj The datefield object
1049 * @param year The year to set
1050 * @param month The month to set
1051 * @param day The day to set
1052 * @return TRUE/FALSE
1054 * @ingroup Datefield
1057 elm_datefield_date_max_set(Evas_Object *obj, int year, int month, int day)
1059 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1060 Widget_Data *wd = elm_widget_data_get(obj);
1062 Eina_Bool update = EINA_FALSE;
1064 if (!wd) return EINA_FALSE;
1065 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1066 day_of_month = _maximum_day_get(year, month);
1067 if (day < 1 || day > day_of_month) return EINA_FALSE;
1073 if (wd->year > wd->y_max)
1075 wd->year = wd->y_max;
1078 if (wd->year == wd->y_max && wd->month > wd->m_max)
1080 wd->month = wd->m_max;
1083 if (wd->year == wd->y_max && wd->month == wd->m_max && wd->day > wd->d_max)
1085 wd->day = wd->d_max;
1089 if (update) _date_update(obj);
1094 * Get upper boundary of the datefield
1096 * @param obj The datefield object
1097 * @param year The pointer to the variable get the maximum year
1098 * @param month The pointer to the variable get the maximum month
1099 * @param day The pointer to the variable get the maximum day
1101 * @ingroup Datefield
1104 elm_datefield_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
1106 ELM_CHECK_WIDTYPE(obj, widtype);
1107 Widget_Data *wd = elm_widget_data_get(obj);
1120 * Set lower boundary of the datefield
1122 * @param obj The datefield object
1123 * @param year The year to set
1124 * @param month The month to set
1125 * @param day The day to set
1126 * @return TRUE/FALSE
1128 * @ingroup Datepicker
1131 elm_datefield_date_min_set(Evas_Object *obj, int year, int month, int day)
1133 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1134 Widget_Data *wd = elm_widget_data_get(obj);
1136 Eina_Bool update = EINA_FALSE;
1138 if (!wd) return EINA_FALSE;
1139 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1140 day_of_month = _maximum_day_get(year, month);
1141 if (day < 1 || day > day_of_month) return EINA_FALSE;
1147 if (wd->year < wd->y_min)
1149 wd->year = wd->y_min;
1152 if (wd->year == wd->y_min && wd->month < wd->m_min)
1154 wd->month = wd->m_min;
1157 if (wd->year == wd->y_min && wd->month == wd->m_min && wd->day < wd->d_min)
1159 wd->day = wd->d_min;
1163 if (update) _date_update(obj);
1168 * Get lower boundary of the datefield
1170 * @param obj The datefield object
1171 * @param year The pointer to the variable get the maximum year
1172 * @param month The pointer to the variable get the maximum month
1173 * @param day The pointer to the variable get the maximum day
1175 * @ingroup Datefield
1178 elm_datefield_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
1180 ELM_CHECK_WIDTYPE(obj, widtype);
1181 Widget_Data *wd = elm_widget_data_get(obj);
1194 * Set if the datefield show hours in military or am/pm mode
1196 * @param obj The datefield object
1197 * @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
1199 * @ingroup Datefield
1202 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
1204 ELM_CHECK_WIDTYPE(obj, widtype);
1205 Widget_Data *wd = elm_widget_data_get(obj);
1209 if (wd->time_mode != mode)
1211 wd->time_mode = mode;
1212 if (!wd->time_mode) edje_object_signal_emit(wd->base, "elm,state,mode,24h", "elm");
1213 else edje_object_signal_emit(wd->base, "elm,state,mode,12h", "elm");
1219 * get time mode of the datefield
1221 * @param obj The datefield object
1222 * @return time mode (EINA_TRUE: 12hour mode / EINA_FALSE: 24hour mode)
1224 * @ingroup Datefield
1227 elm_datefield_time_mode_get(const Evas_Object *obj)
1229 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1230 Widget_Data *wd = elm_widget_data_get(obj);
1232 if (!wd) return EINA_FALSE;
1234 return wd->time_mode;
1238 * Set date format of datefield
1240 * @param obj The datefield object
1241 * @param fmt The date format, ex) yymmdd. Default value is mmddyy.
1243 * @ingroup Datefield
1246 elm_datefield_date_format_set(Evas_Object *obj, const char *fmt)
1248 ELM_CHECK_WIDTYPE(obj, widtype);
1249 Widget_Data *wd = elm_widget_data_get(obj);
1250 char sig[32] = "elm,state,format,";
1253 if (!wd || !fmt) return;
1258 sig[j++] = tolower(fmt[i++]);
1260 if (j < 32) sig[j] = '\0';
1261 edje_object_signal_emit(wd->base, sig, "elm");
1263 if (strstr(sig, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
1264 else if (strstr(sig, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
1265 else if (strstr(sig, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
1266 else if (strstr(sig, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
1267 else if (strstr(sig, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
1268 else if (strstr(sig, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
1269 wd->format_exists = EINA_TRUE;
1273 * get date format of the datefield
1275 * @param obj The datefield object
1276 * @return date format string. ex) yymmdd
1278 * @ingroup Datefield
1281 elm_datefield_date_format_get(const Evas_Object *obj)
1283 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1284 Widget_Data *wd = elm_widget_data_get(obj);
1286 switch (wd->date_format)
1288 case DATE_FORMAT_YYMMDD: return "yymmdd";
1289 case DATE_FORMAT_YYDDMM: return "yyddmm";
1290 case DATE_FORMAT_MMYYDD: return "mmyydd";
1291 case DATE_FORMAT_MMDDYY: return "mmddyy";
1292 case DATE_FORMAT_DDYYMM: return "ddyymm";
1293 case DATE_FORMAT_DDMMYY: return "ddmmyy";
1294 default: return NULL;
1299 * Add a callback function for input panel state
1301 * @param obj The datefield object
1302 * @param func The function to be called when the event is triggered (value will be the Ecore_IMF_Input_Panel_State)
1303 * @param data The data pointer to be passed to @p func
1305 * @ingroup Datefield
1308 elm_datefield_input_panel_state_callback_add(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value), void *data)
1310 ELM_CHECK_WIDTYPE(obj, widtype);
1311 Widget_Data *wd = elm_widget_data_get(obj);
1316 if (wd->func && (wd->func != pEventCallbackFunc))
1317 elm_datefield_input_panel_state_callback_del(obj, wd->func);
1319 if (wd->func != pEventCallbackFunc)
1321 wd->func = pEventCallbackFunc;
1322 wd->func_data = data;
1324 for (i = 0; i < DATE_MAX; i++)
1325 ecore_imf_context_input_panel_event_callback_add(
1326 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1328 for (i = 0; i < TIME_MAX-1; i++)
1329 ecore_imf_context_input_panel_event_callback_add(
1330 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1335 * Delete a callback function for input panel state
1337 * @param obj The datefield object
1338 * @param func The function to be called when the event is triggered
1340 * @ingroup Datefield
1343 elm_datefield_input_panel_state_callback_del(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value))
1345 ELM_CHECK_WIDTYPE(obj, widtype);
1346 Widget_Data *wd = elm_widget_data_get(obj);
1351 if (wd->func && wd->func == pEventCallbackFunc)
1353 for (i = 0; i < DATE_MAX; i++)
1354 ecore_imf_context_input_panel_event_callback_del(
1355 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1357 for (i = 0; i < TIME_MAX-1; i++)
1358 ecore_imf_context_input_panel_event_callback_del(
1359 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1362 wd->func_data = NULL;