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_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
80 static void _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
81 static void _entry_focused_cb(void *data, Evas_Object *obj, void *event_info);
82 static void _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info);
83 static void _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info);
84 static Eina_Bool _imf_event_commit_cb(void *data, int type, void *event);
85 static void _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value);
87 static void _date_entry_add(Evas_Object *obj);
88 static void _time_entry_add(Evas_Object *obj);
89 static void _date_update(Evas_Object *obj);
90 static Eina_Bool _focus_idler_cb(void *obj);
91 static void _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj);
92 static Eina_Bool _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen);
93 static char* _get_i18n_string(Evas_Object *obj, nl_item item);
94 static int _maximum_day_get(int year, int month);
95 static int _check_date_boundary(Evas_Object *obj, int num, int flag);
98 _del_hook(Evas_Object *obj)
100 Widget_Data *wd = elm_widget_data_get(obj);
103 ecore_event_handler_del(wd->handler);
109 _on_focus_hook(void *data, 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 = ecore_idler_add(_focus_idler_cb, obj);
118 _theme_hook(Evas_Object *obj)
120 Widget_Data *wd = elm_widget_data_get(obj);
124 if (!wd || !wd->base) return;
126 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
128 _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
130 for (i = 0; i < DATE_MAX; i++)
131 elm_object_style_set(wd->date[i], "datefield/hybrid");
132 for (i = 0; i < TIME_MAX; i++)
133 elm_object_style_set(wd->time[i], "datefield/hybrid");
135 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
137 _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
139 for (i = 0; i < DATE_MAX; i++)
140 elm_object_style_set(wd->date[i], "datefield");
142 for (i = 0; i < TIME_MAX; i++)
143 evas_object_hide(wd->time[i]);
145 else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
147 _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
149 for (i = 0; i < TIME_MAX; i++)
150 elm_object_style_set(wd->time[i], "datefield");
152 for (i = 0; i < DATE_MAX; i++)
153 evas_object_hide(wd->date[i]);
156 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
158 edje_object_part_swallow(wd->base, "elm.swallow.date.year", wd->date[DATE_YEAR]);
159 edje_object_part_swallow(wd->base, "elm.swallow.date.month", wd->date[DATE_MON]);
160 edje_object_part_swallow(wd->base, "elm.swallow.date.day", wd->date[DATE_DAY]);
161 edje_object_part_text_set(wd->base, "elm.text.date.comma", ",");
164 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
166 edje_object_part_swallow(wd->base, "elm.swallow.time.hour", wd->time[TIME_HOUR]);
167 edje_object_part_swallow(wd->base, "elm.swallow.time.min", wd->time[TIME_MIN]);
168 edje_object_part_text_set(wd->base, "elm.text.colon", ":");
171 edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
174 if (wd->format_exists)
175 sprintf(sig, "elm,state,format,%s", elm_datefield_date_format_get(obj));
178 char *str = _get_i18n_string(obj, D_FMT);
181 if (!strcmp(str, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
182 else if (!strcmp(str, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
183 else if (!strcmp(str, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
184 else if (!strcmp(str, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
185 else if (!strcmp(str, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
186 else if (!strcmp(str, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
187 sprintf(sig, "elm,state,format,%s",str);
191 edje_object_signal_emit(wd->base, sig, "elm");
198 _sizing_eval(Evas_Object *obj)
200 Widget_Data *wd = elm_widget_data_get(obj);
201 Evas_Coord minw = -1, minh = -1;
203 edje_object_size_min_calc(wd->base, &minw, &minh);
204 evas_object_size_hint_min_set(obj, minw, minh);
205 evas_object_size_hint_max_set(obj, -1, -1);
209 _signal_ampm_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
211 Widget_Data *wd = elm_widget_data_get(data);
212 Evas_Object *focus_obj;
214 if (!wd || !wd->base) return ;
216 focus_obj = elm_widget_focused_object_get(data);
217 if (focus_obj) elm_object_unfocus(focus_obj);
221 _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
223 Widget_Data *wd = elm_widget_data_get(data);
226 if (!wd || !wd->base) return ;
231 str = _get_i18n_string(data, PM_STR);
234 edje_object_part_text_set(wd->base, "elm.text.ampm", str);
237 wd->hour += HOUR_12H_MAXIMUM;
241 str = _get_i18n_string(data, AM_STR);
244 edje_object_part_text_set(wd->base, "elm.text.ampm", str);
247 wd->hour -= HOUR_12H_MAXIMUM;
249 evas_object_smart_callback_call(data, "changed", NULL);
253 _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
255 Widget_Data *wd = elm_widget_data_get(data);
258 if (!strcmp(source, "elm.rect.date.year.over"))
259 elm_object_focus(wd->date[DATE_YEAR]);
260 else if (!strcmp(source, "elm.rect.date.month.over"))
261 elm_object_focus(wd->date[DATE_MON]);
262 else if (!strcmp(source, "elm.rect.date.day.over"))
263 elm_object_focus(wd->date[DATE_DAY]);
264 else if (!strcmp(source, "elm.rect.time.hour.over"))
265 elm_object_focus(wd->time[TIME_HOUR]);
266 else if (!strcmp(source, "elm.rect.time.min.over"))
267 elm_object_focus(wd->time[TIME_MIN]);
268 else if (!strcmp(source, "elm.rect.date.left.pad"))
270 switch (wd->date_format)
272 case DATE_FORMAT_YYDDMM:
273 case DATE_FORMAT_YYMMDD:
274 elm_object_focus(wd->date[DATE_YEAR]);
276 case DATE_FORMAT_MMDDYY:
277 case DATE_FORMAT_MMYYDD:
278 elm_object_focus(wd->date[DATE_MON]);
280 case DATE_FORMAT_DDMMYY:
281 case DATE_FORMAT_DDYYMM:
282 elm_object_focus(wd->date[DATE_DAY]);
285 else if (!strcmp(source, "elm.rect.date.right.pad"))
287 switch (wd->date_format)
289 case DATE_FORMAT_MMDDYY:
290 case DATE_FORMAT_DDMMYY:
291 elm_object_focus(wd->date[DATE_YEAR]);
293 case DATE_FORMAT_DDYYMM:
294 case DATE_FORMAT_YYDDMM:
295 elm_object_focus(wd->date[DATE_MON]);
297 case DATE_FORMAT_YYMMDD:
298 case DATE_FORMAT_MMYYDD:
299 elm_object_focus(wd->date[DATE_DAY]);
305 _focus_idler_cb(void *obj)
307 Widget_Data *wd = elm_widget_data_get(obj);
308 Evas_Object *focus_obj;
310 focus_obj = elm_widget_focused_object_get(obj);
311 if (focus_obj == obj)
313 if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
314 elm_object_focus(wd->time[TIME_HOUR]);
316 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
318 switch (wd->date_format)
320 case DATE_FORMAT_YYDDMM:
321 case DATE_FORMAT_YYMMDD:
322 elm_object_focus(wd->date[DATE_YEAR]);
324 case DATE_FORMAT_MMDDYY:
325 case DATE_FORMAT_MMYYDD:
326 elm_object_focus(wd->date[DATE_MON]);
328 case DATE_FORMAT_DDMMYY:
329 case DATE_FORMAT_DDYYMM:
330 elm_object_focus(wd->date[DATE_DAY]);
339 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
341 Widget_Data *wd = elm_widget_data_get(data);
342 if (!wd || !wd->base) return;
346 ecore_idler_del(wd->idler);
350 if (obj == wd->date[DATE_YEAR])
351 edje_object_signal_emit(wd->base, "elm,state,year,focus,in", "elm");
352 else if (obj == wd->date[DATE_MON])
353 edje_object_signal_emit(wd->base, "elm,state,month,focus,in", "elm");
354 else if (obj == wd->date[DATE_DAY])
355 edje_object_signal_emit(wd->base, "elm,state,day,focus,in", "elm");
356 else if (obj == wd->time[TIME_HOUR])
357 edje_object_signal_emit(wd->base, "elm,state,hour,focus,in", "elm");
358 else if (obj == wd->time[TIME_MIN])
359 edje_object_signal_emit(wd->base, "elm,state,min,focus,in", "elm");
363 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
365 Widget_Data *wd = elm_widget_data_get(data);
366 char str[YEAR_MAX_LENGTH+1] = {0,};
370 if (!wd || !wd->base) return;
373 if (obj == wd->date[DATE_YEAR])
375 if (strlen(elm_entry_entry_get(wd->date[DATE_YEAR])))
376 wd->year = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
377 wd->year = _check_date_boundary(data, wd->year, DATE_YEAR);
378 sprintf(str, "%d", wd->year);
379 elm_entry_entry_set(wd->date[DATE_YEAR], str);
380 //check month boundary
381 if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
384 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
387 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
392 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
395 sprintf(str, "%d", wd->day);
396 elm_entry_entry_set(wd->date[DATE_DAY], str);
398 edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
400 else if (obj == wd->date[DATE_MON])
402 if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
405 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
408 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
413 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
416 sprintf(str, "%d", wd->day);
417 elm_entry_entry_set(wd->date[DATE_DAY], str);
419 edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
421 else if (obj == wd->date[DATE_DAY])
423 if (strlen(elm_entry_entry_get(wd->date[DATE_DAY])))
424 wd->day = atoi(elm_entry_entry_get(wd->date[DATE_DAY]));
425 wd->day = _check_date_boundary(data, wd->day, DATE_DAY);
426 sprintf(str, "%d", wd->day);
427 elm_entry_entry_set(wd->date[DATE_DAY], str);
428 edje_object_signal_emit(wd->base, "elm,state,day,focus,out", "elm");
430 else if (obj == wd->time[TIME_HOUR])
432 if (strlen(elm_entry_entry_get(wd->time[TIME_HOUR])))
433 num = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
436 if (!wd->time_mode) // 24 mode
438 if (num > HOUR_24H_MAXIMUM) num = HOUR_24H_MAXIMUM;
443 if (num > HOUR_24H_MAXIMUM || num == 0)
445 num = HOUR_12H_MAXIMUM;
448 else if (num > HOUR_12H_MAXIMUM)
450 num -= HOUR_12H_MAXIMUM;
453 wd->hour = (wd->pm == EINA_TRUE)? num + HOUR_12H_MAXIMUM : num;
454 if ((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
457 i18n_str = _get_i18n_string(data, PM_STR);
460 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
466 i18n_str = _get_i18n_string(data, AM_STR);
469 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
474 sprintf(str, "%02d", num);
475 elm_entry_entry_set(wd->time[TIME_HOUR], str);
476 edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
478 else if (obj == wd->time[TIME_MIN])
480 if (strlen(elm_entry_entry_get(wd->time[TIME_MIN])))
481 wd->min = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
482 if (wd->min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
484 sprintf(str, "%02d", wd->min);
485 elm_entry_entry_set(wd->time[TIME_MIN], str);
486 edje_object_signal_emit(wd->base, "elm,state,min,focus,out", "elm");
488 evas_object_smart_callback_call(data, "changed", NULL);
492 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
494 Widget_Data *wd = elm_widget_data_get(obj);
497 if (focus_obj == wd->date[DATE_YEAR])
499 switch (wd->date_format)
501 case DATE_FORMAT_DDMMYY:
502 case DATE_FORMAT_MMDDYY:
504 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
505 elm_object_focus(wd->time[TIME_HOUR]);
506 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
507 elm_object_unfocus(wd->date[DATE_YEAR]);
510 case DATE_FORMAT_DDYYMM:
511 case DATE_FORMAT_YYMMDD:
512 elm_object_focus(wd->date[DATE_MON]);
514 case DATE_FORMAT_MMYYDD:
515 case DATE_FORMAT_YYDDMM:
516 elm_object_focus(wd->date[DATE_DAY]);
519 else if (focus_obj == wd->date[DATE_MON])
521 switch (wd->date_format)
523 case DATE_FORMAT_DDYYMM:
524 case DATE_FORMAT_YYDDMM:
526 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
527 elm_object_focus(wd->time[TIME_HOUR]);
528 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
529 elm_object_unfocus(wd->date[DATE_MON]);
532 case DATE_FORMAT_DDMMYY:
533 case DATE_FORMAT_MMYYDD:
534 elm_object_focus(wd->date[DATE_YEAR]);
536 case DATE_FORMAT_MMDDYY:
537 case DATE_FORMAT_YYMMDD:
538 elm_object_focus(wd->date[DATE_DAY]);
541 else if (focus_obj == wd->date[DATE_DAY])
543 switch (wd->date_format)
545 case DATE_FORMAT_YYMMDD:
546 case DATE_FORMAT_MMYYDD:
548 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
549 elm_object_focus(wd->time[TIME_HOUR]);
550 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
551 elm_object_unfocus(wd->date[DATE_DAY]);
554 case DATE_FORMAT_DDYYMM:
555 case DATE_FORMAT_MMDDYY:
556 elm_object_focus(wd->date[DATE_YEAR]);
558 case DATE_FORMAT_DDMMYY:
559 case DATE_FORMAT_YYDDMM:
560 elm_object_focus(wd->date[DATE_MON]);
563 else if (focus_obj == wd->time[TIME_HOUR])
564 elm_object_focus(wd->time[TIME_MIN]);
565 else if (focus_obj == wd->time[TIME_MIN])
566 elm_object_unfocus(wd->time[TIME_MIN]);
570 _check_date_boundary(Evas_Object *obj, int num, int flag)
572 Widget_Data *wd = elm_widget_data_get(obj);
573 if (flag == DATE_YEAR)
575 if (num > wd->y_max) num = wd->y_max;
576 else if (num < wd->y_min) num = wd->y_min;
580 else if (flag == DATE_MON)
582 if (wd->year == wd->y_max && num > wd->m_max) num = wd->m_max;
583 else if (wd->year == wd->y_min && num < wd->m_min) num = wd->m_min;
584 else if (num > MONTH_MAXIMUM) num = MONTH_MAXIMUM;
585 else if (num <= 0) num = 1;
589 else if (flag == DATE_DAY)
591 int day_of_month = _maximum_day_get(wd->year, wd->month);
592 if (wd->year == wd->y_max && wd->month == wd->m_max && num > wd->d_max) num = wd->d_max;
593 else if (wd->year == wd->y_min && wd->month == wd->m_min && num < wd->d_min) num = wd->d_min;
594 else if (num > day_of_month) num = day_of_month;
595 else if (num <= 0) num = 1;
602 _get_i18n_string(Evas_Object *obj, nl_item item)
604 Widget_Data *wd = elm_widget_data_get(obj);
609 if (!wd) return NULL;
611 fmt = nl_langinfo(item);
612 if (!fmt) return NULL;
617 str = calloc(7, sizeof(char));
620 if (fmt[i] == '%' && fmt[i+1])
625 case 'Y': case 'M': case 'D': case 'y': case 'm': case 'd':
626 str[j++] = tolower(fmt[i]);
627 str[j++] = tolower(fmt[i]);
638 str = calloc(strlen(fmt)+1, sizeof(char));
643 str = calloc(3, sizeof(char));
644 if (item == AM_STR) strcpy(str, "AM");
645 else if (item == PM_STR) strcpy(str, "PM");
648 case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: case ABMON_5: case ABMON_6:
649 case ABMON_7: case ABMON_8: case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
650 str = calloc(strlen(fmt)+1, sizeof(char));
654 if (fmt[i] >= '1' && fmt[i] <= '9')
656 if (fmt[i+1] >= '1' && fmt[i+1] <= '9')
668 _maximum_day_get(int year, int month)
670 int day_of_month = 0;
671 if (year == 0 || month == 0) return 0;
683 if ((!(year % 4) && (year % 100)) || !(year % 400))
698 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
700 Widget_Data *wd = elm_widget_data_get(obj);
702 if (!wd) return EINA_FALSE;
704 if (focus_obj == wd->date[DATE_YEAR] && strlen == YEAR_MAX_LENGTH)
705 wd->editing = EINA_FALSE;
706 else if (focus_obj == wd->date[DATE_MON])
707 wd->editing = EINA_FALSE;
708 else if (focus_obj == wd->date[DATE_DAY])
710 if (strlen == DAY_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 3)
711 wd->editing = EINA_FALSE;
713 else if (focus_obj == wd->time[TIME_HOUR])
715 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
716 wd->editing = EINA_FALSE;
718 else if (focus_obj == wd->time[TIME_MIN])
720 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 5)
721 wd->editing = EINA_FALSE;
727 _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info)
729 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
731 if (!strcmp(ev->keyname, "BackSpace"))
732 elm_entry_entry_set(obj, "");
736 _imf_event_commit_cb(void *data, int type, void *event)
738 Widget_Data *wd = elm_widget_data_get(data);
739 Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event;
740 Evas_Object *focus_obj;
741 char str[YEAR_MAX_LENGTH+1] = {0,};
743 if (!wd) return ECORE_CALLBACK_PASS_ON;
744 if (!elm_widget_focus_get(data)) return ECORE_CALLBACK_PASS_ON;
746 focus_obj = elm_widget_focused_object_get(data);
749 elm_entry_entry_set(focus_obj, "");
750 wd->editing = EINA_TRUE;
752 if (focus_obj == wd->date[DATE_MON])
755 wd->month = atoi(ev->str);
756 i18n_str = _get_i18n_string(data, ABMON_1+wd->month-1);
759 elm_entry_entry_set(focus_obj, i18n_str);
765 strcpy(str, elm_entry_entry_get(focus_obj));
766 str[strlen(str)] = ev->str[0];
767 elm_entry_entry_set(focus_obj, str);
770 if (_check_input_done(data, focus_obj, strlen(str)))
771 _entry_focus_move(data, focus_obj);
773 return ECORE_CALLBACK_DONE;
777 _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value)
779 Widget_Data *wd = elm_widget_data_get(data);
784 wd->func(wd->func_data, data, value);
788 _date_update(Evas_Object *obj)
790 Widget_Data *wd = elm_widget_data_get(obj);
791 char str[YEAR_MAX_LENGTH+1] = {0,};
794 if (!wd || !wd->base) return;
796 sprintf(str, "%d", wd->year);
797 elm_entry_entry_set(wd->date[DATE_YEAR], str);
799 i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
802 elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
806 sprintf(str, "%d", wd->day);
807 elm_entry_entry_set(wd->date[DATE_DAY], str);
809 if (!wd->time_mode) //24 mode
810 sprintf(str, "%d", wd->hour);
813 if (wd->hour >= HOUR_12H_MAXIMUM)
816 i18n_str = _get_i18n_string(obj, PM_STR);
819 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
826 i18n_str = _get_i18n_string(obj, AM_STR);
829 edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
834 if (wd->hour > HOUR_12H_MAXIMUM)
835 sprintf(str, "%02d", wd->hour - HOUR_12H_MAXIMUM);
836 else if (wd->hour == 0)
837 sprintf(str, "%02d", HOUR_12H_MAXIMUM);
839 sprintf(str, "%02d", wd->hour);
841 elm_entry_entry_set(wd->time[TIME_HOUR], str);
842 sprintf(str, "%02d", wd->min);
843 elm_entry_entry_set(wd->time[TIME_MIN], str);
847 _date_entry_add(Evas_Object *obj)
849 Widget_Data *wd = elm_widget_data_get(obj);
854 for (i = 0; i < DATE_MAX; i++)
856 wd->date[i] = elm_entry_add(obj);
857 elm_entry_single_line_set(wd->date[i], EINA_TRUE);
858 elm_entry_context_menu_disabled_set(wd->date[i], EINA_TRUE);
859 if (i == DATE_MON) elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_MONTH);
860 else elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
861 evas_object_size_hint_weight_set(wd->date[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
862 evas_object_size_hint_align_set(wd->date[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
863 evas_object_smart_callback_add(wd->date[i], "focused", _entry_focused_cb, obj);
864 evas_object_smart_callback_add(wd->date[i], "unfocused", _entry_unfocused_cb, obj);
865 evas_object_event_callback_add(wd->date[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
866 elm_widget_sub_object_add(obj, wd->date[i]);
868 elm_entry_maximum_bytes_set(wd->date[DATE_YEAR], YEAR_MAX_LENGTH);
869 elm_entry_maximum_bytes_set(wd->date[DATE_DAY], DAY_MAX_LENGTH);
873 _time_entry_add(Evas_Object *obj)
875 Widget_Data *wd = elm_widget_data_get(obj);
880 for (i = 0; i < TIME_MAX; i++)
882 wd->time[i] = elm_entry_add(obj);
883 elm_entry_single_line_set(wd->time[i], EINA_TRUE);
884 elm_entry_context_menu_disabled_set(wd->time[i], EINA_TRUE);
885 elm_entry_input_panel_layout_set(wd->time[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
886 elm_entry_maximum_bytes_set(wd->time[i], TIME_MAX_LENGTH);
887 evas_object_size_hint_weight_set(wd->time[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
888 evas_object_size_hint_align_set(wd->time[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
889 evas_object_smart_callback_add(wd->time[i], "focused", _entry_focused_cb, obj);
890 evas_object_smart_callback_add(wd->time[i], "unfocused", _entry_unfocused_cb, obj);
891 evas_object_event_callback_add(wd->time[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
892 elm_widget_sub_object_add(obj, wd->time[i]);
897 * Add a new datefield object
898 * The date format and strings are based on current locale
900 * @param parent The parent object
901 * @return The new object or NULL if it cannot be created
906 elm_datefield_add(Evas_Object *parent)
912 e = evas_object_evas_get(parent);
914 wd = ELM_NEW(Widget_Data);
915 obj = elm_widget_add(e);
916 ELM_SET_WIDTYPE(widtype, "datefield");
917 elm_widget_type_set(obj, "datefield");
918 elm_widget_sub_object_add(parent, obj);
919 elm_widget_data_set(obj, wd);
920 elm_widget_del_hook_set(obj, _del_hook);
921 elm_widget_theme_hook_set(obj, _theme_hook);
922 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
923 elm_widget_can_focus_set(obj, EINA_TRUE);
925 wd->base = edje_object_add(e);
926 elm_widget_resize_object_set(obj, wd->base);
927 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.left.pad", _signal_rect_mouse_down, obj);
928 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.year.over", _signal_rect_mouse_down, obj);
929 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.month.over", _signal_rect_mouse_down, obj);
930 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.day.over", _signal_rect_mouse_down, obj);
931 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.right.pad", _signal_rect_mouse_down, obj);
933 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.hour.over", _signal_rect_mouse_down, obj);
934 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.min.over", _signal_rect_mouse_down, obj);
935 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.ampm.over", _signal_ampm_mouse_down, obj);
936 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "elm.rect.time.ampm.over", _signal_ampm_clicked, obj);
938 wd->handler = ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, obj);
939 _date_entry_add(obj);
940 _time_entry_add(obj);
948 wd->year = wd->y_min;
952 wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
953 wd->time_mode = EINA_TRUE;
961 * set layout for the datefield
963 * @param obj The datefield object
964 * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
969 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
971 ELM_CHECK_WIDTYPE(obj, widtype);
972 Widget_Data *wd = elm_widget_data_get(obj);
975 if (layout < ELM_DATEFIELD_LAYOUT_TIME ||layout > ELM_DATEFIELD_LAYOUT_DATEANDTIME) return;
977 if (wd->layout != layout)
986 * get layout of the datefield
988 * @param obj The datefield object
989 * @return layout of the datefield
993 EAPI Elm_Datefield_Layout
994 elm_datefield_layout_get(const Evas_Object *obj)
996 ELM_CHECK_WIDTYPE(obj, widtype) 0;
997 Widget_Data *wd = elm_widget_data_get(obj);
1005 * Set selected date of the datefield
1007 * @param obj The datefield object
1008 * @param year The year to set
1009 * @param month The month to set
1010 * @param day The day to set
1011 * @param hour The hours to set (24hour mode - 0~23)
1012 * @param min The minutes to set (0~59)
1014 * @ingroup Datefield
1017 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
1019 ELM_CHECK_WIDTYPE(obj, widtype);
1020 Widget_Data *wd = elm_widget_data_get(obj);
1024 wd->year = _check_date_boundary(obj, year, DATE_YEAR);
1025 wd->month = _check_date_boundary(obj, month, DATE_MON);
1026 wd->day = _check_date_boundary(obj, day, DATE_DAY);
1028 if (hour > HOUR_24H_MAXIMUM) wd->hour = HOUR_24H_MAXIMUM;
1029 else if (hour < 0) wd->hour = 0;
1030 else wd->hour = hour;
1032 if (min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
1033 else if (min < 0) wd->min = 0;
1040 * Get selected date of the datefield
1042 * @param obj The datefield object
1043 * @param year The pointer to the variable get the selected year
1044 * @param month The pointer to the variable get the selected month
1045 * @param day The pointer to the variable get the selected day
1046 * @param hour The pointer to the variable get the selected hour (24hour mode)
1047 * @param hour The pointer to the variable get the selected min
1049 * @ingroup Datefield
1052 elm_datefield_date_get(const Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
1054 ELM_CHECK_WIDTYPE(obj, widtype);
1055 Widget_Data *wd = elm_widget_data_get(obj);
1072 * Set upper boundary of the datefield
1074 * @param obj The datefield object
1075 * @param year The year to set
1076 * @param month The month to set
1077 * @param day The day to set
1078 * @return TRUE/FALSE
1080 * @ingroup Datefield
1083 elm_datefield_date_max_set(Evas_Object *obj, int year, int month, int day)
1085 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1086 Widget_Data *wd = elm_widget_data_get(obj);
1088 Eina_Bool update = EINA_FALSE;
1090 if (!wd) return EINA_FALSE;
1091 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1092 day_of_month = _maximum_day_get(year, month);
1093 if (day < 1 || day > day_of_month) return EINA_FALSE;
1099 if (wd->year > wd->y_max)
1101 wd->year = wd->y_max;
1104 if (wd->year == wd->y_max && wd->month > wd->m_max)
1106 wd->month = wd->m_max;
1109 if (wd->year == wd->y_max && wd->month == wd->m_max && wd->day > wd->d_max)
1111 wd->day = wd->d_max;
1115 if (update) _date_update(obj);
1120 * Get upper boundary of the datefield
1122 * @param obj The datefield object
1123 * @param year The pointer to the variable get the maximum year
1124 * @param month The pointer to the variable get the maximum month
1125 * @param day The pointer to the variable get the maximum day
1127 * @ingroup Datefield
1130 elm_datefield_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
1132 ELM_CHECK_WIDTYPE(obj, widtype);
1133 Widget_Data *wd = elm_widget_data_get(obj);
1146 * Set lower boundary of the datefield
1148 * @param obj The datefield object
1149 * @param year The year to set
1150 * @param month The month to set
1151 * @param day The day to set
1152 * @return TRUE/FALSE
1154 * @ingroup Datepicker
1157 elm_datefield_date_min_set(Evas_Object *obj, int year, int month, int day)
1159 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1160 Widget_Data *wd = elm_widget_data_get(obj);
1162 Eina_Bool update = EINA_FALSE;
1164 if (!wd) return EINA_FALSE;
1165 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1166 day_of_month = _maximum_day_get(year, month);
1167 if (day < 1 || day > day_of_month) return EINA_FALSE;
1173 if (wd->year < wd->y_min)
1175 wd->year = wd->y_min;
1178 if (wd->year == wd->y_min && wd->month < wd->m_min)
1180 wd->month = wd->m_min;
1183 if (wd->year == wd->y_min && wd->month == wd->m_min && wd->day < wd->d_min)
1185 wd->day = wd->d_min;
1189 if (update) _date_update(obj);
1194 * Get lower boundary of the datefield
1196 * @param obj The datefield object
1197 * @param year The pointer to the variable get the maximum year
1198 * @param month The pointer to the variable get the maximum month
1199 * @param day The pointer to the variable get the maximum day
1201 * @ingroup Datefield
1204 elm_datefield_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
1206 ELM_CHECK_WIDTYPE(obj, widtype);
1207 Widget_Data *wd = elm_widget_data_get(obj);
1220 * Set if the datefield show hours in military or am/pm mode
1222 * @param obj The datefield object
1223 * @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
1225 * @ingroup Datefield
1228 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
1230 ELM_CHECK_WIDTYPE(obj, widtype);
1231 Widget_Data *wd = elm_widget_data_get(obj);
1235 if (wd->time_mode != mode)
1237 wd->time_mode = mode;
1238 if (!wd->time_mode) edje_object_signal_emit(wd->base, "elm,state,mode,24h", "elm");
1239 else edje_object_signal_emit(wd->base, "elm,state,mode,12h", "elm");
1245 * get time mode of the datefield
1247 * @param obj The datefield object
1248 * @return time mode (EINA_TRUE: 12hour mode / EINA_FALSE: 24hour mode)
1250 * @ingroup Datefield
1253 elm_datefield_time_mode_get(const Evas_Object *obj)
1255 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1256 Widget_Data *wd = elm_widget_data_get(obj);
1258 if (!wd) return EINA_FALSE;
1260 return wd->time_mode;
1264 * Set date format of datefield
1266 * @param obj The datefield object
1267 * @param fmt The date format, ex) yymmdd. Default value is mmddyy.
1269 * @ingroup Datefield
1272 elm_datefield_date_format_set(Evas_Object *obj, const char *fmt)
1274 ELM_CHECK_WIDTYPE(obj, widtype);
1275 Widget_Data *wd = elm_widget_data_get(obj);
1276 char sig[32] = "elm,state,format,";
1279 if (!wd || !fmt) return;
1284 sig[j++] = tolower(fmt[i++]);
1287 edje_object_signal_emit(wd->base, sig, "elm");
1289 if (strstr(sig, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
1290 else if (strstr(sig, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
1291 else if (strstr(sig, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
1292 else if (strstr(sig, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
1293 else if (strstr(sig, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
1294 else if (strstr(sig, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
1295 wd->format_exists = EINA_TRUE;
1299 * get date format of the datefield
1301 * @param obj The datefield object
1302 * @return date format string. ex) yymmdd
1304 * @ingroup Datefield
1307 elm_datefield_date_format_get(const Evas_Object *obj)
1309 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1310 Widget_Data *wd = elm_widget_data_get(obj);
1312 switch (wd->date_format)
1314 case DATE_FORMAT_YYMMDD: return "yymmdd";
1315 case DATE_FORMAT_YYDDMM: return "yyddmm";
1316 case DATE_FORMAT_MMYYDD: return "mmyydd";
1317 case DATE_FORMAT_MMDDYY: return "mmddyy";
1318 case DATE_FORMAT_DDYYMM: return "ddyymm";
1319 case DATE_FORMAT_DDMMYY: return "ddmmyy";
1324 * Add a callback function for input panel state
1326 * @param obj The datefield object
1327 * @param func The function to be called when the event is triggered (value will be the Ecore_IMF_Input_Panel_State)
1328 * @param data The data pointer to be passed to @p func
1330 * @ingroup Datefield
1333 elm_datefield_input_panel_state_callback_add(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value), void *data)
1335 ELM_CHECK_WIDTYPE(obj, widtype);
1336 Widget_Data *wd = elm_widget_data_get(obj);
1341 if (wd->func && (wd->func != pEventCallbackFunc))
1342 elm_datefield_input_panel_state_callback_del(obj, wd->func);
1344 if (wd->func != pEventCallbackFunc)
1346 wd->func = pEventCallbackFunc;
1347 wd->func_data = data;
1349 for (i = 0; i < DATE_MAX; i++)
1350 ecore_imf_context_input_panel_event_callback_add(
1351 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1353 for (i = 0; i < TIME_MAX; i++)
1354 ecore_imf_context_input_panel_event_callback_add(
1355 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1360 * Delete a callback function for input panel state
1362 * @param obj The datefield object
1363 * @param func The function to be called when the event is triggered
1365 * @ingroup Datefield
1368 elm_datefield_input_panel_state_callback_del(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value))
1370 ELM_CHECK_WIDTYPE(obj, widtype);
1371 Widget_Data *wd = elm_widget_data_get(obj);
1376 if (wd->func && wd->func == pEventCallbackFunc)
1378 for (i = 0; i < DATE_MAX; i++)
1379 ecore_imf_context_input_panel_event_callback_del(
1380 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1382 for (i = 0; i < TIME_MAX; i++)
1383 ecore_imf_context_input_panel_event_callback_del(
1384 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1387 wd->func_data = NULL;