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