Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / lib / elm_datefield.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include <langinfo.h>
4
5 /**
6  * @defgroup Datefield Datefield
7  * @ingroup Elementary
8  *
9  * This is a date editfield. it is used to input date and time using keypad
10  */
11
12 typedef struct _Widget_Data Widget_Data;
13
14 enum 
15 {
16   DATE_YEAR,
17   DATE_MON,
18   DATE_DAY,
19   DATE_MAX
20 };
21
22 enum
23 {
24   TIME_HOUR,
25   TIME_MIN,
26   TIME_AMPM,
27   TIME_MAX
28 };
29
30 enum
31 {
32   DATE_FORMAT_YYMMDD,
33   DATE_FORMAT_YYDDMM,
34   DATE_FORMAT_MMYYDD,
35   DATE_FORMAT_MMDDYY,
36   DATE_FORMAT_DDYYMM,
37   DATE_FORMAT_DDMMYY,
38   DATE_FORMAT_MAX
39 };
40
41 #define YEAR_MAX_LENGTH 4
42 #define DAY_MAX_LENGTH 2
43 #define TIME_MAX_LENGTH 2
44
45 #define MONTH_MAXIMUM 12
46 #define HOUR_24H_MAXIMUM 23
47 #define HOUR_12H_MAXIMUM 12
48 #define MIN_MAXIMUM 59
49
50 struct _Widget_Data
51 {
52    Evas_Object *base;
53    Evas_Object *date[DATE_MAX];
54    Evas_Object *time[TIME_MAX];
55    Ecore_Event_Handler *handler;
56    Ecore_Idler *idler;
57    unsigned int layout;
58
59    int year, month, day, hour, min;
60    int y_max, m_max, d_max;
61    int y_min, m_min, d_min;
62    int date_format;
63    Eina_Bool pm:1;
64    Eina_Bool time_mode:1;
65    Eina_Bool format_exists:1;
66    Eina_Bool editing:1;
67
68    void (*func)(void *data, Evas_Object *obj, int value);
69    void *func_data;
70 };
71
72 static const char *widtype = NULL;
73
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);
78
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);
85
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);
95
96 static void
97 _del_hook(Evas_Object *obj)
98 {
99    Widget_Data *wd = elm_widget_data_get(obj);
100    if (!wd) return ;
101
102    ecore_event_handler_del(wd->handler);
103    ecore_idler_del(wd->idler);
104
105    free(wd);
106 }
107
108 static void
109 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
110 {
111    Widget_Data *wd = elm_widget_data_get(obj);
112    if (!wd || !wd->base) return ;
113
114    if ((elm_widget_focus_get(obj))&&(!wd->idler))  wd->idler = ecore_idler_add(_focus_idler_cb, obj);
115 }
116
117 static void
118 _theme_hook(Evas_Object *obj)
119 {
120    Widget_Data *wd = elm_widget_data_get(obj);
121    char sig[32] = {0,};
122    int i;
123    char buf[1024];
124
125    if (!wd || !wd->base) return;
126
127    if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
128      {
129         _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
130
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");
135
136         snprintf(buf, sizeof(buf), "datefield.ampm/%s", elm_widget_style_get(obj));
137         elm_object_style_set(wd->time[TIME_AMPM], buf);
138      }
139    else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
140      {
141         _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
142
143         for (i = 0; i < DATE_MAX; i++)
144           elm_object_style_set(wd->date[i], "datefield");
145
146         for (i = 0; i < TIME_MAX; i++)
147           evas_object_hide(wd->time[i]);
148      }
149    else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
150      {
151         _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
152
153         for (i = 0; i < TIME_MAX-1; i++)
154           elm_object_style_set(wd->time[i], "datefield");
155
156         snprintf(buf, sizeof(buf), "datefield.ampm/%s", elm_widget_style_get(obj));
157         elm_object_style_set(wd->time[TIME_AMPM], buf);
158
159         for (i = 0; i < DATE_MAX; i++)
160           evas_object_hide(wd->date[i]);
161      }
162
163    if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
164      {
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", ",");
169      }
170
171    if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
172      {
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", ":");
177      }
178
179    edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
180
181    //set date format
182    if (wd->format_exists)
183      sprintf(sig, "elm,state,format,%s", elm_datefield_date_format_get(obj));
184    else
185      {
186         char *str = _get_i18n_string(obj, D_FMT);
187         if (str) 
188           {
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);
196              free(str);
197           }
198      }
199    edje_object_signal_emit(wd->base, sig, "elm");
200
201    _date_update(obj);
202    _sizing_eval(obj);
203 }
204
205 static void
206 _sizing_eval(Evas_Object *obj)
207 {
208    Widget_Data *wd = elm_widget_data_get(obj);
209    Evas_Coord minw = -1, minh = -1;
210
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);
214 }
215
216 static void
217 _ampm_clicked_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
218 {
219    Widget_Data *wd = elm_widget_data_get(data);
220    char *str;
221
222    if (!wd || !wd->base) return ;
223
224    wd->pm = !wd->pm; 
225    if (wd->pm)
226      {
227         str = _get_i18n_string(data, PM_STR);
228         if (str) 
229           {
230          elm_button_label_set(wd->time[TIME_AMPM], str);
231              free(str);
232           }
233         wd->hour += HOUR_12H_MAXIMUM;
234      }
235    else
236      {
237         str = _get_i18n_string(data, AM_STR);
238         if (str)
239           {
240          elm_button_label_set(wd->time[TIME_AMPM], str);
241              free(str);
242           }
243         wd->hour -= HOUR_12H_MAXIMUM;
244      }
245    evas_object_smart_callback_call(data, "changed", NULL);
246 }
247
248 static void
249 _signal_rect_mouse_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source)
250 {
251    Widget_Data *wd = elm_widget_data_get(data);
252    if (!wd) return;
253
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]);
264 }
265
266 static Eina_Bool 
267 _focus_idler_cb(void *obj)
268 {
269    Widget_Data *wd = elm_widget_data_get(obj);
270    Evas_Object *focus_obj;
271
272    focus_obj = elm_widget_focused_object_get(obj);
273    if (focus_obj == obj)
274      {
275         if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
276           elm_object_focus(wd->time[TIME_HOUR]);
277
278         else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
279           {
280              switch (wd->date_format)
281                {
282                 case DATE_FORMAT_YYDDMM:
283                 case DATE_FORMAT_YYMMDD:
284                   elm_object_focus(wd->date[DATE_YEAR]);
285                   break;
286                 case DATE_FORMAT_MMDDYY:
287                 case DATE_FORMAT_MMYYDD:
288                   elm_object_focus(wd->date[DATE_MON]);
289                   break;
290                 case DATE_FORMAT_DDMMYY:
291                 case DATE_FORMAT_DDYYMM:
292                   elm_object_focus(wd->date[DATE_DAY]);
293                }
294           }
295      }
296    wd->idler = NULL;
297    return EINA_FALSE;
298 }
299
300 static void
301 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
302 {
303    Widget_Data *wd = elm_widget_data_get(data);
304    if (!wd || !wd->base) return;
305
306    if (wd->idler) 
307      {
308         ecore_idler_del(wd->idler);
309         wd->idler = NULL;
310      }
311
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");
322 }
323
324 static void
325 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
326 {
327    Widget_Data *wd = elm_widget_data_get(data);
328    char str[YEAR_MAX_LENGTH+1] = {0,};
329    char *i18n_str;
330    int num = 0;
331
332    if (!wd || !wd->base) return;
333    wd->editing = FALSE;
334
335    if (obj == wd->date[DATE_YEAR])
336      {
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)))
344           {
345              wd->month = num;
346              i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
347              if (i18n_str)
348                {
349                   elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
350                   free(i18n_str);
351                }
352           }
353         //check day boundary
354         if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
355           {
356              wd->day = num;
357              sprintf(str, "%d", wd->day);
358              elm_entry_entry_set(wd->date[DATE_DAY], str);
359           }
360         edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
361      }
362    else if (obj == wd->date[DATE_MON])
363      {
364         if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
365           {
366              wd->month = num;
367              i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
368              if (i18n_str)
369                {
370                   elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
371                   free(i18n_str);
372                }  
373           }
374         //check day boundary
375         if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
376           {
377              wd->day = num;
378              sprintf(str, "%d", wd->day);               
379              elm_entry_entry_set(wd->date[DATE_DAY], str);
380           }
381         edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
382      }
383    else if (obj == wd->date[DATE_DAY])
384      {
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");
391      }
392    else if (obj == wd->time[TIME_HOUR])
393      {
394         if (strlen(elm_entry_entry_get(wd->time[TIME_HOUR])))
395           num = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
396         else num = wd->hour;
397
398         if (!wd->time_mode) // 24 mode
399           {
400              if (num > HOUR_24H_MAXIMUM) num = HOUR_24H_MAXIMUM;
401              wd->hour = num;
402           }
403         else // 12 mode
404           {
405              if (num > HOUR_24H_MAXIMUM || num == 0)
406                {
407                   num = HOUR_12H_MAXIMUM;
408                   wd->pm = EINA_FALSE;
409                }
410              else if (num > HOUR_12H_MAXIMUM)
411                {
412                   num -= HOUR_12H_MAXIMUM;
413                   wd->pm = EINA_TRUE;
414                }
415              wd->hour = (wd->pm == EINA_TRUE)? num + HOUR_12H_MAXIMUM : num;
416              if ((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
417              if (wd->pm) 
418                {
419                   i18n_str = _get_i18n_string(data, PM_STR);
420                   if (i18n_str)
421                     {
422                elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
423                        free(i18n_str);
424                     }
425                }
426              else 
427                {
428                   i18n_str = _get_i18n_string(data, AM_STR);
429                   if (i18n_str)
430                     {
431                elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
432                        free(i18n_str);
433                     }
434                }
435           }
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");
439      }
440    else if (obj == wd->time[TIME_MIN])
441      {
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;
445
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");
449      }
450    evas_object_smart_callback_call(data, "changed", NULL);
451 }
452
453 static void 
454 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
455 {
456    Widget_Data *wd = elm_widget_data_get(obj);
457    if (!wd) return;
458
459    if (focus_obj == wd->date[DATE_YEAR])
460      {
461         switch (wd->date_format)
462           {
463            case DATE_FORMAT_DDMMYY:
464            case DATE_FORMAT_MMDDYY:
465              {
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]);
470              }
471              break;
472            case DATE_FORMAT_DDYYMM:
473            case DATE_FORMAT_YYMMDD:
474              elm_object_focus(wd->date[DATE_MON]);
475              break;
476            case DATE_FORMAT_MMYYDD:
477            case DATE_FORMAT_YYDDMM:
478              elm_object_focus(wd->date[DATE_DAY]);
479           }
480      }
481    else if (focus_obj == wd->date[DATE_MON])
482      {
483         switch (wd->date_format)
484           {
485            case DATE_FORMAT_DDYYMM:
486            case DATE_FORMAT_YYDDMM:
487              {
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]);
492              }
493              break;
494            case DATE_FORMAT_DDMMYY:
495            case DATE_FORMAT_MMYYDD:
496              elm_object_focus(wd->date[DATE_YEAR]);
497              break;
498            case DATE_FORMAT_MMDDYY:
499            case DATE_FORMAT_YYMMDD:
500              elm_object_focus(wd->date[DATE_DAY]);
501           }
502      }
503    else if (focus_obj == wd->date[DATE_DAY])
504      {
505         switch (wd->date_format)
506           {
507            case DATE_FORMAT_YYMMDD:
508            case DATE_FORMAT_MMYYDD:
509              {
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]);
514              }
515              break;
516            case DATE_FORMAT_DDYYMM:
517            case DATE_FORMAT_MMDDYY:
518              elm_object_focus(wd->date[DATE_YEAR]);
519              break;
520            case DATE_FORMAT_DDMMYY:
521            case DATE_FORMAT_YYDDMM:
522              elm_object_focus(wd->date[DATE_MON]);
523           }
524      }
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]);
531 }
532
533 static int
534 _check_date_boundary(Evas_Object *obj, int num, int flag)
535 {
536    Widget_Data *wd = elm_widget_data_get(obj);
537    if (flag == DATE_YEAR)
538      {
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;
541         return num;
542      }
543
544    else if (flag == DATE_MON)
545      {
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;
550         return num;
551      }
552
553    else if (flag == DATE_DAY)
554      {
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;
560         return num;
561      }
562    return num;
563 }
564
565 static char*
566 _get_i18n_string(Evas_Object *obj, nl_item item)
567 {
568    Widget_Data *wd = elm_widget_data_get(obj);
569    const char *fmt;
570    char *str = NULL;
571    int i = 0, j = 0;
572
573    if (!wd) return NULL;
574
575    fmt = nl_langinfo(item);
576    if (!fmt) return NULL;
577
578    switch (item)
579      {
580       case D_FMT:
581          str = calloc(7, sizeof(char));
582          while (fmt[i]) 
583            {
584               if (fmt[i] == '%' && fmt[i+1]) 
585                 {
586                    i++;
587                    switch (fmt[i]) 
588                      {
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]);
592                          break;
593                      }
594                 }
595               i++;
596            }
597          return str;
598       case AM_STR: 
599       case PM_STR:
600          if (strlen(fmt) > 0)
601            {
602               str = calloc(strlen(fmt)+1, sizeof(char));
603               strcpy(str, fmt);
604            }
605          else
606            {
607               str = calloc(3, sizeof(char));
608               if (item == AM_STR) strcpy(str, "AM");
609               else if (item == PM_STR) strcpy(str, "PM");
610            }
611          return str;
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));
615          while (fmt[i])
616            {
617               str[j++] = fmt[i];
618               if (fmt[i] >= '1' && fmt[i] <= '9')
619                 {
620                    if (fmt[i+1] >= '1' && fmt[i+1] <= '9')
621                      str[j] = fmt[i+1];
622                    break;
623                 }
624               i++;
625            }
626          return str;     
627      }
628    return NULL;
629 }
630
631 static int
632 _maximum_day_get(int year, int month)
633 {
634    int day_of_month = 0;
635    if (year == 0 || month == 0) return 0;
636
637    switch (month)
638      {
639       case 4:
640       case 6:
641       case 9:
642       case 11:
643         day_of_month = 30;
644         break;
645       case 2:
646         {
647            if ((!(year % 4) && (year % 100)) || !(year % 400))
648              day_of_month = 29;
649            else
650              day_of_month = 28;
651         }
652         break;
653       default:
654         day_of_month = 31;
655         break;
656      }
657
658    return day_of_month;
659 }
660
661 static Eina_Bool 
662 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
663 {
664    Widget_Data *wd = elm_widget_data_get(obj);
665
666    if (!wd) return EINA_FALSE;
667
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])
673      {
674         if (strlen == DAY_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 3)
675           wd->editing = EINA_FALSE;
676      }
677    else if (focus_obj == wd->time[TIME_HOUR])
678      {
679         if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
680           wd->editing = EINA_FALSE;
681      }
682    else if (focus_obj == wd->time[TIME_MIN])
683      {
684         if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 5) 
685           wd->editing = EINA_FALSE;
686      }
687    return !wd->editing;
688 }
689
690 static void
691 _entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj , void *event_info)
692 {
693    Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
694
695    if (!strcmp(ev->keyname, "BackSpace"))
696      elm_entry_entry_set(obj, "");
697 }
698
699 static Eina_Bool 
700 _imf_event_commit_cb(void *data , int type __UNUSED__, void *event)
701 {
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,};
706
707    if (!wd) return ECORE_CALLBACK_PASS_ON;
708    if (!elm_widget_focus_get(data)) return ECORE_CALLBACK_PASS_ON;
709
710    focus_obj = elm_widget_focused_object_get(data);
711    if (!wd->editing) 
712      {
713         elm_entry_entry_set(focus_obj, "");
714         wd->editing = EINA_TRUE;
715      }
716    if (focus_obj == wd->date[DATE_MON])
717      {
718         char *i18n_str;
719         wd->month = atoi(ev->str);
720         i18n_str = _get_i18n_string(data, ABMON_1+wd->month-1);
721         if (i18n_str)
722           {
723              elm_entry_entry_set(focus_obj, i18n_str);
724              free(i18n_str);
725           }
726      }
727    else
728      {
729         strcpy(str, elm_entry_entry_get(focus_obj));
730         str[strlen(str)] = ev->str[0];
731         elm_entry_entry_set(focus_obj, str);
732      }
733
734    if (_check_input_done(data, focus_obj, strlen(str)))
735      _entry_focus_move(data, focus_obj);
736
737    return ECORE_CALLBACK_DONE;
738 }
739
740 static void 
741 _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx __UNUSED__, int value)
742 {
743    Widget_Data *wd = elm_widget_data_get(data);
744
745    if (!wd) return;
746
747    if (wd->func)  
748      wd->func(wd->func_data, data, value);
749 }
750
751 static void
752 _date_update(Evas_Object *obj)
753 {
754    Widget_Data *wd = elm_widget_data_get(obj);
755    char str[YEAR_MAX_LENGTH+1] = {0,};
756    char *i18n_str;
757
758    if (!wd || !wd->base) return;
759
760    sprintf(str, "%d", wd->year);
761    elm_entry_entry_set(wd->date[DATE_YEAR], str);
762
763    i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
764    if (i18n_str)
765      {
766         elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
767         free(i18n_str);
768      }
769
770    sprintf(str, "%d", wd->day);
771    elm_entry_entry_set(wd->date[DATE_DAY], str);
772
773    if (!wd->time_mode) //24 mode
774      sprintf(str, "%d", wd->hour);
775    else
776      {
777         if (wd->hour >= HOUR_12H_MAXIMUM)
778           {
779              wd->pm = EINA_TRUE;
780              i18n_str = _get_i18n_string(obj, PM_STR);
781              if (i18n_str) 
782                {
783               elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
784                   free(i18n_str);
785                }
786           }
787         else
788           {
789              wd->pm = EINA_FALSE;
790              i18n_str = _get_i18n_string(obj, AM_STR);
791              if (i18n_str)
792                {
793               elm_button_label_set(wd->time[TIME_AMPM], i18n_str);
794                   free(i18n_str);
795                }
796           }
797
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);
802         else
803           sprintf(str, "%02d", wd->hour);
804      }
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);
808 }
809
810 static void 
811 _date_entry_add(Evas_Object *obj)
812 {
813    Widget_Data *wd = elm_widget_data_get(obj);
814    static Elm_Entry_Filter_Limit_Size filter_data, filter_data2;
815    int i;
816
817    if (!wd) return;     
818
819    for (i = 0; i < DATE_MAX; i++)
820      {
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]);
832      }
833    
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);
840 }
841
842 static void 
843 _time_entry_add(Evas_Object *obj)
844 {
845    Widget_Data *wd = elm_widget_data_get(obj);
846    static Elm_Entry_Filter_Limit_Size filter_data;
847    int i;
848
849    if (!wd) return;
850    
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++)
854      {
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]);
866      }
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]);
872 }
873
874 /**
875  * Add a new datefield object
876  * The date format and strings are based on current locale
877  *
878  * @param parent The parent object
879  * @return The new object or NULL if it cannot be created
880  *
881  * @ingroup Datefield
882  */
883 EAPI Evas_Object *
884 elm_datefield_add(Evas_Object *parent)
885 {
886    Evas_Object *obj;
887    Evas *e;
888    Widget_Data *wd;
889
890    e = evas_object_evas_get(parent);
891    if (!e) return NULL; 
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);
902
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);
908
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);
911
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);
915
916    wd->y_min = 1900;
917    wd->m_min = 1;
918    wd->d_min = 1;
919    wd->y_max = -1;
920    wd->m_max = 12;
921    wd->d_max = 31;
922    wd->year = wd->y_min;
923    wd->month = 1;
924    wd->day = 1;
925
926    wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
927    wd->time_mode = EINA_TRUE;
928
929    _theme_hook(obj);
930
931    return obj;
932 }
933
934 /**
935  * set layout for the datefield
936  *
937  * @param obj The datefield object
938  * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
939  *
940  * @ingroup Datefield
941  */
942 EAPI void
943 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
944 {
945    ELM_CHECK_WIDTYPE(obj, widtype);
946    Widget_Data *wd = elm_widget_data_get(obj);
947
948    if (!wd) return;
949    if (layout > ELM_DATEFIELD_LAYOUT_DATEANDTIME) return;
950
951    if (wd->layout != layout)
952      {
953         wd->layout = layout;
954         _theme_hook(obj);
955      }
956    return;
957 }
958
959 /**
960  * get layout of the datefield
961  *
962  * @param obj The datefield object
963  * @return layout of the datefield
964  *
965  * @ingroup Datefield
966  */
967 EAPI Elm_Datefield_Layout
968 elm_datefield_layout_get(const Evas_Object *obj)
969 {
970    ELM_CHECK_WIDTYPE(obj, widtype) 0;
971    Widget_Data *wd = elm_widget_data_get(obj);
972
973    if (!wd) return 0;
974
975    return wd->layout;
976 }
977
978 /**
979  * Set selected date of the datefield
980  *
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)
987  * 
988  * @ingroup Datefield
989  */
990 EAPI void
991 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
992 {
993    ELM_CHECK_WIDTYPE(obj, widtype);
994    Widget_Data *wd = elm_widget_data_get(obj);
995
996    if (!wd) return;
997
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);
1001
1002    if (hour > HOUR_24H_MAXIMUM) wd->hour = HOUR_24H_MAXIMUM;
1003    else if (hour < 0) wd->hour = 0;
1004    else wd->hour = hour;
1005
1006    if (min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
1007    else if (min < 0) wd->min = 0;
1008    else wd->min = min;
1009
1010    _date_update(obj);
1011 }
1012
1013 /**
1014  * Get selected date of the datefield
1015  *
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
1022  *
1023  * @ingroup Datefield
1024  */
1025 EAPI void
1026 elm_datefield_date_get(const Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
1027 {
1028    ELM_CHECK_WIDTYPE(obj, widtype);
1029    Widget_Data *wd = elm_widget_data_get(obj);
1030
1031    if (!wd) return;
1032
1033    if (year)
1034      *year = wd->year;
1035    if (month)
1036      *month = wd->month;
1037    if (day)
1038      *day = wd->day;
1039    if (hour)
1040      *hour = wd->hour;
1041    if (min)
1042      *min = wd->min;
1043 }
1044
1045 /**
1046  * Set upper boundary of the datefield
1047  *
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
1053  *
1054  * @ingroup Datefield
1055  */
1056 EAPI Eina_Bool
1057 elm_datefield_date_max_set(Evas_Object *obj, int year, int month, int day)
1058 {
1059    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1060    Widget_Data *wd = elm_widget_data_get(obj);
1061    int day_of_month;
1062    Eina_Bool update = EINA_FALSE;
1063
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;
1068
1069    wd->y_max = year;
1070    wd->m_max = month;
1071    wd->d_max = day;
1072
1073    if (wd->year > wd->y_max)
1074      {
1075         wd->year = wd->y_max;
1076         update = EINA_TRUE;
1077      }
1078    if (wd->year == wd->y_max && wd->month > wd->m_max)
1079      {
1080         wd->month = wd->m_max;
1081         update = EINA_TRUE;
1082      }
1083    if (wd->year == wd->y_max && wd->month == wd->m_max && wd->day > wd->d_max)
1084      {
1085         wd->day = wd->d_max;
1086         update = EINA_TRUE;
1087      }
1088
1089    if (update) _date_update(obj);
1090    return EINA_TRUE;
1091 }
1092
1093 /**
1094  * Get upper boundary of the datefield
1095  *
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
1100  *
1101  * @ingroup Datefield
1102  */
1103 EAPI void
1104 elm_datefield_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
1105 {
1106    ELM_CHECK_WIDTYPE(obj, widtype);
1107    Widget_Data *wd = elm_widget_data_get(obj);
1108
1109    if (!wd) return;
1110
1111    if (year)
1112      *year = wd->y_max;
1113    if (month)
1114      *month = wd->m_max;
1115    if (day)
1116      *day = wd->d_max;
1117 }
1118
1119 /**
1120  * Set lower boundary of the datefield
1121  *
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
1127  *
1128  * @ingroup Datepicker
1129  */
1130 EAPI Eina_Bool
1131 elm_datefield_date_min_set(Evas_Object *obj, int year, int month, int day)
1132 {
1133    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1134    Widget_Data *wd = elm_widget_data_get(obj);
1135    int day_of_month;
1136    Eina_Bool update = EINA_FALSE;
1137
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;
1142
1143    wd->y_min = year;
1144    wd->m_min = month;
1145    wd->d_min = day;
1146
1147    if (wd->year < wd->y_min)
1148      {
1149         wd->year = wd->y_min;
1150         update = EINA_TRUE;
1151      }
1152    if (wd->year == wd->y_min && wd->month < wd->m_min)
1153      {
1154         wd->month = wd->m_min;
1155         update = EINA_TRUE;
1156      }
1157    if (wd->year == wd->y_min && wd->month == wd->m_min && wd->day < wd->d_min)
1158      {
1159         wd->day = wd->d_min;
1160         update = EINA_TRUE;
1161      }
1162
1163    if (update) _date_update(obj);
1164    return EINA_TRUE;
1165 }
1166
1167 /**
1168  * Get lower boundary of the datefield
1169  *
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
1174  *
1175  * @ingroup Datefield
1176  */
1177 EAPI void
1178 elm_datefield_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
1179 {
1180    ELM_CHECK_WIDTYPE(obj, widtype);
1181    Widget_Data *wd = elm_widget_data_get(obj);
1182
1183    if (!wd) return;
1184
1185    if (year)
1186      *year = wd->y_min;
1187    if (month)
1188      *month = wd->m_min;
1189    if (day)
1190      *day = wd->d_min;
1191 }
1192
1193 /**
1194  * Set if the datefield show hours in military or am/pm mode
1195  *
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 
1198  *
1199  * @ingroup Datefield
1200  */
1201 EAPI void
1202 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
1203 {
1204    ELM_CHECK_WIDTYPE(obj, widtype);
1205    Widget_Data *wd = elm_widget_data_get(obj);
1206
1207    if (!wd) return;
1208
1209    if (wd->time_mode != mode) 
1210      {
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");
1214         _date_update(obj);
1215      }
1216 }
1217
1218 /**
1219  * get time mode of the datefield
1220  *
1221  * @param obj The datefield object
1222  * @return time mode (EINA_TRUE: 12hour mode / EINA_FALSE: 24hour mode) 
1223  *
1224  * @ingroup Datefield
1225  */
1226 EAPI Eina_Bool
1227 elm_datefield_time_mode_get(const Evas_Object *obj)
1228 {
1229    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1230    Widget_Data *wd = elm_widget_data_get(obj);
1231
1232    if (!wd) return EINA_FALSE;
1233
1234    return wd->time_mode;
1235 }
1236
1237 /**
1238  * Set date format of datefield
1239  *
1240  * @param obj The datefield object
1241  * @param fmt The date format, ex) yymmdd. Default value is mmddyy.
1242  *
1243  * @ingroup Datefield
1244  */
1245 EAPI void
1246 elm_datefield_date_format_set(Evas_Object *obj, const char *fmt)
1247 {
1248    ELM_CHECK_WIDTYPE(obj, widtype);
1249    Widget_Data *wd = elm_widget_data_get(obj);
1250    char sig[32] = "elm,state,format,";
1251    int i = 0, j;
1252
1253    if (!wd || !fmt) return;
1254
1255    j = strlen(sig);
1256    while (j < 31 )
1257      {
1258         sig[j++] = tolower(fmt[i++]);
1259      }
1260    if (j < 32) sig[j] = '\0';
1261    edje_object_signal_emit(wd->base, sig, "elm");
1262
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;
1270 }
1271
1272 /**
1273  * get date format of the datefield
1274  *
1275  * @param obj The datefield object
1276  * @return date format string. ex) yymmdd
1277  *
1278  * @ingroup Datefield
1279  */
1280 EAPI const char *
1281 elm_datefield_date_format_get(const Evas_Object *obj)
1282 {
1283    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1284    Widget_Data *wd = elm_widget_data_get(obj);
1285
1286    switch (wd->date_format)
1287      {
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;
1295      }
1296 }
1297
1298 /**
1299  * Add a callback function for input panel state
1300  *
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 
1304  *
1305  * @ingroup Datefield
1306  */
1307 EAPI void 
1308 elm_datefield_input_panel_state_callback_add(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value), void *data)
1309 {
1310    ELM_CHECK_WIDTYPE(obj, widtype);
1311    Widget_Data *wd = elm_widget_data_get(obj);
1312    int i;
1313
1314    if (!wd) return;
1315
1316    if (wd->func && (wd->func != pEventCallbackFunc))
1317      elm_datefield_input_panel_state_callback_del(obj, wd->func);
1318
1319    if (wd->func != pEventCallbackFunc)
1320      {
1321         wd->func = pEventCallbackFunc;
1322         wd->func_data = data;
1323
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);
1327
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);
1331      }
1332 }
1333
1334 /**
1335  * Delete a callback function for input panel state
1336  *
1337  * @param obj The datefield object
1338  * @param func The function to be called when the event is triggered
1339  *
1340  * @ingroup Datefield
1341  */
1342 EAPI void 
1343 elm_datefield_input_panel_state_callback_del(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value))
1344 {
1345    ELM_CHECK_WIDTYPE(obj, widtype);
1346    Widget_Data *wd = elm_widget_data_get(obj);
1347    int i;
1348
1349    if (!wd) return;
1350
1351    if (wd->func && wd->func == pEventCallbackFunc) 
1352      {
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);
1356
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);
1360
1361         wd->func = NULL;
1362         wd->func_data = NULL;
1363      }
1364 }