f1f13ef863b2379c7d5887d36d166170858ea77a
[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_MAX
27 };
28
29 enum
30 {
31   DATE_FORMAT_YYMMDD,
32   DATE_FORMAT_YYDDMM,
33   DATE_FORMAT_MMYYDD,
34   DATE_FORMAT_MMDDYY,
35   DATE_FORMAT_DDYYMM,
36   DATE_FORMAT_DDMMYY,
37   DATE_FORMAT_MAX
38 };
39
40 #define YEAR_MAX_LENGTH 4
41 #define DAY_MAX_LENGTH 2
42 #define TIME_MAX_LENGTH 2
43
44 #define MONTH_MAXIMUM 12
45 #define HOUR_24H_MAXIMUM 23
46 #define HOUR_12H_MAXIMUM 12
47 #define MIN_MAXIMUM 59
48
49 struct _Widget_Data
50 {
51    Evas_Object *base;
52    Evas_Object *date[DATE_MAX];
53    Evas_Object *time[TIME_MAX];
54    Ecore_Event_Handler *handler;
55    Ecore_Idler *idler;
56    int layout;
57
58    int year, month, day, hour, min;
59    int y_max, m_max, d_max;
60    int y_min, m_min, d_min;
61    int date_format;
62    Eina_Bool pm:1;
63    Eina_Bool time_mode:1;
64    Eina_Bool format_exists:1;
65    Eina_Bool editing:1;
66
67    void (*func)(void *data, Evas_Object *obj, int value);
68    void *func_data;
69 };
70
71 static const char *widtype = NULL;
72
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);
77
78 static void _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
79 static void _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
80 static void _entry_focused_cb(void *data, Evas_Object *obj, void *event_info);
81 static void _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info);
82 static void _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info);
83 static Eina_Bool _imf_event_commit_cb(void *data, int type, void *event);
84 static void _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value);
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
104    free(wd);
105 }
106
107 static void
108 _on_focus_hook(void *data, Evas_Object *obj)
109 {
110    Widget_Data *wd = elm_widget_data_get(obj);
111    if (!wd || !wd->base) return ;
112
113    if (elm_widget_focus_get(obj)) wd->idler = ecore_idler_add(_focus_idler_cb, obj);
114 }
115
116 static void
117 _theme_hook(Evas_Object *obj)
118 {
119    Widget_Data *wd = elm_widget_data_get(obj);
120    char sig[32] = {0,};
121    int i;
122
123    if (!wd || !wd->base) return;
124
125    if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
126      {
127         _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
128
129         for (i = 0; i < DATE_MAX; i++)
130           elm_object_style_set(wd->date[i], "datefield/hybrid");
131         for (i = 0; i < TIME_MAX; i++)
132           elm_object_style_set(wd->time[i], "datefield/hybrid");
133      }
134    else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
135      {
136         _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
137
138         for (i = 0; i < DATE_MAX; i++)
139           elm_object_style_set(wd->date[i], "datefield");
140
141         for (i = 0; i < TIME_MAX; i++)
142           evas_object_hide(wd->time[i]);
143      }
144    else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
145      {
146         _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
147
148         for (i = 0; i < TIME_MAX; i++)
149           elm_object_style_set(wd->time[i], "datefield");
150
151         for (i = 0; i < DATE_MAX; i++)
152           evas_object_hide(wd->date[i]);
153      }
154
155    if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
156      {
157         edje_object_part_swallow(wd->base, "elm.swallow.date.year", wd->date[DATE_YEAR]);
158         edje_object_part_swallow(wd->base, "elm.swallow.date.month", wd->date[DATE_MON]);
159         edje_object_part_swallow(wd->base, "elm.swallow.date.day", wd->date[DATE_DAY]);
160         edje_object_part_text_set(wd->base, "elm.text.date.comma", ",");
161      }
162
163    if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
164      {
165         edje_object_part_swallow(wd->base, "elm.swallow.time.hour", wd->time[TIME_HOUR]);
166         edje_object_part_swallow(wd->base, "elm.swallow.time.min", wd->time[TIME_MIN]);
167         edje_object_part_text_set(wd->base, "elm.text.colon", ":");
168      }
169
170    edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
171
172    //set date format
173    if (wd->format_exists)
174      sprintf(sig, "elm,state,format,%s", elm_datefield_date_format_get(obj));
175    else
176      {
177         char *str = _get_i18n_string(obj, D_FMT);
178         if (str) 
179           {
180              if (!strcmp(str, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
181              else if (!strcmp(str, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
182              else if (!strcmp(str, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
183              else if (!strcmp(str, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
184              else if (!strcmp(str, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
185              else if (!strcmp(str, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
186              sprintf(sig, "elm,state,format,%s",str);
187              free(str);
188           }
189      }
190    edje_object_signal_emit(wd->base, sig, "elm");
191
192    _date_update(obj);
193    _sizing_eval(obj);
194 }
195
196 static void
197 _sizing_eval(Evas_Object *obj)
198 {
199    Widget_Data *wd = elm_widget_data_get(obj);
200    Evas_Coord minw = -1, minh = -1;
201
202    edje_object_size_min_calc(wd->base, &minw, &minh);
203    evas_object_size_hint_min_set(obj, minw, minh);
204    evas_object_size_hint_max_set(obj, -1, -1);
205 }
206
207 static void
208 _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
209 {
210    Widget_Data *wd = elm_widget_data_get(data);
211    char *str;
212
213    if (!wd || !wd->base) return ;
214
215    wd->pm = !wd->pm; 
216    if (wd->pm)
217      {
218         str = _get_i18n_string(data, PM_STR);
219         if (str) 
220           {
221              edje_object_part_text_set(wd->base, "elm.text.ampm", str);
222              free(str);
223           }
224         wd->hour += HOUR_12H_MAXIMUM;
225      }
226    else
227      {
228         str = _get_i18n_string(data, AM_STR);
229         if (str)
230           {
231              edje_object_part_text_set(wd->base, "elm.text.ampm", str);
232              free(str);
233           }
234         wd->hour -= HOUR_12H_MAXIMUM;
235      }
236    evas_object_smart_callback_call(data, "changed", NULL);
237 }
238
239 static void
240 _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
241 {
242    Widget_Data *wd = elm_widget_data_get(data);
243    if (!wd) return;
244
245    if (!strcmp(source, "elm.rect.date.year.over"))
246      elm_object_focus(wd->date[DATE_YEAR]);
247    else if (!strcmp(source, "elm.rect.date.month.over"))
248      elm_object_focus(wd->date[DATE_MON]);
249    else if (!strcmp(source, "elm.rect.date.day.over"))
250      elm_object_focus(wd->date[DATE_DAY]);
251    else if (!strcmp(source, "elm.rect.time.hour.over"))
252      elm_object_focus(wd->time[TIME_HOUR]);
253    else if (!strcmp(source, "elm.rect.time.min.over"))
254      elm_object_focus(wd->time[TIME_MIN]);
255    else if (!strcmp(source, "elm.rect.date.left.pad"))
256      {
257         switch (wd->date_format)
258           {
259            case DATE_FORMAT_YYDDMM:
260            case DATE_FORMAT_YYMMDD:
261              elm_object_focus(wd->date[DATE_YEAR]);
262              break;
263            case DATE_FORMAT_MMDDYY:
264            case DATE_FORMAT_MMYYDD:
265              elm_object_focus(wd->date[DATE_MON]);
266              break;
267            case DATE_FORMAT_DDMMYY:
268            case DATE_FORMAT_DDYYMM:
269              elm_object_focus(wd->date[DATE_DAY]);
270           }
271      }
272    else if (!strcmp(source, "elm.rect.date.right.pad"))
273      {
274         switch (wd->date_format)
275           {
276            case DATE_FORMAT_MMDDYY:
277            case DATE_FORMAT_DDMMYY:
278              elm_object_focus(wd->date[DATE_YEAR]);
279              break;
280            case DATE_FORMAT_DDYYMM:
281            case DATE_FORMAT_YYDDMM:
282              elm_object_focus(wd->date[DATE_MON]);
283              break;
284            case DATE_FORMAT_YYMMDD:
285            case DATE_FORMAT_MMYYDD:
286              elm_object_focus(wd->date[DATE_DAY]);
287           }
288      }
289 }
290
291 static Eina_Bool 
292 _focus_idler_cb(void *obj)
293 {
294    Widget_Data *wd = elm_widget_data_get(obj);
295    Evas_Object *focus_obj;
296
297    focus_obj = elm_widget_focused_object_get(obj);
298    if (focus_obj == obj)
299      {
300         if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
301           elm_object_focus(wd->time[TIME_HOUR]);
302
303         else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
304           {
305              switch (wd->date_format)
306                {
307                 case DATE_FORMAT_YYDDMM:
308                 case DATE_FORMAT_YYMMDD:
309                   elm_object_focus(wd->date[DATE_YEAR]);
310                   break;
311                 case DATE_FORMAT_MMDDYY:
312                 case DATE_FORMAT_MMYYDD:
313                   elm_object_focus(wd->date[DATE_MON]);
314                   break;
315                 case DATE_FORMAT_DDMMYY:
316                 case DATE_FORMAT_DDYYMM:
317                   elm_object_focus(wd->date[DATE_DAY]);
318                }
319           }
320      }
321    wd->idler = NULL;
322    return EINA_FALSE;
323 }
324
325 static void
326 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
327 {
328    Widget_Data *wd = elm_widget_data_get(data);
329    if (!wd || !wd->base) return;
330
331    if (wd->idler) 
332      {
333         ecore_idler_del(wd->idler);
334         wd->idler = NULL;
335      }
336
337    if (obj == wd->date[DATE_YEAR])
338      edje_object_signal_emit(wd->base, "elm,state,year,focus,in", "elm");
339    else if (obj == wd->date[DATE_MON])
340      edje_object_signal_emit(wd->base, "elm,state,month,focus,in", "elm");
341    else if (obj == wd->date[DATE_DAY])
342      edje_object_signal_emit(wd->base, "elm,state,day,focus,in", "elm");
343    else if (obj == wd->time[TIME_HOUR])
344      edje_object_signal_emit(wd->base, "elm,state,hour,focus,in", "elm");
345    else if (obj == wd->time[TIME_MIN])
346      edje_object_signal_emit(wd->base, "elm,state,min,focus,in", "elm");
347 }
348
349 static void
350 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
351 {
352    Widget_Data *wd = elm_widget_data_get(data);
353    char str[YEAR_MAX_LENGTH+1] = {0,};
354    char *i18n_str;
355    int num = 0;
356
357    if (!wd || !wd->base) return;
358    wd->editing = FALSE;
359
360    if (obj == wd->date[DATE_YEAR])
361      {
362         if (strlen(elm_entry_entry_get(wd->date[DATE_YEAR])))
363           wd->year = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
364         wd->year = _check_date_boundary(data, wd->year, DATE_YEAR);
365         sprintf(str, "%d", wd->year);
366         elm_entry_entry_set(wd->date[DATE_YEAR], str);
367         //check month boundary
368         if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
369           {
370              wd->month = num;
371              i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
372              if (i18n_str)
373                {
374                   elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
375                   free(i18n_str);
376                }
377           }
378         //check day boundary
379         if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
380           {
381              wd->day = num;
382              sprintf(str, "%d", wd->day);
383              elm_entry_entry_set(wd->date[DATE_DAY], str);
384           }
385         edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
386      }
387    else if (obj == wd->date[DATE_MON])
388      {
389         if (wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
390           {
391              wd->month = num;
392              i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
393              if (i18n_str)
394                {
395                   elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
396                   free(i18n_str);
397                }  
398           }
399         //check day boundary
400         if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
401           {
402              wd->day = num;
403              sprintf(str, "%d", wd->day);               
404              elm_entry_entry_set(wd->date[DATE_DAY], str);
405           }
406         edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
407      }
408    else if (obj == wd->date[DATE_DAY])
409      {
410         if (strlen(elm_entry_entry_get(wd->date[DATE_DAY])))
411           wd->day = atoi(elm_entry_entry_get(wd->date[DATE_DAY]));
412         wd->day = _check_date_boundary(data, wd->day, DATE_DAY);
413         sprintf(str, "%d", wd->day);
414         elm_entry_entry_set(wd->date[DATE_DAY], str);
415         edje_object_signal_emit(wd->base, "elm,state,day,focus,out", "elm");
416      }
417    else if (obj == wd->time[TIME_HOUR])
418      {
419         if (strlen(elm_entry_entry_get(wd->time[TIME_HOUR])))
420           num = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
421         else num = wd->hour;
422
423         if (!wd->time_mode) // 24 mode
424           {
425              if (num > HOUR_24H_MAXIMUM) num = HOUR_24H_MAXIMUM;
426              wd->hour = num;
427           }
428         else // 12 mode
429           {
430              if (num > HOUR_24H_MAXIMUM || num == 0)
431                {
432                   num = HOUR_12H_MAXIMUM;
433                   wd->pm = EINA_FALSE;
434                }
435              else if (num > HOUR_12H_MAXIMUM)
436                {
437                   num -= HOUR_12H_MAXIMUM;
438                   wd->pm = EINA_TRUE;
439                }
440              wd->hour = (wd->pm == EINA_TRUE)? num + HOUR_12H_MAXIMUM : num;
441              if ((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
442              if (wd->pm) 
443                {
444                   i18n_str = _get_i18n_string(data, PM_STR);
445                   if (i18n_str)
446                     {
447                        edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
448                        free(i18n_str);
449                     }
450                }
451              else 
452                {
453                   i18n_str = _get_i18n_string(data, AM_STR);
454                   if (i18n_str)
455                     {
456                        edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
457                        free(i18n_str);
458                     }
459                }
460           }
461         sprintf(str, "%02d", num);
462         elm_entry_entry_set(wd->time[TIME_HOUR], str);
463         edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
464      }
465    else if (obj == wd->time[TIME_MIN])
466      {
467         if (strlen(elm_entry_entry_get(wd->time[TIME_MIN]))) 
468           wd->min = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
469         if (wd->min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
470
471         sprintf(str, "%02d", wd->min);
472         elm_entry_entry_set(wd->time[TIME_MIN], str);
473         edje_object_signal_emit(wd->base, "elm,state,min,focus,out", "elm");
474      }
475    evas_object_smart_callback_call(data, "changed", NULL);
476 }
477
478 static void 
479 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
480 {
481    Widget_Data *wd = elm_widget_data_get(obj);
482    if (!wd) return;
483
484    if (focus_obj == wd->date[DATE_YEAR])
485      {
486         switch (wd->date_format)
487           {
488            case DATE_FORMAT_DDMMYY:
489            case DATE_FORMAT_MMDDYY:
490              {
491                  if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
492                    elm_object_focus(wd->time[TIME_HOUR]);
493                  else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
494                    elm_object_unfocus(wd->date[DATE_YEAR]);
495              }
496              break;
497            case DATE_FORMAT_DDYYMM:
498            case DATE_FORMAT_YYMMDD:
499              elm_object_focus(wd->date[DATE_MON]);
500              break;
501            case DATE_FORMAT_MMYYDD:
502            case DATE_FORMAT_YYDDMM:
503              elm_object_focus(wd->date[DATE_DAY]);
504           }
505      }
506    else if (focus_obj == wd->date[DATE_MON])
507      {
508         switch (wd->date_format)
509           {
510            case DATE_FORMAT_DDYYMM:
511            case DATE_FORMAT_YYDDMM:
512              {
513                 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
514                   elm_object_focus(wd->time[TIME_HOUR]);
515                 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
516                   elm_object_unfocus(wd->date[DATE_MON]);
517              }
518              break;
519            case DATE_FORMAT_DDMMYY:
520            case DATE_FORMAT_MMYYDD:
521              elm_object_focus(wd->date[DATE_YEAR]);
522              break;
523            case DATE_FORMAT_MMDDYY:
524            case DATE_FORMAT_YYMMDD:
525              elm_object_focus(wd->date[DATE_DAY]);
526           }
527      }
528    else if (focus_obj == wd->date[DATE_DAY])
529      {
530         switch (wd->date_format)
531           {
532            case DATE_FORMAT_YYMMDD:
533            case DATE_FORMAT_MMYYDD:
534              {
535                 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
536                   elm_object_focus(wd->time[TIME_HOUR]);
537                 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
538                   elm_object_unfocus(wd->date[DATE_DAY]);
539              }
540              break;
541            case DATE_FORMAT_DDYYMM:
542            case DATE_FORMAT_MMDDYY:
543              elm_object_focus(wd->date[DATE_YEAR]);
544              break;
545            case DATE_FORMAT_DDMMYY:
546            case DATE_FORMAT_YYDDMM:
547              elm_object_focus(wd->date[DATE_MON]);
548           }
549      }
550    else if (focus_obj == wd->time[TIME_HOUR])
551      elm_object_focus(wd->time[TIME_MIN]);
552    else if (focus_obj == wd->time[TIME_MIN])
553      elm_object_unfocus(wd->time[TIME_MIN]);
554 }
555
556 static int
557 _check_date_boundary(Evas_Object *obj, int num, int flag)
558 {
559    Widget_Data *wd = elm_widget_data_get(obj);
560    if (flag == DATE_YEAR)
561      {
562         if (num > wd->y_max) num = wd->y_max;
563         else if (num < wd->y_min) num = wd->y_min;
564         return num;
565      }
566
567    else if (flag == DATE_MON)
568      {
569         if (wd->year == wd->y_max && num > wd->m_max) num = wd->m_max;
570         else if (wd->year == wd->y_min && num < wd->m_min) num = wd->m_min;
571         else if (num > MONTH_MAXIMUM) num = MONTH_MAXIMUM;
572         else if (num <= 0) num = 1;
573         return num;
574      }
575
576    else if (flag == DATE_DAY)
577      {
578         int day_of_month = _maximum_day_get(wd->year, wd->month);
579         if (wd->year == wd->y_max && wd->month == wd->m_max && num > wd->d_max) num = wd->d_max;
580         else if (wd->year == wd->y_min && wd->month == wd->m_min && num < wd->d_min) num = wd->d_min;
581         else if (num > day_of_month) num = day_of_month;
582         else if (num <= 0) num = 1;
583         return num;
584      }
585    return num;
586 }
587
588 static char*
589 _get_i18n_string(Evas_Object *obj, nl_item item)
590 {
591    Widget_Data *wd = elm_widget_data_get(obj);
592    const char *fmt;
593    char *str = NULL;
594    int i = 0, j = 0;
595
596    if (!wd) return NULL;
597
598    fmt = nl_langinfo(item);
599    if (!fmt) return NULL;
600
601    switch (item)
602      {
603       case D_FMT:
604          str = calloc(7, sizeof(char));
605          while (fmt[i]) 
606            {
607               if (fmt[i] == '%' && fmt[i+1]) 
608                 {
609                    i++;
610                    switch (fmt[i]) 
611                      {
612                       case 'Y': case 'M': case 'D': case 'y': case 'm': case 'd':
613                          str[j++] = tolower(fmt[i]);
614                          str[j++] = tolower(fmt[i]);
615                          break;
616                      }
617                 }
618               i++;
619            }
620          return str;
621       case AM_STR: 
622       case PM_STR:
623          if (strlen(fmt) > 0)
624            {
625               str = calloc(strlen(fmt)+1, sizeof(char));
626               strcpy(str, fmt);
627            }
628          else
629            {
630               str = calloc(3, sizeof(char));
631               if (item == AM_STR) strcpy(str, "AM");
632               else if (item == PM_STR) strcpy(str, "PM");
633            }
634          return str;
635       case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: case ABMON_5: case ABMON_6:
636       case ABMON_7: case ABMON_8: case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
637          str = calloc(strlen(fmt)+1, sizeof(char));
638          while (fmt[i])
639            {
640               str[j++] = fmt[i];
641               if (fmt[i] >= '1' && fmt[i] <= '9')
642                 {
643                    if (fmt[i+1] >= '1' && fmt[i+1] <= '9')
644                      str[j] = fmt[i+1];
645                    break;
646                 }
647               i++;
648            }
649          return str;     
650      }
651    return NULL;
652 }
653
654 static int
655 _maximum_day_get(int year, int month)
656 {
657    int day_of_month = 0;
658    if (year == 0 || month == 0) return 0;
659
660    switch (month)
661      {
662       case 4:
663       case 6:
664       case 9:
665       case 11:
666         day_of_month = 30;
667         break;
668       case 2:
669         {
670            if ((!(year % 4) && (year % 100)) || !(year % 400))
671              day_of_month = 29;
672            else
673              day_of_month = 28;
674         }
675         break;
676       default:
677         day_of_month = 31;
678         break;
679      }
680
681    return day_of_month;
682 }
683
684 static Eina_Bool 
685 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
686 {
687    Widget_Data *wd = elm_widget_data_get(obj);
688
689    if (!wd) return EINA_FALSE;
690
691    if (focus_obj == wd->date[DATE_YEAR] && strlen == YEAR_MAX_LENGTH)
692      wd->editing = EINA_FALSE;
693    else if (focus_obj == wd->date[DATE_MON])
694      wd->editing = EINA_FALSE;
695    else if (focus_obj == wd->date[DATE_DAY])
696      {
697         if (strlen == DAY_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 3)
698           wd->editing = EINA_FALSE;
699      }
700    else if (focus_obj == wd->time[TIME_HOUR])
701      {
702         if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
703           wd->editing = EINA_FALSE;
704      }
705    else if (focus_obj == wd->time[TIME_MIN])
706      {
707         if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 5) 
708           wd->editing = EINA_FALSE;
709      }
710    return !wd->editing;
711 }
712
713 static void
714 _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info)
715 {
716    Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
717
718    if (!strcmp(ev->keyname, "BackSpace"))
719      elm_entry_entry_set(obj, "");
720 }
721
722 static Eina_Bool 
723 _imf_event_commit_cb(void *data, int type, void *event)
724 {
725    Widget_Data *wd = elm_widget_data_get(data);
726    Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event;
727    Evas_Object *focus_obj;
728    char str[YEAR_MAX_LENGTH+1] = {0,};
729
730    if (!wd) return ECORE_CALLBACK_PASS_ON;
731    if (!elm_widget_focus_get(data)) return ECORE_CALLBACK_PASS_ON;
732
733    focus_obj = elm_widget_focused_object_get(data);
734    if (!wd->editing) 
735      {
736         elm_entry_entry_set(focus_obj, "");
737         wd->editing = EINA_TRUE;
738      }
739    if (focus_obj == wd->date[DATE_MON])
740      {
741         char *i18n_str;
742         wd->month = atoi(ev->str);
743         i18n_str = _get_i18n_string(data, ABMON_1+wd->month-1);
744         if (i18n_str)
745           {
746              elm_entry_entry_set(focus_obj, i18n_str);
747              free(i18n_str);
748           }
749      }
750    else
751      {
752         strcpy(str, elm_entry_entry_get(focus_obj));
753         str[strlen(str)] = ev->str[0];
754         elm_entry_entry_set(focus_obj, str);
755      }
756
757    if (_check_input_done(data, focus_obj, strlen(str)))
758      _entry_focus_move(data, focus_obj);
759
760    return ECORE_CALLBACK_DONE;
761 }
762
763 static void 
764 _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value)
765 {
766    Widget_Data *wd = elm_widget_data_get(data);
767
768    if (!wd) return;
769
770    if (wd->func)  
771      wd->func(wd->func_data, data, value);
772 }
773
774 static void
775 _date_update(Evas_Object *obj)
776 {
777    Widget_Data *wd = elm_widget_data_get(obj);
778    char str[YEAR_MAX_LENGTH+1] = {0,};
779    char *i18n_str;
780
781    if (!wd || !wd->base) return;
782
783    sprintf(str, "%d", wd->year);
784    elm_entry_entry_set(wd->date[DATE_YEAR], str);
785
786    i18n_str = _get_i18n_string(obj, ABMON_1+wd->month-1);
787    if (i18n_str)
788      {
789         elm_entry_entry_set(wd->date[DATE_MON], i18n_str);
790         free(i18n_str);
791      }
792
793    sprintf(str, "%d", wd->day);
794    elm_entry_entry_set(wd->date[DATE_DAY], str);
795
796    if (!wd->time_mode) //24 mode
797      sprintf(str, "%d", wd->hour);
798    else
799      {
800         if (wd->hour >= HOUR_12H_MAXIMUM)
801           {
802              wd->pm = EINA_TRUE;
803              i18n_str = _get_i18n_string(obj, PM_STR);
804              if (i18n_str) 
805                {
806                   edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);
807                   free(i18n_str);
808                }
809           }
810         else
811           {
812              wd->pm = EINA_FALSE;
813              i18n_str = _get_i18n_string(obj, AM_STR);
814              if (i18n_str)
815                {
816                   edje_object_part_text_set(wd->base, "elm.text.ampm", i18n_str);               
817                   free(i18n_str);
818                }
819           }
820
821         if (wd->hour > HOUR_12H_MAXIMUM)
822           sprintf(str, "%02d", wd->hour - HOUR_12H_MAXIMUM);
823         else if (wd->hour == 0)
824           sprintf(str, "%02d", HOUR_12H_MAXIMUM);
825         else
826           sprintf(str, "%02d", wd->hour);
827      }
828    elm_entry_entry_set(wd->time[TIME_HOUR], str);
829    sprintf(str, "%02d", wd->min);
830    elm_entry_entry_set(wd->time[TIME_MIN], str);
831 }
832
833 static void 
834 _date_entry_add(Evas_Object *obj)
835 {
836    Widget_Data *wd = elm_widget_data_get(obj);
837    static Elm_Entry_Filter_Limit_Size filter_data, filter_data2;
838    int i;
839
840    if (!wd) return;     
841
842    for (i = 0; i < DATE_MAX; i++)
843      {
844         wd->date[i] = elm_entry_add(obj);
845         elm_entry_single_line_set(wd->date[i], EINA_TRUE);
846         elm_entry_context_menu_disabled_set(wd->date[i], EINA_TRUE);
847         if (i == DATE_MON) elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_MONTH);
848         else elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
849         evas_object_size_hint_weight_set(wd->date[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
850         evas_object_size_hint_align_set(wd->date[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
851         evas_object_smart_callback_add(wd->date[i], "focused", _entry_focused_cb, obj);
852         evas_object_smart_callback_add(wd->date[i], "unfocused", _entry_unfocused_cb, obj);
853         evas_object_event_callback_add(wd->date[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
854         elm_widget_sub_object_add(obj, wd->date[i]);
855      }
856    
857    filter_data.max_char_count = 0;
858    filter_data.max_byte_count = YEAR_MAX_LENGTH;
859    elm_entry_text_filter_append(wd->date[DATE_YEAR], elm_entry_filter_limit_size, &filter_data);
860    filter_data2.max_char_count = 0;
861    filter_data2.max_byte_count = DAY_MAX_LENGTH;
862    elm_entry_text_filter_append(wd->date[DATE_YEAR], elm_entry_filter_limit_size, &filter_data2);
863 }
864
865 static void 
866 _time_entry_add(Evas_Object *obj)
867 {
868    Widget_Data *wd = elm_widget_data_get(obj);
869    static Elm_Entry_Filter_Limit_Size filter_data;
870    int i;
871
872    if (!wd) return;
873    
874    filter_data.max_char_count = 0;
875    filter_data.max_byte_count = TIME_MAX_LENGTH;
876    for (i = 0; i < TIME_MAX; i++)
877      {
878         wd->time[i] = elm_entry_add(obj);
879         elm_entry_single_line_set(wd->time[i], EINA_TRUE);
880         elm_entry_context_menu_disabled_set(wd->time[i], EINA_TRUE);
881         elm_entry_input_panel_layout_set(wd->time[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
882         elm_entry_text_filter_append(wd->time[i], elm_entry_filter_limit_size, &filter_data);
883         evas_object_size_hint_weight_set(wd->time[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
884         evas_object_size_hint_align_set(wd->time[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
885         evas_object_smart_callback_add(wd->time[i], "focused", _entry_focused_cb, obj);
886         evas_object_smart_callback_add(wd->time[i], "unfocused", _entry_unfocused_cb, obj);
887         evas_object_event_callback_add(wd->time[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
888         elm_widget_sub_object_add(obj, wd->time[i]);
889      }
890 }
891
892 /**
893  * Add a new datefield object
894  * The date format and strings are based on current locale
895  *
896  * @param parent The parent object
897  * @return The new object or NULL if it cannot be created
898  *
899  * @ingroup Datefield
900  */
901 EAPI Evas_Object *
902 elm_datefield_add(Evas_Object *parent)
903 {
904    Evas_Object *obj;
905    Evas *e;
906    Widget_Data *wd;
907
908    e = evas_object_evas_get(parent);
909    if (!e) return NULL; 
910    wd = ELM_NEW(Widget_Data);
911    obj = elm_widget_add(e); 
912    ELM_SET_WIDTYPE(widtype, "datefield");
913    elm_widget_type_set(obj, "datefield");
914    elm_widget_sub_object_add(parent, obj);
915    elm_widget_data_set(obj, wd);
916    elm_widget_del_hook_set(obj, _del_hook);
917    elm_widget_theme_hook_set(obj, _theme_hook);
918    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
919    elm_widget_can_focus_set(obj, EINA_TRUE);
920
921    wd->base = edje_object_add(e);
922    elm_widget_resize_object_set(obj, wd->base);
923    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.left.pad", _signal_rect_mouse_down, obj);
924    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.year.over", _signal_rect_mouse_down, obj);
925    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.month.over", _signal_rect_mouse_down, obj);
926    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.day.over", _signal_rect_mouse_down, obj);
927    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.right.pad", _signal_rect_mouse_down, obj);
928
929    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.hour.over", _signal_rect_mouse_down, obj);
930    edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.min.over", _signal_rect_mouse_down, obj);
931    edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "elm.rect.time.ampm.over", _signal_ampm_clicked, obj);
932
933    wd->handler =  ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, obj);
934    _date_entry_add(obj);
935    _time_entry_add(obj);
936
937    wd->y_min = 1900;
938    wd->m_min = 1;
939    wd->d_min = 1;
940    wd->y_max = 2099;
941    wd->m_max = 12;
942    wd->d_max = 31;
943    wd->year = wd->y_min;
944    wd->month = 1;
945    wd->day = 1;
946
947    wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
948    wd->time_mode = EINA_TRUE;
949
950    _theme_hook(obj);
951
952    return obj;
953 }
954
955 /**
956  * set layout for the datefield
957  *
958  * @param obj The datefield object
959  * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
960  *
961  * @ingroup Datefield
962  */
963 EAPI void
964 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
965 {
966    ELM_CHECK_WIDTYPE(obj, widtype);
967    Widget_Data *wd = elm_widget_data_get(obj);
968
969    if (!wd) return;
970    if (layout < ELM_DATEFIELD_LAYOUT_TIME ||layout > ELM_DATEFIELD_LAYOUT_DATEANDTIME) return;
971
972    if (wd->layout != layout)
973      {
974         wd->layout = layout;
975         _theme_hook(obj);
976      }
977    return;
978 }
979
980 /**
981  * get layout of the datefield
982  *
983  * @param obj The datefield object
984  * @return layout of the datefield
985  *
986  * @ingroup Datefield
987  */
988 EAPI Elm_Datefield_Layout
989 elm_datefield_layout_get(const Evas_Object *obj)
990 {
991    ELM_CHECK_WIDTYPE(obj, widtype) 0;
992    Widget_Data *wd = elm_widget_data_get(obj);
993
994    if (!wd) return 0;
995
996    return wd->layout;
997 }
998
999 /**
1000  * Set selected date of the datefield
1001  *
1002  * @param obj The datefield object
1003  * @param year The year to set
1004  * @param month The month to set
1005  * @param day The day to set
1006  * @param hour The hours to set (24hour mode - 0~23)
1007  * @param min The minutes to set (0~59)
1008  * 
1009  * @ingroup Datefield
1010  */
1011 EAPI void
1012 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
1013 {
1014    ELM_CHECK_WIDTYPE(obj, widtype);
1015    Widget_Data *wd = elm_widget_data_get(obj);
1016
1017    if (!wd) return;
1018
1019    wd->year = _check_date_boundary(obj, year, DATE_YEAR);
1020    wd->month = _check_date_boundary(obj, month, DATE_MON);
1021    wd->day = _check_date_boundary(obj, day, DATE_DAY);
1022
1023    if (hour > HOUR_24H_MAXIMUM) wd->hour = HOUR_24H_MAXIMUM;
1024    else if (hour < 0) wd->hour = 0;
1025    else wd->hour = hour;
1026
1027    if (min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
1028    else if (min < 0) wd->min = 0;
1029    else wd->min = min;
1030
1031    _date_update(obj);
1032 }
1033
1034 /**
1035  * Get selected date of the datefield
1036  *
1037  * @param obj The datefield object
1038  * @param year The pointer to the variable get the selected year
1039  * @param month The pointer to the variable get the selected month
1040  * @param day The pointer to the variable get the selected day
1041  * @param hour The pointer to the variable get the selected hour (24hour mode)
1042  * @param hour The pointer to the variable get the selected min
1043  *
1044  * @ingroup Datefield
1045  */
1046 EAPI void
1047 elm_datefield_date_get(const Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
1048 {
1049    ELM_CHECK_WIDTYPE(obj, widtype);
1050    Widget_Data *wd = elm_widget_data_get(obj);
1051
1052    if (!wd) return;
1053
1054    if (year)
1055      *year = wd->year;
1056    if (month)
1057      *month = wd->month;
1058    if (day)
1059      *day = wd->day;
1060    if (hour)
1061      *hour = wd->hour;
1062    if (min)
1063      *min = wd->min;
1064 }
1065
1066 /**
1067  * Set upper boundary of the datefield
1068  *
1069  * @param obj The datefield object
1070  * @param year The year to set
1071  * @param month The month to set
1072  * @param day The day to set
1073  * @return TRUE/FALSE
1074  *
1075  * @ingroup Datefield
1076  */
1077 EAPI Eina_Bool
1078 elm_datefield_date_max_set(Evas_Object *obj, int year, int month, int day)
1079 {
1080    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1081    Widget_Data *wd = elm_widget_data_get(obj);
1082    int day_of_month;
1083    Eina_Bool update = EINA_FALSE;
1084
1085    if (!wd) return EINA_FALSE;
1086    if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1087    day_of_month = _maximum_day_get(year, month);
1088    if (day < 1 || day > day_of_month) return EINA_FALSE;
1089
1090    wd->y_max = year;
1091    wd->m_max = month;
1092    wd->d_max = day;
1093
1094    if (wd->year > wd->y_max)
1095      {
1096         wd->year = wd->y_max;
1097         update = EINA_TRUE;
1098      }
1099    if (wd->year == wd->y_max && wd->month > wd->m_max)
1100      {
1101         wd->month = wd->m_max;
1102         update = EINA_TRUE;
1103      }
1104    if (wd->year == wd->y_max && wd->month == wd->m_max && wd->day > wd->d_max)
1105      {
1106         wd->day = wd->d_max;
1107         update = EINA_TRUE;
1108      }
1109
1110    if (update) _date_update(obj);
1111    return EINA_TRUE;
1112 }
1113
1114 /**
1115  * Get upper boundary of the datefield
1116  *
1117  * @param obj The datefield object
1118  * @param year The pointer to the variable get the maximum year
1119  * @param month The pointer to the variable get the maximum month
1120  * @param day The pointer to the variable get the maximum day
1121  *
1122  * @ingroup Datefield
1123  */
1124 EAPI void
1125 elm_datefield_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
1126 {
1127    ELM_CHECK_WIDTYPE(obj, widtype);
1128    Widget_Data *wd = elm_widget_data_get(obj);
1129
1130    if (!wd) return;
1131
1132    if (year)
1133      *year = wd->y_max;
1134    if (month)
1135      *month = wd->m_max;
1136    if (day)
1137      *day = wd->d_max;
1138 }
1139
1140 /**
1141  * Set lower boundary of the datefield
1142  *
1143  * @param obj The datefield object
1144  * @param year The year to set
1145  * @param month The month to set
1146  * @param day The day to set
1147  * @return TRUE/FALSE
1148  *
1149  * @ingroup Datepicker
1150  */
1151 EAPI Eina_Bool
1152 elm_datefield_date_min_set(Evas_Object *obj, int year, int month, int day)
1153 {
1154    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1155    Widget_Data *wd = elm_widget_data_get(obj);
1156    int day_of_month;
1157    Eina_Bool update = EINA_FALSE;
1158
1159    if (!wd) return EINA_FALSE;
1160    if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1161    day_of_month = _maximum_day_get(year, month);
1162    if (day < 1 || day > day_of_month) return EINA_FALSE;
1163
1164    wd->y_min = year;
1165    wd->m_min = month;
1166    wd->d_min = day;
1167
1168    if (wd->year < wd->y_min)
1169      {
1170         wd->year = wd->y_min;
1171         update = EINA_TRUE;
1172      }
1173    if (wd->year == wd->y_min && wd->month < wd->m_min)
1174      {
1175         wd->month = wd->m_min;
1176         update = EINA_TRUE;
1177      }
1178    if (wd->year == wd->y_min && wd->month == wd->m_min && wd->day < wd->d_min)
1179      {
1180         wd->day = wd->d_min;
1181         update = EINA_TRUE;
1182      }
1183
1184    if (update) _date_update(obj);
1185    return EINA_TRUE;
1186 }
1187
1188 /**
1189  * Get lower boundary of the datefield
1190  *
1191  * @param obj The datefield object
1192  * @param year The pointer to the variable get the maximum year
1193  * @param month The pointer to the variable get the maximum month
1194  * @param day The pointer to the variable get the maximum day
1195  *
1196  * @ingroup Datefield
1197  */
1198 EAPI void
1199 elm_datefield_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
1200 {
1201    ELM_CHECK_WIDTYPE(obj, widtype);
1202    Widget_Data *wd = elm_widget_data_get(obj);
1203
1204    if (!wd) return;
1205
1206    if (year)
1207      *year = wd->y_min;
1208    if (month)
1209      *month = wd->m_min;
1210    if (day)
1211      *day = wd->d_min;
1212 }
1213
1214 /**
1215  * Set if the datefield show hours in military or am/pm mode
1216  *
1217  * @param obj The datefield object
1218  * @param mode option for the hours mode. If true, it is shown as 12h mode, if false, it is shown as 24h mode. Default value is true 
1219  *
1220  * @ingroup Datefield
1221  */
1222 EAPI void
1223 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
1224 {
1225    ELM_CHECK_WIDTYPE(obj, widtype);
1226    Widget_Data *wd = elm_widget_data_get(obj);
1227
1228    if (!wd) return;
1229
1230    if (wd->time_mode != mode) 
1231      {
1232         wd->time_mode = mode;
1233         if (!wd->time_mode) edje_object_signal_emit(wd->base, "elm,state,mode,24h", "elm");
1234         else edje_object_signal_emit(wd->base, "elm,state,mode,12h", "elm");
1235         _date_update(obj);
1236      }
1237 }
1238
1239 /**
1240  * get time mode of the datefield
1241  *
1242  * @param obj The datefield object
1243  * @return time mode (EINA_TRUE: 12hour mode / EINA_FALSE: 24hour mode) 
1244  *
1245  * @ingroup Datefield
1246  */
1247 EAPI Eina_Bool
1248 elm_datefield_time_mode_get(const Evas_Object *obj)
1249 {
1250    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1251    Widget_Data *wd = elm_widget_data_get(obj);
1252
1253    if (!wd) return EINA_FALSE;
1254
1255    return wd->time_mode;
1256 }
1257
1258 /**
1259  * Set date format of datefield
1260  *
1261  * @param obj The datefield object
1262  * @param fmt The date format, ex) yymmdd. Default value is mmddyy.
1263  *
1264  * @ingroup Datefield
1265  */
1266 EAPI void
1267 elm_datefield_date_format_set(Evas_Object *obj, const char *fmt)
1268 {
1269    ELM_CHECK_WIDTYPE(obj, widtype);
1270    Widget_Data *wd = elm_widget_data_get(obj);
1271    char sig[32] = "elm,state,format,";
1272    int i = 0, j;
1273
1274    if (!wd || !fmt) return;
1275
1276    j = strlen(sig);
1277    while (j < 32)
1278      {
1279         sig[j++] = tolower(fmt[i++]);
1280      }
1281    sig[j] = '\0';
1282    edje_object_signal_emit(wd->base, sig, "elm");
1283
1284    if (strstr(sig, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
1285    else if (strstr(sig, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
1286    else if (strstr(sig, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
1287    else if (strstr(sig, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
1288    else if (strstr(sig, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
1289    else if (strstr(sig, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
1290    wd->format_exists = EINA_TRUE;
1291 }
1292
1293 /**
1294  * get date format of the datefield
1295  *
1296  * @param obj The datefield object
1297  * @return date format string. ex) yymmdd
1298  *
1299  * @ingroup Datefield
1300  */
1301 EAPI const char *
1302 elm_datefield_date_format_get(const Evas_Object *obj)
1303 {
1304    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1305    Widget_Data *wd = elm_widget_data_get(obj);
1306
1307    switch (wd->date_format)
1308      {
1309       case DATE_FORMAT_YYMMDD: return "yymmdd";
1310       case DATE_FORMAT_YYDDMM: return "yyddmm";
1311       case DATE_FORMAT_MMYYDD: return "mmyydd";
1312       case DATE_FORMAT_MMDDYY: return "mmddyy";
1313       case DATE_FORMAT_DDYYMM: return "ddyymm";
1314       case DATE_FORMAT_DDMMYY: return "ddmmyy";
1315      }
1316 }
1317
1318 /**
1319  * Add a callback function for input panel state
1320  *
1321  * @param obj The datefield object
1322  * @param func The function to be called when the event is triggered (value will be the Ecore_IMF_Input_Panel_State)
1323  * @param data The data pointer to be passed to @p func 
1324  *
1325  * @ingroup Datefield
1326  */
1327 EAPI void 
1328 elm_datefield_input_panel_state_callback_add(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value), void *data)
1329 {
1330    ELM_CHECK_WIDTYPE(obj, widtype);
1331    Widget_Data *wd = elm_widget_data_get(obj);
1332    int i;
1333
1334    if (!wd) return;
1335
1336    if (wd->func && (wd->func != pEventCallbackFunc))
1337      elm_datefield_input_panel_state_callback_del(obj, wd->func);
1338
1339    if (wd->func != pEventCallbackFunc)
1340      {
1341         wd->func = pEventCallbackFunc;
1342         wd->func_data = data;
1343
1344         for (i = 0; i < DATE_MAX; i++)
1345           ecore_imf_context_input_panel_event_callback_add(
1346         elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1347
1348         for (i = 0; i < TIME_MAX; i++)
1349           ecore_imf_context_input_panel_event_callback_add(
1350         elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1351      }
1352 }
1353
1354 /**
1355  * Delete a callback function for input panel state
1356  *
1357  * @param obj The datefield object
1358  * @param func The function to be called when the event is triggered
1359  *
1360  * @ingroup Datefield
1361  */
1362 EAPI void 
1363 elm_datefield_input_panel_state_callback_del(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value))
1364 {
1365    ELM_CHECK_WIDTYPE(obj, widtype);
1366    Widget_Data *wd = elm_widget_data_get(obj);
1367    int i;
1368
1369    if (!wd) return;
1370
1371    if (wd->func && wd->func == pEventCallbackFunc) 
1372      {
1373         for (i = 0; i < DATE_MAX; i++)
1374           ecore_imf_context_input_panel_event_callback_del(
1375         elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1376
1377         for (i = 0; i < TIME_MAX; i++)
1378           ecore_imf_context_input_panel_event_callback_del(
1379         elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1380
1381         wd->func = NULL;
1382         wd->func_data = NULL;
1383      }
1384 }