Merge "gengrid TC modified"
[framework/uifw/elementary.git] / tests / src / lib / elm_datefield.c
1 #include <locale.h>
2 #include <Elementary.h>
3 #include "elm_priv.h"
4
5 /**
6  * @defgroup Datefield Datefield
7  * @ingroup Elementary
8  *
9  * This is a date edit field. it is used to input date and time using
10  * diskselector integrated ctxpopup.
11  *
12  * Datefield Format can be like "%b %d, %Y %I : %M %p".
13  * Maximum allowed format length is 32 chars.
14  * Format can include separators for each individual datefield item.
15  * Each separator can be a maximum of 6 UTF-8 bytes.
16  * Space is also taken as a separator.
17  * Following are the allowed set of format specifiers for each datefield item.
18  * These specifiers can be arranged at any order as per user requirement and
19  * their value will be replaced in the format as mentioned below.
20  * %Y : The year as a decimal number including the century.
21  * %y : The year as a decimal number without a century (range 00 to 99)
22  * %m : The month as a decimal number (range 01 to 12).
23  * %b : The abbreviated month name according to the current locale.
24  * %B : The full month name according to the current locale.
25  * %d : The day of the month as a decimal number (range 01 to 31).
26  * %I : The hour as a decimal number using a 12-hour clock (range 01 to 12).
27  * %H : The hour as a decimal number using a 24-hour clock (range 00 to 23).
28  * %k : The hour (24-hour clock) as a decimal number (range 0 to 23). single
29  *      digits are preceded by a blank.
30  * %l : The hour (12-hour clock) as a decimal number (range 1 to 12); single
31  *      digits are preceded by a blank.
32  * %M : The minute as a decimal number (range 00 to 59).
33  * %p : Either 'AM' or 'PM' according to the given time value, or the
34  *      corresponding strings for the current locale. Noon is treated as 'PM'
35  *      and midnight as 'AM'
36  * %P : Like %p but in lowercase: 'am' or 'pm' or a corresponding string for
37  *      the current locale.
38  * For more reference, see the below link:
39  * http://www.gnu.org/s/hello/manual/libc.html#Formatting-Calendar-Time
40  * Default format is taken as per the system display language and Region format.
41  *
42  */
43
44 typedef struct _Widget_Data Widget_Data;
45
46 #define DATEFIELD_TYPE_COUNT        6
47 #define BUFFER_SIZE                 64
48 #define MAX_FORMAT_LEN              32
49 #define MAX_SEPARATOR_LEN           6
50 #define MAX_ITEM_FORMAT_LEN         3
51 #define DISKSELECTOR_ITEMS_NUM_MIN  4
52
53 // Interface between EDC & C code. Item names & signal names.
54 // Values 0 to 6 are valid range, can be substituted for %d.
55 #define EDC_DATEFIELD_ENABLE_SIG_STR        "elm,state,enabled"
56 #define EDC_DATEFIELD_DISABLE_SIG_STR       "elm,state,disabled"
57 #define EDC_DATEFIELD_FOCUSIN_SIG_STR       "elm,action,focus"
58 #define EDC_DATEFIELD_FOCUSOUT_SIG_STR      "elm,action,unfocus"
59 #define EDC_PART_ITEM_STR                   "item%d"
60 #define EDC_PART_SEPARATOR_STR              "separator%d"
61 #define EDC_PART_ITEM_OVER_STR              "item%d.over"
62 #define EDC_PART_ITEM_ENABLE_SIG_STR        "item%d,enable"
63 #define EDC_PART_ITEM_DISABLE_SIG_STR       "item%d,disable"
64 #define EDC_PART_ITEM_FOCUSIN_SIG_STR       "item%d,focus,in"
65 #define EDC_PART_ITEM_FOCUSOUT_SIG_STR      "item%d,focus,out"
66 #define EDC_PART_ITEM_STYLE_DEFAULT_SIG_STR "item%d,style,default"
67 #define EDC_PART_ITEM_STYLE_AMPM_SIG_STR    "item%d,style,ampm"
68
69 #define DEFAULT_FORMAT "%b %d, %Y %I : %M %p"
70
71 typedef struct _Format_Map
72 {
73    Elm_Datefield_ItemType type;
74    char fmt_char[5];
75    int def_min;
76    int def_max;
77 }Format_Map;
78
79 static const Format_Map mapping[DATEFIELD_TYPE_COUNT] = {
80    { ELM_DATEFIELD_YEAR,   "Yy",    70, 137 },
81    { ELM_DATEFIELD_MONTH,  "mbB",   0,  11  },
82    { ELM_DATEFIELD_DATE,   "d",     1,  31  },
83    { ELM_DATEFIELD_HOUR,   "IHkl",  0,  23  },
84    { ELM_DATEFIELD_MINUTE, "M",     0,  59  },
85    { ELM_DATEFIELD_AMPM,   "pP",    0,  1   }
86 };
87
88 static int _days_in_month[12] = { 31, 28, 31, 30, 31, 30,
89                                   31, 31, 30, 31, 30, 31 };
90
91 typedef enum _Elm_Datefield_HourType
92   {
93      ELM_DATEFIELD_HOUR_12 = 1000,
94      ELM_DATEFIELD_HOUR_24,
95      ELM_DATEFIELD_HOUR_NA
96   } Elm_Datefield_HourType;
97
98
99 typedef struct _Datefield_Item
100 {
101    char fmt[MAX_ITEM_FORMAT_LEN];
102    Elm_Datefield_ItemType type;
103    Elm_Datefield_HourType hour_type;
104    const char *content; //string to be displayed
105    const char *separator;
106    int location; //location of the item as per the current format
107    int *value;
108    int min, max;
109    int default_min, default_max;
110    Eina_Bool fmt_exist:1; //if item format is present or not
111    Eina_Bool enabled:1; //if item is to be shown or not
112    Eina_Bool abs_min:1;
113    Eina_Bool abs_max:1;
114 } Datefield_Item;
115
116 struct _Widget_Data
117 {
118    Evas_Object *base;
119    struct tm *time;
120    int ampm;
121    Datefield_Item *item_list; //Fixed set of items, so no Eina list.
122    Evas_Object *ctxpopup;
123    Datefield_Item *selected_it;
124    char format[MAX_FORMAT_LEN];
125    Eina_Bool user_format:1; //whether user set format or the default format.
126 };
127
128 typedef struct _DiskItem_Data
129 {
130    Evas_Object *datefield;
131    unsigned int sel_item_value;
132 } DiskItem_Data;
133
134 static const char *widtype = NULL;
135
136 static void _del_hook(Evas_Object *obj);
137 static void _on_focus_hook(void *data __UNUSED__, Evas_Object *obj);
138 static void _disable_hook(Evas_Object *obj);
139 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
140 static void _sizing_eval(Evas_Object *obj);
141 static void _theme_hook(Evas_Object *obj);
142 static void _ctxpopup_dismissed_cb(void *data, Evas_Object *obj __UNUSED__,
143                                    void *event_info __UNUSED__);
144 static void _datefield_resize_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj
145                                  __UNUSED__, void *event_info __UNUSED__);
146 static void _datefield_move_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj
147                                  __UNUSED__, void *event_info __UNUSED__);
148
149 static void _update_items(Evas_Object *obj);
150 static void _field_value_set(Evas_Object * obj, Elm_Datefield_ItemType type,
151                              int value, Eina_Bool adjust_time);
152 static void _diskselector_cb(void *data, Evas_Object *obj __UNUSED__,
153                              void *event_info __UNUSED__);
154 static void _ampm_clicked (void *data);
155 static void _diskselector_item_free_cb(void *data, Evas_Object *obj __UNUSED__,
156                                        void *event_info __UNUSED__);
157 static void _load_field_options(Evas_Object * data, Evas_Object *diskselector,
158                                 Datefield_Item *it);
159 static void _datefield_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
160                      const char *emission __UNUSED__, const char *source);
161 static void _format_reload(Evas_Object *obj);
162 static void _item_list_init(Evas_Object *obj);
163
164 static const char SIG_CHANGED[] = "changed";
165 static const Evas_Smart_Cb_Description _signals[] = {
166        {SIG_CHANGED, ""},
167        {NULL, NULL}
168 };
169
170 static void
171 _del_hook(Evas_Object *obj)
172 {
173    Widget_Data *wd;
174    Datefield_Item *tmp;
175    unsigned int idx;
176
177    wd = elm_widget_data_get(obj);
178    if (!wd) return;
179    if (wd->time) free(wd->time);
180    for (idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++ )
181      {
182         tmp = wd->item_list + idx;
183         eina_stringshare_replace(&tmp->content, NULL);
184         eina_stringshare_replace(&tmp->separator, NULL);
185      }
186    if (wd->item_list) free(wd->item_list);
187    evas_object_del(wd->ctxpopup);
188
189    free(wd);
190 }
191
192 static void
193 _disable_hook(Evas_Object *obj)
194 {
195    Widget_Data *wd;
196
197    wd = elm_widget_data_get(obj);
198    if (!wd || !wd->base) return;
199    if (elm_widget_disabled_get(obj))
200      {
201         evas_object_hide(wd->ctxpopup);
202         edje_object_signal_emit(wd->base, EDC_DATEFIELD_DISABLE_SIG_STR,"elm");
203      }
204    else
205      edje_object_signal_emit(wd->base, EDC_DATEFIELD_ENABLE_SIG_STR, "elm");
206 }
207
208 static void
209 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
210 {
211    Widget_Data *wd;
212
213    wd = elm_widget_data_get(obj);
214    if (!wd ) return;
215    if (elm_widget_focus_get(obj))
216       edje_object_signal_emit(wd->base, EDC_DATEFIELD_FOCUSIN_SIG_STR, "elm");
217    else
218       edje_object_signal_emit(wd->base, EDC_DATEFIELD_FOCUSOUT_SIG_STR, "elm");
219 }
220
221 static void
222 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
223 {
224    Widget_Data *wd;
225
226    wd = elm_widget_data_get(obj);
227    if (!wd) return;
228    evas_object_hide(wd->ctxpopup);
229    edje_object_mirrored_set(wd->base, rtl);
230 }
231
232 static void
233 _sizing_eval(Evas_Object *obj)
234 {
235    Widget_Data *wd;
236    Evas_Coord minw = -1, minh = -1;
237
238    wd = elm_widget_data_get(obj);
239    if (!wd || !wd->base) return;
240    edje_object_size_min_calc(wd->base, &minw, &minh);
241    evas_object_size_hint_min_set(obj, minw, minh);
242    evas_object_size_hint_max_set(obj, -1, -1);
243 }
244
245 static void
246 _theme_hook(Evas_Object *obj)
247 {
248    Widget_Data *wd;
249    Datefield_Item *it;
250    char buf[BUFFER_SIZE];
251    unsigned int idx;
252    //Evas_Object *diskselector;
253
254    wd = elm_widget_data_get(obj);
255    if (!wd || !wd->base) return;
256    _elm_theme_object_set(obj, wd->base, "datefield", "base",
257                          elm_widget_style_get(obj));
258    _elm_widget_mirrored_reload(obj);
259    _mirrored_set(obj, elm_widget_mirrored_get(obj));
260
261    snprintf(buf, sizeof(buf), "datefield/%s", elm_object_style_get(obj));
262    elm_object_style_set(wd->ctxpopup, buf);
263    /*//Enabled once elm_object_content_get() API comes to git.
264    if (diskselector = elm_object_content_get(wd->ctxpopup))
265    elm_object_style_set(diskselector, buf);*/
266    edje_object_scale_set(wd->base,elm_widget_scale_get(obj)*_elm_config->scale);
267
268    if (elm_widget_disabled_get(obj))
269      edje_object_signal_emit(wd->base, EDC_DATEFIELD_DISABLE_SIG_STR,"elm");
270    else
271      edje_object_signal_emit(wd->base, EDC_DATEFIELD_ENABLE_SIG_STR, "elm");
272
273    for (idx= 0; idx < DATEFIELD_TYPE_COUNT; idx++ )
274      {
275         it = wd->item_list + idx;
276         if (it->fmt_exist && it->enabled )
277           {
278              snprintf(buf, sizeof(buf), EDC_PART_ITEM_STR, it->location);
279              edje_object_part_text_set(wd->base, buf, it->content);
280              snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, it->location);
281              edje_object_part_text_set(wd->base, buf, it->separator);
282              snprintf(buf, sizeof(buf), EDC_PART_ITEM_ENABLE_SIG_STR,
283                       it->location);
284              edje_object_signal_emit(wd->base, buf, "elm");
285              if (it->type == ELM_DATEFIELD_AMPM)
286                snprintf(buf, sizeof(buf), EDC_PART_ITEM_STYLE_AMPM_SIG_STR,
287                         it->location);
288              else
289                snprintf(buf, sizeof(buf), EDC_PART_ITEM_STYLE_DEFAULT_SIG_STR,
290                         it->location);
291              edje_object_signal_emit(wd->base, buf, "elm");
292           }
293         else
294           {
295              snprintf(buf, sizeof(buf),EDC_PART_ITEM_DISABLE_SIG_STR,
296                       it->location);
297              edje_object_signal_emit(wd->base, buf, "elm");
298           }
299      }
300    edje_object_message_signal_process(wd->base);
301    _sizing_eval(obj);
302 }
303
304 static void
305 _ctxpopup_dismissed_cb(void *data, Evas_Object *obj __UNUSED__,
306                        void *event_info __UNUSED__)
307 {
308    Widget_Data *wd;
309    Evas_Object *diskselector;
310    char buf[BUFFER_SIZE];
311
312    wd = elm_widget_data_get(data);
313    if (!wd || !wd->base) return;
314    diskselector = elm_ctxpopup_content_unset(wd->ctxpopup);
315    if (diskselector) evas_object_del(diskselector);
316
317    if (wd->selected_it)
318      {
319         snprintf(buf, sizeof(buf), EDC_PART_ITEM_FOCUSOUT_SIG_STR,
320                  wd->selected_it->location);
321         edje_object_signal_emit(wd->base, buf, "elm");
322         wd->selected_it = NULL;
323      }
324 }
325
326 static void
327 _datefield_resize_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj __UNUSED__,
328                      void *event_info __UNUSED__)
329 {
330    Widget_Data *wd;
331
332    wd = elm_widget_data_get(data);
333    if (!wd) return;
334    evas_object_hide(wd->ctxpopup);
335 }
336
337 static void
338 _datefield_move_cb(void *data, Evas *e __UNUSED__,Evas_Object *obj __UNUSED__,
339                      void *event_info __UNUSED__)
340 {
341    Widget_Data *wd;
342
343    wd = elm_widget_data_get(data);
344    if (!wd) return;
345    evas_object_hide(wd->ctxpopup);
346 }
347
348 static void
349 _contextual_field_limit_get(Evas_Object * obj, Datefield_Item * it,
350                 Eina_Bool hr_fmt_check, int *range_min, int *range_max)
351 {
352    Widget_Data *wd;
353    Datefield_Item * tmp;
354    unsigned int idx;
355    int ctx_max;
356    Eina_Bool min_limit = EINA_TRUE;
357    Eina_Bool max_limit = EINA_TRUE;
358
359    wd = elm_widget_data_get(obj);
360    if (!wd || !it) return;
361
362    //Top to down check for current field relative min/max limit
363    if (!it->abs_min || !it->abs_max )
364      {
365         for (idx = ELM_DATEFIELD_YEAR; idx < it->type; idx++)
366           {
367              tmp = wd->item_list + idx;
368              if (max_limit && (*(tmp->value) < tmp->max)) max_limit= EINA_FALSE;
369              if (min_limit && (*(tmp->value) > tmp->min)) min_limit= EINA_FALSE;
370           }
371      }
372
373    if (it->abs_min || min_limit) (*range_min) = it->min;
374    else (*range_min) = it->default_min;
375
376    if (it->abs_max || max_limit) (*range_max) = it->max;
377    else (*range_max) = it->default_max;
378
379    ctx_max = it->default_max;
380    if (it->type == ELM_DATEFIELD_DATE )
381      {
382         ctx_max = _days_in_month[wd->time->tm_mon];
383         // Check for Leap year Feb.
384         if (__isleap((wd->time->tm_year)) && wd->time->tm_mon == 1) ctx_max= 29;
385      }
386    else if (it->type == ELM_DATEFIELD_HOUR  &&  hr_fmt_check &&
387             it->hour_type == ELM_DATEFIELD_HOUR_12 )  ctx_max = 11;
388
389    if (*range_max > ctx_max) *range_max = ctx_max;
390 }
391
392 static void
393 _update_items(Evas_Object *obj)
394 {
395    Widget_Data *wd;
396    Datefield_Item *it;
397    char buf[BUFFER_SIZE];
398    unsigned int idx= 0;
399
400    wd = elm_widget_data_get(obj);
401    if (!wd || !wd->base) return;
402    for (idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++ )
403      {
404         it = wd->item_list + idx;
405         if ( it->fmt_exist && it->enabled )
406           {
407              strftime(buf, BUFFER_SIZE, it->fmt, wd->time);
408
409              // FIXME: no locale string availble from Libc...
410              if ((!strncmp(buf, "",1)) && (it->type == ELM_DATEFIELD_AMPM))
411                {
412                   if (wd->ampm) strncpy(buf, E_("PM"), BUFFER_SIZE);
413                   else strncpy(buf, E_("AM"), BUFFER_SIZE);
414                }
415              eina_stringshare_replace(&it->content, buf);
416              snprintf(buf, sizeof(buf), EDC_PART_ITEM_STR, it->location);
417              edje_object_part_text_set(wd->base, buf, it->content);
418           }
419      }
420 }
421
422 static void
423 _field_value_set(Evas_Object * obj, Elm_Datefield_ItemType item_type, int value,
424                  Eina_Bool adjust_time)
425 {
426    Widget_Data *wd;
427    Datefield_Item * it;
428    unsigned int idx;
429    int min, max;
430    Eina_Bool value_changed = EINA_FALSE;
431
432    wd = elm_widget_data_get(obj);
433    if (!wd) return;
434
435    if (item_type == ELM_DATEFIELD_AMPM)
436      {
437         if ( value == wd->ampm ) return;
438         item_type = ELM_DATEFIELD_HOUR;
439         value = (wd->time->tm_hour + 12) % 24;
440         adjust_time =  EINA_FALSE;
441      }
442
443    it = wd->item_list + item_type;
444    _contextual_field_limit_get(obj, it, EINA_FALSE, &min, &max);
445
446    //12 hr format & PM then add 12 to value.
447    if (adjust_time && it->type == ELM_DATEFIELD_HOUR &&
448        it->hour_type == ELM_DATEFIELD_HOUR_12 && wd->ampm && value < 12)
449       value += 12;
450
451    if (value < min) value = min;
452    else if (value > max) value = max;
453    if ( *(it->value) == value) return;
454    *(it->value) = value;
455    value_changed = EINA_TRUE;
456
457    //Validate & reset lower order fields
458    for ( idx = item_type+1; idx < DATEFIELD_TYPE_COUNT; idx++ )
459      {
460         it = wd->item_list + idx;
461         _contextual_field_limit_get(obj, it, EINA_FALSE, &min, &max);
462         //Validate current value against context based Min/Max restriction.
463         if (*it->value < min)
464           {
465              *it->value = min;
466              value_changed = EINA_TRUE;
467           }
468         else if (*it->value > max)
469           {
470              *it->value = max;
471              value_changed = EINA_TRUE;
472           }
473      }
474    //update AM/PM state
475    wd->ampm = (wd->time->tm_hour > 11 );
476    _update_items(obj);
477
478    if (value_changed)
479      evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
480 }
481
482 static void
483 _diskselector_cb(void *data, Evas_Object *obj __UNUSED__,
484                  void *event_info __UNUSED__)
485 {
486    DiskItem_Data *cb_data;
487    Widget_Data *wd;
488
489    cb_data = (DiskItem_Data *)data;
490    if (!cb_data) return;
491    wd = elm_widget_data_get(cb_data->datefield);
492    if (!wd ) return;
493
494    _field_value_set(cb_data->datefield, wd->selected_it->type,
495                     cb_data->sel_item_value, EINA_TRUE);
496
497    evas_object_hide(wd->ctxpopup);
498 }
499
500 static void
501 _ampm_clicked (void *data)
502 {
503    Widget_Data *wd;
504    char buf[BUFFER_SIZE];
505
506    wd = elm_widget_data_get(data);
507    if (!wd || !wd->base) return;
508
509    _field_value_set( data, ELM_DATEFIELD_AMPM, !wd->ampm, EINA_FALSE );
510
511    snprintf(buf, sizeof(buf), EDC_PART_ITEM_FOCUSOUT_SIG_STR,
512             wd->selected_it->location);
513    edje_object_signal_emit(wd->base, buf, "elm");
514    wd->selected_it = NULL;
515 }
516
517 static void
518 _diskselector_item_free_cb(void *data, Evas_Object *obj __UNUSED__,
519                            void *event_info __UNUSED__)
520 {
521    if (data) free(data);
522 }
523 \r
524 static void
525 _load_field_options(Evas_Object * data, Evas_Object *diskselector,
526                     Datefield_Item *it)
527 {
528    Widget_Data *wd;
529    DiskItem_Data *disk_data;
530    Elm_Object_Item *item;
531    int idx, min, max, selected_val;
532    int text_len, max_len = 0;
533    char item_label[BUFFER_SIZE];
534    int cur_val, date_val;
535
536    wd = elm_widget_data_get(data);
537    if (!wd) return;
538
539    cur_val = *(it->value);
540    date_val = wd->time->tm_mday;
541    _contextual_field_limit_get(data, it, EINA_TRUE, &min, &max );
542
543    selected_val = *(it->value);
544    wd->time->tm_mday = 1;
545    // If 12hr format & PM, reduce 12
546    if (it->hour_type == ELM_DATEFIELD_HOUR_12 && wd->ampm) selected_val -= 12;
547
548    for (idx = min; idx <= max; idx++)\r
549      {
550         *(it->value) = idx;
551         strftime(item_label, BUFFER_SIZE, it->fmt, wd->time );
552         text_len = strlen(item_label);
553         if (text_len > max_len ) max_len = text_len; //Store max. label length
554
555         if (idx == selected_val) //Selected Item, dont attach a callback handler
556           {
557              item = elm_diskselector_item_append(diskselector, item_label,
558                                                  NULL, NULL, NULL);
559              elm_diskselector_item_selected_set(item, EINA_TRUE);
560           }
561         else
562           {
563              disk_data = (DiskItem_Data *) malloc (sizeof(DiskItem_Data));
564              disk_data->datefield = data;
565              disk_data->sel_item_value = idx;
566              item = elm_diskselector_item_append(diskselector,
567                                  item_label, NULL, _diskselector_cb, disk_data);
568              elm_diskselector_item_del_cb_set(item, _diskselector_item_free_cb);
569           }
570      }
571    *(it->value) = cur_val;
572    wd->time->tm_mday = date_val;
573    elm_diskselector_side_label_length_set(diskselector, max_len);
574 }
575
576 static void
577 _datefield_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
578                       const char *emission __UNUSED__, const char *source)
579 {
580    Widget_Data *wd = elm_widget_data_get(data);
581    Evas_Object *diskselector;
582    const Evas_Object *edj_part;
583    char buf[BUFFER_SIZE];
584    unsigned int idx = 0, idx1 = 0, display_item_num;
585    Evas_Coord x = 0, y = 0, w = 0, h = 0;
586    Evas_Coord disksel_width;
587
588    if (!wd || !wd->base) return;
589    if (elm_widget_disabled_get(data)) return;
590
591    wd->selected_it = NULL;
592    //Locate the selected Index & Selected Datefield_Item
593    for (idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++ )
594      {
595         snprintf(buf, sizeof(buf), EDC_PART_ITEM_OVER_STR, idx);
596         if (!strncmp(buf, source, sizeof(buf)))
597           {
598              for (idx1 = 0; idx1 < DATEFIELD_TYPE_COUNT; idx1++ )
599                {
600                  if ((wd->item_list + idx1)->location == (int)idx)
601                    {
602                       wd->selected_it = wd->item_list + idx1;
603                       break;
604                    }
605                }
606              break;
607           }
608      }
609
610    if ( !wd->selected_it || !wd->selected_it->fmt_exist
611                          || !wd->selected_it->enabled ) return;
612    snprintf(buf, sizeof(buf), EDC_PART_ITEM_FOCUSIN_SIG_STR,
613             wd->selected_it->location);
614    edje_object_signal_emit(wd->base, buf, "elm");
615
616    if ( wd->selected_it->type == ELM_DATEFIELD_AMPM )
617      {
618         _ampm_clicked (data);
619         return;
620      }
621
622    //Recreating diskselector everytime due to diskselector behavior
623    diskselector = elm_diskselector_add(elm_widget_top_get(data));
624    snprintf(buf, sizeof(buf), "datefield/%s", elm_object_style_get(data));
625    elm_object_style_set(diskselector, buf);
626
627    //Load the options list
628    _load_field_options(data, diskselector, wd->selected_it);
629
630    elm_ctxpopup_direction_priority_set(wd->ctxpopup, ELM_CTXPOPUP_DIRECTION_DOWN,
631                                        ELM_CTXPOPUP_DIRECTION_UP, -1, -1);
632    elm_object_content_set(wd->ctxpopup, diskselector);
633    snprintf(buf,sizeof(buf), EDC_PART_ITEM_STR, wd->selected_it->location);
634    edj_part = edje_object_part_object_get(wd->base, buf);
635    evas_object_geometry_get(edj_part, &x, &y, &w, &h);
636    evas_object_move(wd->ctxpopup, (x+w/2), (y+h));
637
638    //If the direction of Ctxpopup is upwards, move it to the top of datefield
639    if (elm_ctxpopup_direction_get (wd->ctxpopup) == ELM_CTXPOPUP_DIRECTION_UP)
640      {
641         elm_ctxpopup_direction_priority_set(wd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
642                                             ELM_CTXPOPUP_DIRECTION_DOWN, -1, -1);
643         evas_object_move(wd->ctxpopup, (x+w/2), y);
644      }
645    evas_object_show(wd->ctxpopup);
646
647    evas_object_geometry_get(diskselector, NULL, NULL, &disksel_width, NULL);
648    display_item_num = disksel_width / (w +  elm_finger_size_get());
649    //odd number of items leads to auto selection.
650    //making as event number of item to prevent auto selection.
651    if (display_item_num%2) display_item_num-=1;
652    if (display_item_num < DISKSELECTOR_ITEMS_NUM_MIN)
653      display_item_num = DISKSELECTOR_ITEMS_NUM_MIN;
654
655    elm_diskselector_display_item_num_set(diskselector, display_item_num);
656    elm_diskselector_round_set(diskselector, EINA_TRUE);
657 }
658
659 static unsigned int
660 _parse_format( Evas_Object *obj )
661 {
662    Widget_Data *wd;
663    Datefield_Item *it = NULL;
664    unsigned int len = 0, idx, location = 0;
665    char separator[MAX_SEPARATOR_LEN];
666    char *fmt_ptr;
667    char cur;
668    Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE,
669              sep_lookup = EINA_FALSE;
670
671    wd = elm_widget_data_get(obj);
672    fmt_ptr = wd->format;
673
674    while ( (cur = *fmt_ptr ) )
675      {
676         if (fmt_parsing)
677           {
678              for ( idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++ )
679                {
680                   if ( strchr( mapping[idx].fmt_char, cur ) )
681                     {
682                        it = wd->item_list + idx;
683                        //Ignore the items already have or disabled
684                        //valid formats, means already parsed & repeated, ignore.
685                        if (!it->enabled || it->location != -1) break;
686                        it->fmt[1] = cur;
687
688                       //set the hour display format 12h/24h
689                        if (it->type == ELM_DATEFIELD_HOUR)
690                          {
691                             if (cur == 'H' || cur == 'k' )
692                               it->hour_type = ELM_DATEFIELD_HOUR_24;
693                             else if (cur == 'I' || cur == 'l' )
694                               it->hour_type = ELM_DATEFIELD_HOUR_12;
695                          }
696                        else it->hour_type = ELM_DATEFIELD_HOUR_NA;
697
698                        it->fmt_exist = EINA_TRUE;
699                        it->location = location++;
700                        fmt_parsing = EINA_FALSE;
701                        sep_lookup = EINA_TRUE;
702                        len = 0;
703                        break;
704                     }
705                }
706           }
707
708         if (cur == '%')
709           {
710              fmt_parsing = EINA_TRUE;
711              sep_parsing = EINA_FALSE;
712              // Set the separator to previous Item
713              separator[len] = 0;
714              if (it) eina_stringshare_replace(&it->separator, separator);
715           }
716         if (sep_parsing && (len < MAX_SEPARATOR_LEN-1)) separator[len++] = cur;
717         if (sep_lookup) sep_parsing = EINA_TRUE;
718         sep_lookup = EINA_FALSE;
719         fmt_ptr++;
720    }
721    // Return the number of valid items parsed.
722    return location;
723 }
724
725 static void
726 _format_reload(Evas_Object *obj)
727 {
728    Widget_Data *wd;
729    Datefield_Item *it;
730    char buf[BUFFER_SIZE];
731    unsigned int idx, location;
732    char *def_fmt;
733
734    wd = elm_widget_data_get(obj);
735    if (!wd) return;
736
737     // fetch the format from locale specific po file.
738    if (!wd->user_format )
739      {
740         def_fmt = E_("DateTimeFormat");
741         if (!strncmp(def_fmt, "DateTimeFormat", sizeof("DateTimeFormat")))
742           strncpy(wd->format, DEFAULT_FORMAT, MAX_FORMAT_LEN );
743         else
744           strncpy(wd->format, def_fmt, MAX_FORMAT_LEN );
745      }
746
747    //reset all the items to disable state
748    for ( idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++ )
749      {
750         it = wd->item_list + idx;
751         eina_stringshare_replace(&it->content, NULL);
752         it->fmt_exist = EINA_FALSE;
753         it->location = -1;
754      }
755    location = _parse_format( obj );
756
757    //assign locations to disabled fields for uniform usage
758    for (idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++)
759      {
760         it = wd->item_list + idx;
761         if (it->location == -1) it->location = location++;
762
763         if (it->fmt_exist && it->enabled)
764           {
765              snprintf(buf, sizeof(buf), EDC_PART_ITEM_ENABLE_SIG_STR,
766                       it->location);
767              edje_object_signal_emit(wd->base, buf, "elm");
768              if (it->type == ELM_DATEFIELD_AMPM)
769                snprintf(buf, sizeof(buf), EDC_PART_ITEM_STYLE_AMPM_SIG_STR,
770                         it->location);
771              else
772                snprintf(buf, sizeof(buf), EDC_PART_ITEM_STYLE_DEFAULT_SIG_STR,
773                         it->location);
774              edje_object_signal_emit(wd->base, buf, "elm");
775           }
776         else
777           {
778              snprintf(buf, sizeof(buf),EDC_PART_ITEM_DISABLE_SIG_STR,
779                       it->location);
780              edje_object_signal_emit(wd->base, buf, "elm");
781           }
782         snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, it->location+1);
783         edje_object_part_text_set(wd->base, buf, it->separator);
784      }
785    edje_object_message_signal_process(wd->base);
786    _update_items(obj);
787 }
788
789 static void
790 _item_list_init(Evas_Object *obj)
791 {
792    Widget_Data *wd;
793    Datefield_Item *it;
794    char buf[BUFFER_SIZE];
795    unsigned int idx;
796    time_t t;
797
798    wd = elm_widget_data_get(obj);
799    if (!wd) return;
800
801    wd->item_list = calloc(1, DATEFIELD_TYPE_COUNT * sizeof(Datefield_Item));
802    wd->time = calloc(1, sizeof(struct tm));
803    t = time(NULL);
804    localtime_r(&t, wd->time);
805
806    (wd->item_list + ELM_DATEFIELD_YEAR)->value = &wd->time->tm_year;
807    (wd->item_list + ELM_DATEFIELD_MONTH)->value = &wd->time->tm_mon;
808    (wd->item_list + ELM_DATEFIELD_DATE)->value = &wd->time->tm_mday;
809    (wd->item_list + ELM_DATEFIELD_HOUR)->value = &wd->time->tm_hour;
810    (wd->item_list + ELM_DATEFIELD_MINUTE)->value = &wd->time->tm_min;
811    (wd->item_list + ELM_DATEFIELD_AMPM)->value = &wd->ampm;
812     wd->ampm = (wd->time->tm_hour > 11 );
813
814    for (idx = 0; idx < DATEFIELD_TYPE_COUNT; idx++)
815      {
816         it = wd->item_list + idx;
817         it->type = ELM_DATEFIELD_YEAR + idx;
818         it->fmt[0] = '%';
819         it->fmt_exist = EINA_FALSE;
820         it->enabled  = EINA_TRUE;
821         it->min = mapping[idx].def_min;
822         it->default_min = mapping[idx].def_min;
823         it->max = mapping[idx].def_max;
824         it->default_max = mapping[idx].def_max;
825         snprintf(buf, sizeof(buf), EDC_PART_ITEM_OVER_STR, idx);
826         edje_object_signal_callback_add(wd->base, "mouse,clicked,1", buf,
827                                         _datefield_clicked_cb, obj);
828      }
829 }
830
831 /**
832  * @brief Add a new datefield Widget
833  * The date format and strings are based on current locale
834  *
835  * @param[in] parent The parent object
836  * @return The new object or NULL if it cannot be created
837  *
838  * @ingroup Datefield
839  */
840 EAPI Evas_Object *
841 elm_datefield_add(Evas_Object *parent)
842 {
843    Evas_Object *obj;
844    Evas *e;
845    Widget_Data *wd;
846
847    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
848
849    ELM_SET_WIDTYPE(widtype, "datefield");
850    elm_widget_type_set(obj, widtype);
851    elm_widget_sub_object_add(parent, obj);
852    elm_widget_data_set(obj, wd);
853    elm_widget_del_hook_set(obj, _del_hook);
854    elm_widget_theme_hook_set(obj, _theme_hook);
855    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
856    elm_widget_disable_hook_set(obj, _disable_hook);
857    elm_widget_can_focus_set(obj, EINA_TRUE);
858
859    wd->base = edje_object_add(e);
860    elm_widget_resize_object_set(obj, wd->base);
861    _elm_theme_object_set(obj, wd->base, "datefield", "base", "default");
862    evas_object_smart_callbacks_descriptions_set(obj, _signals);
863
864    _item_list_init(obj);
865    _format_reload(obj);
866
867    wd->ctxpopup = elm_ctxpopup_add(elm_widget_top_get(obj));
868    elm_object_style_set(wd->ctxpopup, "datefield/default");
869    elm_ctxpopup_horizontal_set(wd->ctxpopup, EINA_TRUE);
870    evas_object_size_hint_weight_set(wd->ctxpopup, EVAS_HINT_EXPAND,
871                                     EVAS_HINT_EXPAND);
872    evas_object_size_hint_align_set(wd->ctxpopup, EVAS_HINT_FILL,EVAS_HINT_FILL);
873    evas_object_smart_callback_add(wd->ctxpopup, "dismissed",
874                                   _ctxpopup_dismissed_cb, obj);
875    evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE,
876                                   _datefield_resize_cb, obj);
877    evas_object_event_callback_add(wd->base, EVAS_CALLBACK_MOVE,
878                                   _datefield_move_cb, obj);
879    _mirrored_set(obj, elm_widget_mirrored_get(obj));
880
881    return obj;
882 }
883
884 /**
885  * Set the format of datefield. Formats can be like "%b %d, %Y %I : %M %p".
886  * Maximum allowed format length is 32 chars.
887  * Format can include separators for each individual datefield item.
888  * Each separator can be a maximum of 6 UTF-8 bytes.
889  * Space is also taken as a separator.
890  * Following are the allowed set of format specifiers for each datefield item.
891  * These specifiers can be arranged at any order as per user requirement and
892  * their value will be replaced in the format as mentioned below.
893  * %Y : The year as a decimal number including the century.
894  * %y : The year as a decimal number without a century (range 00 to 99)
895  * %m : The month as a decimal number (range 01 to 12).
896  * %b : The abbreviated month name according to the current locale.
897  * %B : The full month name according to the current locale.
898  * %d : The day of the month as a decimal number (range 01 to 31).
899  * %I : The hour as a decimal number using a 12-hour clock (range 01 to 12).
900  * %H : The hour as a decimal number using a 24-hour clock (range 00 to 23).
901  * %k : The hour (24-hour clock) as a decimal number (range 0 to 23). single
902  *      digits are preceded by a blank.
903  * %l : The hour (12-hour clock) as a decimal number (range 1 to 12); single
904  *      digits are preceded by a blank.
905  * %M : The minute as a decimal number (range 00 to 59).
906  * %p : Either 'AM' or 'PM' according to the given time value, or the
907  *      corresponding strings for the current locale. Noon is treated as 'PM'
908  *      and midnight as 'AM'
909  * %P : Like %p but in lowercase: 'am' or 'pm' or a corresponding string for
910  *      the current locale.
911  * Default format is taken as per the system display language and Region format.
912  *
913  * @param[in] obj The datefield object
914  * @param[in] fmt The date format
915  *
916  */
917 EAPI void
918 elm_datefield_format_set(Evas_Object *obj, const char *fmt)
919 {
920    ELM_CHECK_WIDTYPE(obj, widtype);
921    Widget_Data *wd;
922
923    wd = elm_widget_data_get(obj);
924    if (!wd) return;
925
926    if (fmt)
927      {
928         strncpy( wd->format, fmt, MAX_FORMAT_LEN );
929         wd->user_format = EINA_TRUE;
930      }
931    else  wd->user_format = EINA_FALSE;
932
933    _format_reload(obj);
934 }
935
936 /**
937  * Get the format of datefield. Formats can be like "%b %d, %Y %I : %M %p".
938  * Maximum allowed format length is 32 chars.
939  * Format can include separators for each individual datefield item.
940  * Each separator can be a maximum of 6 UTF-8 bytes.
941  * Space is also taken as a separator.
942  * Following are the allowed set of format specifiers for each datefield item.
943  * These specifiers can be arranged at any order as per user requirement and
944  * their value will be replaced in the format as mentioned below.
945  * %Y : The year as a decimal number including the century.
946  * %y : The year as a decimal number without a century (range 00 to 99)
947  * %m : The month as a decimal number (range 01 to 12).
948  * %b : The abbreviated month name according to the current locale.
949  * %B : The full month name according to the current locale.
950  * %d : The day of the month as a decimal number (range 01 to 31).
951  * %I : The hour as a decimal number using a 12-hour clock (range 01 to 12).
952  * %H : The hour as a decimal number using a 24-hour clock (range 00 to 23).
953  * %k : The hour (24-hour clock) as a decimal number (range 0 to 23). single
954  *      digits are preceded by a blank.
955  * %l : The hour (12-hour clock) as a decimal number (range 1 to 12); single
956  *      digits are preceded by a blank.
957  * %M : The minute as a decimal number (range 00 to 59).
958  * %p : Either 'AM' or 'PM' according to the given time value, or the
959  *      corresponding strings for the current locale. Noon is treated as 'PM'
960  *      and midnight as 'AM'
961  * %P : Like %p but in lowercase: 'am' or 'pm' or a corresponding string for
962  *      the current locale.
963  * Default format is taken as per the system display language and Region format.
964  *
965  * @param[in] obj The datefield object
966  * @return date format string. ex) %b %d, %Y %I : %M %p
967  *
968  */
969 EAPI char *
970 elm_datefield_format_get(const Evas_Object *obj)
971 {
972    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
973    Widget_Data *wd = elm_widget_data_get(obj);
974    if (!wd ) return NULL;
975    return strdup(wd->format);
976 }
977
978 /**
979  * @brief Set the selected value of the datefield
980  * Year : years since 1900. Negative value represents year below 1900. (
981  * year value -30 represents 1870). Year default range is from 70 to 137.
982  * Month value range is from 0 to 11
983  * Date value range is from 1 to 31 according to the month value.
984  * The hour value should be set according to 24hr format (0~23)
985  * Minute value range is from 0 to 59.
986  * AM/PM. Value 0 for AM and 1 for PM.
987  * If the value is beyond the range,
988  * a) Value is less than Min range value, then Min range value is set.
989  * b) Greater than Max range value, then Max Range value is set.
990  * Both Min and Max range of individual fields are bound to the current context.
991  *
992  * @param[in] obj The datefield object
993  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
994  * @param[in] value The data to be set. ex. year/month/date/hour/minute/ampm
995  *
996  * @ingroup Datefield
997  */
998 EAPI void
999 elm_datefield_item_value_set(Evas_Object *obj, Elm_Datefield_ItemType itemtype,
1000                              int value)
1001 {
1002    ELM_CHECK_WIDTYPE(obj, widtype);
1003    Widget_Data *wd;
1004    Datefield_Item *it;
1005
1006    wd = elm_widget_data_get(obj);
1007    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return;
1008
1009    it = wd->item_list + itemtype;
1010    _field_value_set(obj, it->type, value, EINA_FALSE);
1011 }
1012
1013 /**
1014  * @brief Get Current value date of the datefield
1015  * Year : years since 1900. Negative value represents year below 1900. (
1016  * year value -30 represents 1870). Year default range is from 70 to 137.
1017  * Month value range is from 0 to 11
1018  * Date value range is from 1 to 31 according to the month value.
1019  * The hour value should be set according to 24hr format (0~23)
1020  * Minute value range is from 0 to 59.
1021  * AM/PM. Value 0 for AM and 1 for PM.
1022  * If the value is beyond the range,
1023  * a) Value is less than Min range value, then Min range value is set.
1024  * b) Greater than Max range value, then Max Range value is set.
1025  * Both Min and Max range of individual fields are bound to the current context.
1026  *
1027  * @param[in] obj The datefield object
1028  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1029  * @return int The value of the field.
1030  *
1031  * @ingroup Datefield
1032  */
1033 EAPI int
1034 elm_datefield_item_value_get(const Evas_Object *obj, Elm_Datefield_ItemType
1035                              itemtype)
1036 {
1037    ELM_CHECK_WIDTYPE(obj, widtype) -1;
1038    Widget_Data *wd;
1039
1040    wd = elm_widget_data_get(obj);
1041    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return -1;
1042
1043    return (*(wd->item_list + itemtype)->value);
1044 }
1045
1046
1047 /**
1048  * @brief Enable/Disable an item of the datefield
1049  *
1050  * @param[in] obj The datefield object
1051  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1052  * @param[in] enable Item is Enabled or disabled.
1053  *
1054  * @ingroup Datefield
1055  */
1056
1057 EAPI void
1058 elm_datefield_item_enabled_set(Evas_Object *obj, Elm_Datefield_ItemType itemtype,
1059                               Eina_Bool enable)
1060 {
1061    ELM_CHECK_WIDTYPE(obj, widtype);
1062    Widget_Data *wd;
1063    Datefield_Item *it;
1064
1065    wd = elm_widget_data_get(obj);
1066    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return;
1067
1068    it = wd->item_list + itemtype;
1069    if ( it->enabled == enable ) return;
1070    it->enabled = enable;
1071    _format_reload(obj);
1072 }
1073
1074 /**
1075  * @brief Get whether the item is Enabled/Disabled
1076  *
1077  * @param[in] obj The datefield object
1078  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1079  * @return EINA_TRUE = Item is Enabled or EINA_FALSE = disabled.
1080  *
1081  * @ingroup Datefield
1082  */
1083
1084 EAPI Eina_Bool
1085 elm_datefield_item_enabled_get(const Evas_Object *obj, Elm_Datefield_ItemType itemtype)
1086 {
1087    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1088    Widget_Data *wd;
1089    Datefield_Item *it;
1090
1091    wd = elm_widget_data_get(obj);
1092    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return EINA_FALSE;
1093
1094    it = wd->item_list + itemtype;
1095    return it->enabled;
1096 }
1097
1098 /**
1099  * @brief Get lower boundary of the datefield
1100  * Year : years since 1900. Negative value represents year below 1900. (
1101  * year value -30 represents 1870). Year default range is from 70 to 137.
1102  * Month default value range is from 0 to 11
1103  * Date default value range is from 1 to 31 according to the month value.
1104  * Hour default value will be in terms of 24 hr format (0~23)
1105  * Minute default value range will be from 0 to 59.
1106  * AM/PM. Value 0 for AM and 1 for PM.
1107  * If the value is beyond the range,
1108  * a) Value is less than Min range value, then Min range value is set.
1109  * b) Greater than Max range value, then Max Range value is set.
1110  * Both Min and Max range of individual fields are bound to the current context.
1111  *
1112  * @param[in] obj The datefield object
1113  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1114  * @param[in] value The minimum value of the field that is to be set.
1115  * @ingroup Datefield
1116  */
1117 EAPI void
1118 elm_datefield_item_min_set(Evas_Object *obj, Elm_Datefield_ItemType itemtype,
1119                            int value,  Eina_Bool abs_limit)
1120 {
1121    ELM_CHECK_WIDTYPE(obj, widtype);
1122    Widget_Data *wd;
1123    Datefield_Item *it;
1124
1125    wd = elm_widget_data_get(obj);
1126    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return;
1127
1128    it = wd->item_list + itemtype;
1129    if ( it->type != ELM_DATEFIELD_YEAR && value < it->default_min )
1130       it->min = it->default_min;
1131    else
1132       it->min = value;
1133
1134    if(it->min > it->max ) it->max = it->min;
1135    it->abs_min = abs_limit;
1136    _field_value_set(obj, it->type, *(it->value), EINA_FALSE);  // Trigger the validation
1137 }
1138
1139 /**
1140  * @brief Get lower boundary of the datefield
1141  * Year : years since 1900. Negative value represents year below 1900. (
1142  * year value -30 represents 1870). Year default range is from 70 to 137.
1143  * Year default range is from 70 to 137.
1144  * Month default value range is from 0 to 11
1145  * Date default value range is from 1 to 31 according to the month value.
1146  * Hour default value will be in terms of 24 hr format (0~23)
1147  * Minute default value range will be from 0 to 59.
1148  * AM/PM. Value 0 for AM and 1 for PM.
1149  * If the value is beyond the range,
1150  * a) Value is less than Min range value, then Min range value is set.
1151  * b) Greater than Max range value, then Max Range value is set.
1152  * Both Min and Max range of individual fields are bound to the current context.
1153  *
1154  * @param[in] obj The datefield object
1155  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1156  * @return int The minimum value of the field.
1157  *
1158  * @ingroup Datepicker
1159  */
1160 EAPI int
1161 elm_datefield_item_min_get(const Evas_Object *obj, Elm_Datefield_ItemType
1162                            itemtype)
1163 {
1164    ELM_CHECK_WIDTYPE(obj, widtype) -1;
1165    Widget_Data *wd;
1166
1167    wd = elm_widget_data_get(obj);
1168    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return -1;
1169
1170    return ((wd->item_list + itemtype)->min);
1171 }
1172
1173 /**
1174  * @brief Get whether the minimum value of the item is absolute or not
1175  *
1176  * @param[in] obj The datefield object
1177  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1178  * @return EINA_TRUE = Minimim is absolute or EINA_FALSE = Minimum is relative.
1179  *
1180  * @ingroup Datefield
1181  */
1182
1183 EAPI Eina_Bool
1184 elm_datefield_item_min_is_absolute(const Evas_Object *obj,
1185                                    Elm_Datefield_ItemType itemtype)
1186 {
1187    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1188    Widget_Data *wd;
1189
1190    wd = elm_widget_data_get(obj);
1191    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return EINA_FALSE;
1192
1193    return ((wd->item_list + itemtype)->abs_min);
1194 }
1195
1196 /**
1197  * @brief Set upper boundary of the datefield
1198  * Year : years since 1900. Negative value represents year below 1900. (
1199  * year value -30 represents 1870). Year default range is from 70 to 137.
1200  * Month:default value range is from 0 to 11
1201  * Date : default value range is from 1 to 31 according to the month value.
1202  * Hour : default value will be in terms of 24 hr format (0~23)
1203  * Minute  : default value range will be from 0 to 59.
1204  * AM/PM: Value 0 for AM and 1 for PM.
1205  * If the value is beyond the contextual range,
1206  * a) Value is less than Min range value, then Min range value is set.
1207  * b) Greater than Max range value, then Max Range value is set.
1208  * Both Min and Max range of individual fields are bound to the current context.
1209  *
1210  * @param[in] obj The datefield object
1211  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1212  * @param[in] value The maximum field value that is to be set.
1213  *
1214  * @ingroup Datefield
1215  */
1216 EAPI void
1217 elm_datefield_item_max_set(Evas_Object *obj, Elm_Datefield_ItemType itemtype,
1218                            int value, Eina_Bool abs_limit )
1219 {
1220    ELM_CHECK_WIDTYPE(obj, widtype);
1221    Widget_Data *wd;
1222    Datefield_Item *it;
1223
1224    wd = elm_widget_data_get(obj);
1225    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return;
1226
1227    it = wd->item_list + itemtype;
1228    if (it->type != ELM_DATEFIELD_YEAR && value > it->default_max )
1229       it->max = it->default_max;
1230    else
1231       it->max = value;
1232
1233    if(it->max < it->min) it->min = it->max;
1234    it->abs_max = abs_limit;
1235
1236    _field_value_set(obj, it->type, *(it->value), EINA_FALSE);  // Trigger the validation
1237 }
1238
1239 /**
1240  * @brief Get upper boundary of the datefield
1241  * Year : years since 1900. Negative value represents year below 1900. (
1242  * year value -30 represents 1870). Year default range is from 70 to 137.
1243  * Month default value range is from 0 to 11
1244  * Date default value range is from 1 to 31 according to the month value.
1245  * Hour default value will be in terms of 24 hr format (0~23)
1246  * Minute default value range will be from 0 to 59.
1247  * AM/PM. Value 0 for AM and 1 for PM.
1248  * If the value is beyond the range,
1249  * a) Value is less than Min range value, then Min range value is set.
1250  * b) Greater than Max range value, then Max Range value is set.
1251  * Both Min and Max range of individual fields are bound to the current context.
1252  *
1253  * @param[in] obj The datefield object
1254  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1255  * @return int The maximum value of the field.
1256  *
1257  * @ingroup Datefield
1258  */
1259 EAPI int
1260 elm_datefield_item_max_get(const Evas_Object *obj, Elm_Datefield_ItemType
1261                            itemtype)
1262 {
1263    ELM_CHECK_WIDTYPE(obj, widtype) -1;
1264    Widget_Data *wd;
1265
1266    wd = elm_widget_data_get(obj);
1267    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return -1;
1268
1269    return ((wd->item_list + itemtype)->max);
1270 }
1271
1272 /**
1273  * @brief Get whether the max value of the item is absolute or not
1274  *
1275  * @param[in] obj The datefield object
1276  * @param[in] itemtype The field type of datefield. ELM_DATEFIELD_YEAR etc.
1277  * @return EINA_TRUE = Max is absolute or EINA_FALSE = Max is relative.
1278  *
1279  * @ingroup Datefield
1280  */
1281
1282 EAPI Eina_Bool
1283 elm_datefield_item_max_is_absolute(const Evas_Object *obj,
1284                                    Elm_Datefield_ItemType itemtype)
1285 {
1286    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1287    Widget_Data *wd;
1288
1289    wd = elm_widget_data_get(obj);
1290    if (!wd || itemtype > ELM_DATEFIELD_AMPM ) return EINA_FALSE;
1291
1292    return ((wd->item_list + itemtype)->abs_max);
1293 }
1294