1 #include <Elementary.h>
12 typedef struct _Widget_Data Widget_Data;
13 typedef struct _Datetime_Field Datetime_Field;
14 typedef struct _Datetime_Mod_Api Datetime_Mod_Api;
15 typedef struct _Format_Map Format_Map;
17 #define DATETIME_TYPE_COUNT 6
18 #define MAX_FORMAT_LEN 64
19 #define MAX_SEPARATOR_LEN 6
20 #define MAX_FIELD_FORMAT_LEN 3
21 #define MIN_DAYS_IN_MONTH 28
22 #define BUFFER_SIZE 1024
24 // interface between EDC & C code. Field names & signal names.
25 // values 0 to DATETIME_TYPE_COUNT are valid range, can be substituted for %d.
26 #define EDC_DATETIME_ENABLE_SIG_STR "elm,state,enabled"
27 #define EDC_DATETIME_DISABLE_SIG_STR "elm,state,disabled"
28 #define EDC_DATETIME_FOCUSIN_SIG_STR "elm,action,focus"
29 #define EDC_DATETIME_FOCUSOUT_SIG_STR "elm,action,unfocus"
30 #define EDC_PART_FIELD_STR "field%d"
31 #define EDC_PART_SEPARATOR_STR "separator%d"
32 #define EDC_PART_FIELD_ENABLE_SIG_STR "field%d,enable"
33 #define EDC_PART_FIELD_DISABLE_SIG_STR "field%d,disable"
35 // struct tm does not define the fields in the order from year, month, date, hour, minute.
36 // values are reassigned to an array for easy handling.
37 #define DATETIME_TM_ARRAY(intptr, tmptr) int *intptr[] = {&(tmptr)->tm_year, \
38 &(tmptr)->tm_mon, &(tmptr)->tm_mday, &(tmptr)->tm_hour, &(tmptr)->tm_min}
40 struct _Datetime_Field
42 Evas_Object *item_obj;
43 char fmt[MAX_FIELD_FORMAT_LEN];
44 Elm_Datetime_Field_Type type;
45 const char *separator;
46 int location; // location of the field as per the current format
48 Eina_Bool fmt_exist:1; // whether field format is present or not
49 Eina_Bool visible:1; // whether field can be visible or not
52 struct _Datetime_Mod_Api
54 Elm_Datetime_Module_Data *(*obj_hook) (Evas_Object *obj);
55 void (*obj_unhook) (Elm_Datetime_Module_Data *module_data);
56 Evas_Object *(*field_create) (Elm_Datetime_Module_Data *module_data,
57 Elm_Datetime_Field_Type field_type);
58 void (*field_value_display) (Elm_Datetime_Module_Data *module_data,
65 Datetime_Field field_list[DATETIME_TYPE_COUNT]; // fixed set of fields.
66 struct tm curr_time, min_limit, max_limit;
67 Elm_Datetime_Module_Data *mod_data;
68 char format[MAX_FORMAT_LEN];
69 Eina_Bool user_format:1; // whether user set format or default format.
80 // default limits for individual fields
81 static Format_Map mapping[DATETIME_TYPE_COUNT] = {
82 [ELM_DATETIME_YEAR] = { "Yy", -1, -1, "" },
83 [ELM_DATETIME_MONTH] = { "mbBh", 0, 11, "" },
84 [ELM_DATETIME_DATE] = { "de", 1, 31, "" },
85 [ELM_DATETIME_HOUR] = { "IHkl", 0, 23, "" },
86 [ELM_DATETIME_MINUTE] = { "M", 0, 59, ":" },
87 [ELM_DATETIME_AMPM] = { "pP", 0, 1, "" }
90 static const char *multifield_formats = "cxXrRTDF";
91 static const char *ignore_separators = "()";
93 static Datetime_Mod_Api *dt_mod = NULL;
94 static const char *widtype = NULL;
96 static void _del_hook(Evas_Object *obj);
97 static void _disable_hook(Evas_Object *obj);
98 static void _translate_hook(Evas_Object *obj);
99 static void _on_focus_hook(void *data __UNUSED__, Evas_Object *obj);
100 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
101 static void _sizing_eval(Evas_Object *obj);
102 static void _theme_hook(Evas_Object *obj);
103 static void _validate_datetime_limits(struct tm *time1, struct tm *time2, Eina_Bool swap);
104 static void _apply_field_limits(Evas_Object *obj);
105 static void _apply_range_restrictions(Evas_Object *obj, struct tm *time);
106 static const char *_field_format_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type);
107 static void _field_limit_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type,
108 int *range_min, int *range_max);
109 static void _reload_format(Evas_Object *obj);
110 static void _field_list_display(Evas_Object *obj);
111 static void _field_list_arrange(Evas_Object *obj);
112 static void _field_list_init(Evas_Object *obj);
114 static const char SIG_CHANGED[] = "changed";
115 static const char SIG_LANGUAGE_CHANGED[] = "language,changed";
116 static const Evas_Smart_Cb_Description _signals[] = {
118 {SIG_LANGUAGE_CHANGED, ""},
122 static Datetime_Mod_Api *
125 Elm_Module *mod = NULL;
126 if (!(mod = _elm_module_find_as("datetime/api"))) return NULL;
128 mod->api = malloc(sizeof(Datetime_Mod_Api));
129 if (!mod->api) return NULL;
131 ((Datetime_Mod_Api *)(mod->api))->obj_hook = _elm_module_symbol_get(mod, "obj_hook");
132 ((Datetime_Mod_Api *)(mod->api))->obj_unhook = _elm_module_symbol_get(mod, "obj_unhook");
133 ((Datetime_Mod_Api *)(mod->api))->field_create = _elm_module_symbol_get(mod, "field_create");
134 ((Datetime_Mod_Api *)(mod->api))->field_value_display = _elm_module_symbol_get(mod, "field_value_display");
140 _del_hook(Evas_Object *obj)
146 wd = elm_widget_data_get(obj);
149 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
151 tmp = wd->field_list + idx;
152 evas_object_del(tmp->item_obj);
153 eina_stringshare_del(tmp->separator);
156 if ((dt_mod) && (dt_mod->obj_unhook))
157 dt_mod->obj_unhook(wd->mod_data); // module - unhook
163 _disable_hook(Evas_Object *obj)
167 wd = elm_widget_data_get(obj);
168 if (!wd || !wd->base) return;
169 if (elm_widget_disabled_get(obj))
170 edje_object_signal_emit(wd->base, EDC_DATETIME_DISABLE_SIG_STR, "elm");
172 edje_object_signal_emit(wd->base, EDC_DATETIME_ENABLE_SIG_STR, "elm");
176 _translate_hook(Evas_Object *obj)
179 wd = elm_widget_data_get(obj);
182 if (!wd->user_format) _reload_format(obj);
183 else _field_list_display(obj);
184 evas_object_smart_callback_call(obj, SIG_LANGUAGE_CHANGED, NULL);
188 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
192 wd = elm_widget_data_get(obj);
195 if (elm_widget_focus_get(obj))
196 edje_object_signal_emit(wd->base, EDC_DATETIME_FOCUSIN_SIG_STR, "elm");
198 edje_object_signal_emit(wd->base, EDC_DATETIME_FOCUSOUT_SIG_STR, "elm");
202 _datetime_items_get(const Evas_Object *obj)
205 Eina_List *items = NULL;
206 Datetime_Field *field;
210 wd = elm_widget_data_get(obj);
211 if (!wd) return NULL;
213 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
215 field = wd->field_list + idx;
216 if (field->fmt_exist && field->visible) count++;
218 for (loc = 0; loc < count; loc++)
220 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
222 field = wd->field_list + idx;
223 if (field->location == loc)
224 items = eina_list_append(items, field->item_obj);
232 _elm_datetime_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
235 const Eina_List *items;
236 void *(*list_data_get) (const Eina_List *list);
237 Eina_List *(*list_free) (Eina_List *list);
240 wd = elm_widget_data_get(obj);
241 if (!wd) return EINA_FALSE;
243 if ((items = elm_widget_focus_custom_chain_get(obj)))
245 list_data_get = eina_list_data_get;
250 items = _datetime_items_get(obj);
251 list_data_get = eina_list_data_get;
252 list_free = eina_list_free;
253 if (!items) return EINA_FALSE;
256 ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
257 if (list_free) list_free((Eina_List *)items);
263 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
267 wd = elm_widget_data_get(obj);
270 edje_object_mirrored_set(wd->base, rtl);
274 _sizing_eval(Evas_Object *obj)
277 Datetime_Field *field;
278 Evas_Coord minw = -1, minh = -1;
279 unsigned int idx, field_count = 0;
281 wd = elm_widget_data_get(obj);
282 if (!wd || !wd->base) return;
283 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
285 field = wd->field_list + idx;
286 if ((field->visible) && (field->fmt_exist)) field_count ++;
289 elm_coords_finger_size_adjust(field_count, &minw, 1, &minh);
290 edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
291 evas_object_size_hint_min_set(obj, minw, minh);
292 evas_object_size_hint_max_set(obj, -1, -1);
296 _theme_hook(Evas_Object *obj)
299 Datetime_Field *field;
300 char buf[BUFFER_SIZE];
303 wd = elm_widget_data_get(obj);
304 if (!wd || !wd->base) return;
306 _elm_theme_object_set(obj, wd->base, "datetime", "base",
307 elm_widget_style_get(obj));
308 _elm_widget_mirrored_reload(obj);
309 _mirrored_set(obj, elm_widget_mirrored_get(obj));
311 edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
313 if (elm_widget_disabled_get(obj))
314 edje_object_signal_emit(wd->base, EDC_DATETIME_DISABLE_SIG_STR,"elm");
316 edje_object_signal_emit(wd->base, EDC_DATETIME_ENABLE_SIG_STR, "elm");
318 if ((!dt_mod) || (!dt_mod->field_value_display)) return;
320 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
322 field = wd->field_list + idx;
323 if (field->fmt_exist && field->visible)
325 snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR, field->location);
326 edje_object_signal_emit(wd->base, buf, "elm");
327 snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
328 edje_object_part_text_set(wd->base, buf, field->separator);
329 dt_mod->field_value_display(wd->mod_data, field->item_obj);
333 snprintf(buf, sizeof(buf),EDC_PART_FIELD_DISABLE_SIG_STR, field->location);
334 edje_object_signal_emit(wd->base, buf, "elm");
337 edje_object_message_signal_process(wd->base);
342 _max_days_get(int year, int month)
349 localtime_r(&t, &time1);
350 time1.tm_year = year;
351 time1.tm_mon = month;
352 for (day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max; day++)
356 if (time1.tm_mday == 1) break;
363 _date_cmp(struct tm *time1, struct tm *time2)
366 DATETIME_TM_ARRAY(timearr1, time1);
367 DATETIME_TM_ARRAY(timearr2, time2);
369 for (idx = 0; idx < DATETIME_TYPE_COUNT - 1; idx++)
371 if (*timearr1[idx] != *timearr2[idx])
377 // validates curr_time/min_limt/max_limit according to the newly set value
379 _validate_datetime_limits(struct tm *time1, struct tm *time2, Eina_Bool swap)
383 if (!time1 || !time2) return;
385 t1 = (swap) ? time2 : time1;
386 t2 = (swap) ? time1 : time2;
388 DATETIME_TM_ARRAY(timearr1, time1);
389 DATETIME_TM_ARRAY(timearr2, time2);
390 for (idx = 0; idx < DATETIME_TYPE_COUNT - 1; idx++)
392 if (*timearr1[idx] < *timearr2[idx])
394 memcpy(t1, t2, sizeof(struct tm));
397 else if (*timearr1[idx] > *timearr2[idx])
403 _apply_field_limits(Evas_Object *obj)
406 Datetime_Field *field;
408 unsigned int idx = 0;
410 wd = elm_widget_data_get(obj);
413 DATETIME_TM_ARRAY(timearr, &wd->curr_time);
414 for (idx = 0; idx < DATETIME_TYPE_COUNT - 1; idx++)
416 field = wd->field_list + idx;
418 if (val < field->min)
419 *timearr[idx] = field->min;
420 else if (val > field->max)
421 *timearr[idx] = field->max;
423 _field_list_display(obj);
427 _apply_range_restrictions(Evas_Object *obj, struct tm *tim)
433 wd = elm_widget_data_get(obj);
434 if (!wd || !tim) return;
436 DATETIME_TM_ARRAY(timearr, tim);
437 for (idx = ELM_DATETIME_MONTH; idx < DATETIME_TYPE_COUNT - 1; idx++)
440 min = mapping[idx].def_min;
441 max = mapping[idx].def_max;
442 if (idx == ELM_DATETIME_DATE)
443 max = _max_days_get(tim->tm_year, tim->tm_mon);
452 _field_format_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type)
455 Datetime_Field *field;
457 wd = elm_widget_data_get(obj);
458 if (!wd) return NULL;
460 field = wd->field_list + field_type;
461 if (!field) return NULL;
467 _field_limit_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type, int *range_min, int *range_max)
470 Datetime_Field *field;
471 int min, max, max_days;
474 wd = elm_widget_data_get(obj);
477 field = wd->field_list + field_type;
483 DATETIME_TM_ARRAY(curr_timearr, &wd->curr_time);
484 DATETIME_TM_ARRAY(min_timearr, &wd->min_limit);
485 DATETIME_TM_ARRAY(max_timearr, &wd->max_limit);
487 for (idx = 0; idx < field->type; idx++)
488 if (*curr_timearr[idx] > *min_timearr[idx]) break;
489 if ((idx == field_type) && (min < *min_timearr[field_type]))
490 min = *min_timearr[field_type];
491 if (field_type == ELM_DATETIME_DATE)
493 max_days = _max_days_get(wd->curr_time.tm_year, wd->curr_time.tm_mon);
494 if (max > max_days) max = max_days;
496 for (idx = 0; idx < field->type; idx++)
497 if (*curr_timearr[idx] < *max_timearr[idx]) break;
498 if ((idx == field_type) && (max > *max_timearr[field_type]))
499 max = *max_timearr[field_type];
506 _field_list_display(Evas_Object *obj)
509 Datetime_Field *field;
512 wd = elm_widget_data_get(obj);
515 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
517 field = wd->field_list + idx;
518 if (field->fmt_exist && field->visible)
520 if ((dt_mod) && (dt_mod->field_value_display))
521 dt_mod->field_value_display(wd->mod_data, field->item_obj);
527 _field_list_arrange(Evas_Object *obj)
530 Datetime_Field *field;
531 char buf[BUFFER_SIZE];
534 wd = elm_widget_data_get(obj);
537 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
539 field = wd->field_list + idx;
540 edje_object_part_unswallow(wd->base, field->item_obj);
542 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
544 field = wd->field_list + idx;
545 if (field->visible && field->fmt_exist)
547 snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location);
548 edje_object_part_swallow(wd->base, buf, field->item_obj);
550 else evas_object_hide(field->item_obj);
553 _field_list_display(obj);
556 // FIXME: provide nl_langinfo on Windows if possible
557 // returns expanded format string for corresponding multi-field format character
559 _expanded_fmt_str_get(char ch)
565 #ifdef HAVE_LANGINFO_H
566 exp_fmt = nl_langinfo(D_T_FMT);
572 #ifdef HAVE_LANGINFO_H
573 exp_fmt = nl_langinfo(D_FMT);
579 #ifdef HAVE_LANGINFO_H
580 exp_fmt = nl_langinfo(T_FMT);
586 #ifdef HAVE_LANGINFO_H
587 exp_fmt = nl_langinfo(T_FMT_AMPM);
596 exp_fmt = "%H:%M:%S";
599 exp_fmt = "%m/%d/%y";
602 exp_fmt = "%Y-%m-%d";
612 _expand_format(char * dt_fmt)
614 char *ptr, *expanded_fmt, ch;
615 char buf[MAX_FORMAT_LEN] = {0,};
616 unsigned int idx = 0, len = 0;
617 Eina_Bool fmt_char = EINA_FALSE;
622 if ((fmt_char) && (strchr(multifield_formats, ch)))
624 // replace the multi-field format characters with corresponding expanded format
625 expanded_fmt = _expanded_fmt_str_get(ch);
626 len = strlen(expanded_fmt);
628 strncat(buf, expanded_fmt, len);
631 else buf[idx++] = ch;
632 if (ch == '%') fmt_char = EINA_TRUE;
633 else fmt_char = EINA_FALSE;
637 strncpy(dt_fmt, buf, MAX_FORMAT_LEN);
641 _parse_format(Evas_Object *obj, char *fmt_ptr)
644 Datetime_Field *field = NULL;
645 unsigned int len = 0, idx = 0, location = 0;
646 char separator[MAX_SEPARATOR_LEN];
648 Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE,
649 sep_lookup = EINA_FALSE;
651 wd = elm_widget_data_get(obj);
653 while ((cur = *fmt_ptr))
657 fmt_parsing = EINA_FALSE;
658 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
660 if (strchr(mapping[idx].fmt_char, cur))
662 field = wd->field_list + idx;
663 // ignore the fields already have or disabled
664 // valid formats, means already parsed & repeated, ignore.
665 if (!field->visible || field->location != -1) break;
667 field->fmt_exist = EINA_TRUE;
668 field->location = location++;
669 sep_lookup = EINA_TRUE;
677 fmt_parsing = EINA_TRUE;
678 sep_parsing = EINA_FALSE;
679 // set the separator to previous field
681 if (field) eina_stringshare_replace(&field->separator, separator);
684 // ignore the set of chars (global, field specific) as field separators.
685 if (sep_parsing && (len < MAX_SEPARATOR_LEN - 1) &&
686 (field->type != ELM_DATETIME_AMPM) && (!strchr(ignore_separators, cur)) &&
687 (!strchr(mapping[idx].ignore_sep, cur)))
688 separator[len++] = cur;
689 if (sep_lookup) sep_parsing = EINA_TRUE;
690 sep_lookup = EINA_FALSE;
693 // return the number of valid fields parsed.
698 _reload_format(Evas_Object *obj)
701 Datetime_Field *field;
702 char buf[BUFFER_SIZE];
703 unsigned int idx, field_count;
706 wd = elm_widget_data_get(obj);
709 // FIXME: provide nl_langinfo on Windows if possible
710 // fetch the default format from Libc.
711 if (!wd->user_format)
712 #ifdef HAVE_LANGINFO_H
713 strncpy(wd->format, nl_langinfo(D_T_FMT), MAX_FORMAT_LEN);
715 strncpy(wd->format, "", MAX_FORMAT_LEN);
718 dt_fmt = (char *)malloc(MAX_FORMAT_LEN);
720 strncpy(dt_fmt, wd->format, MAX_FORMAT_LEN);
722 _expand_format(dt_fmt);
724 // reset all the fields to disable state
725 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
727 field = wd->field_list + idx;
728 field->fmt_exist = EINA_FALSE;
729 field->location = -1;
732 field_count = _parse_format(obj, dt_fmt);
735 // assign locations to disabled fields for uniform usage
736 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
738 field = wd->field_list + idx;
739 if (field->location == -1) field->location = field_count++;
741 if (field->fmt_exist && field->visible)
743 snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
745 edje_object_signal_emit(wd->base, buf, "elm");
749 snprintf(buf, sizeof(buf),EDC_PART_FIELD_DISABLE_SIG_STR,
751 edje_object_signal_emit(wd->base, buf, "elm");
753 snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, (field->location + 1));
754 edje_object_part_text_set(wd->base, buf, field->separator);
756 edje_object_message_signal_process(wd->base);
757 _field_list_arrange(obj);
761 _field_list_init(Evas_Object *obj)
764 Datetime_Field *field;
768 wd = elm_widget_data_get(obj);
772 localtime_r(&t, &wd->curr_time);
774 mapping[ELM_DATETIME_YEAR].def_min = _elm_config->year_min;
775 mapping[ELM_DATETIME_YEAR].def_max = _elm_config->year_max;
776 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
778 field = wd->field_list + idx;
779 field->type = ELM_DATETIME_YEAR + idx;
781 field->fmt_exist = EINA_FALSE;
782 field->visible = EINA_TRUE;
783 field->min = mapping[idx].def_min;
784 field->max = mapping[idx].def_max;
786 DATETIME_TM_ARRAY(min_timearr, &wd->min_limit);
787 DATETIME_TM_ARRAY(max_timearr, &wd->max_limit);
788 for (idx = 0; idx < DATETIME_TYPE_COUNT-1; idx++)
790 *min_timearr[idx] = mapping[idx].def_min;
791 *max_timearr[idx] = mapping[idx].def_max;
796 elm_datetime_add(Evas_Object *parent)
801 Datetime_Field *field;
804 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
806 ELM_SET_WIDTYPE(widtype, "datetime");
807 elm_widget_type_set(obj, widtype);
808 elm_widget_sub_object_add(parent, obj);
809 elm_widget_data_set(obj, wd);
810 elm_widget_del_hook_set(obj, _del_hook);
811 elm_widget_theme_hook_set(obj, _theme_hook);
812 elm_widget_translate_hook_set(obj, _translate_hook);
813 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
814 elm_widget_disable_hook_set(obj, _disable_hook);
815 elm_widget_can_focus_set(obj, EINA_TRUE);
816 elm_widget_focus_next_hook_set(obj, _elm_datetime_focus_next_hook);
818 wd->base = edje_object_add(e);
819 elm_widget_resize_object_set(obj, wd->base);
820 _elm_theme_object_set(obj, wd->base, "datetime", "base", "default");
821 evas_object_smart_callbacks_descriptions_set(obj, _signals);
823 // module - initialise module for datetime
824 if (!dt_mod) dt_mod = _dt_mod_init();
825 if ((dt_mod) && (dt_mod->obj_hook))
826 wd->mod_data = dt_mod->obj_hook(obj);
827 // update module data
830 wd->mod_data->base = obj;
831 wd->mod_data->field_limit_get = _field_limit_get;
832 wd->mod_data->field_format_get = _field_format_get;
835 _field_list_init(obj);
838 if ((dt_mod)&&(dt_mod->field_create))
840 for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
842 field = wd->field_list + idx;
843 field->item_obj = dt_mod->field_create(wd->mod_data, idx);
846 _field_list_arrange(obj);
847 _mirrored_set(obj, elm_widget_mirrored_get(obj));
853 elm_datetime_format_get(const Evas_Object *obj)
855 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
858 wd = elm_widget_data_get(obj);
859 if (!wd) return NULL;
865 elm_datetime_format_set(Evas_Object *obj, const char *fmt)
867 ELM_CHECK_WIDTYPE(obj, widtype);
870 wd = elm_widget_data_get(obj);
875 strncpy(wd->format, fmt, MAX_FORMAT_LEN);
876 wd->user_format = EINA_TRUE;
879 wd->user_format = EINA_FALSE;
885 elm_datetime_field_visible_get(const Evas_Object *obj, Elm_Datetime_Field_Type
888 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
890 Datetime_Field *field;
892 wd = elm_widget_data_get(obj);
893 if (!wd || (fieldtype > ELM_DATETIME_AMPM)) return EINA_FALSE;
895 field = wd->field_list + fieldtype;
896 return field->visible;
900 elm_datetime_field_visible_set(Evas_Object *obj, Elm_Datetime_Field_Type fieldtype,
903 ELM_CHECK_WIDTYPE(obj, widtype);
905 Datetime_Field *field;
907 wd = elm_widget_data_get(obj);
908 if (!wd || (fieldtype > ELM_DATETIME_AMPM)) return;
910 field = wd->field_list + fieldtype;
911 if (field->visible == visible) return;
913 field->visible = visible;
918 elm_datetime_field_limit_get(const Evas_Object *obj, Elm_Datetime_Field_Type fieldtype,
921 ELM_CHECK_WIDTYPE(obj, widtype);
923 Datetime_Field *field;
925 wd = elm_widget_data_get(obj);
926 if (!wd || (fieldtype >= ELM_DATETIME_AMPM)) return;
928 field = wd->field_list + fieldtype;
929 if (min) *min = field->min;
930 if (max) *max = field->max;
934 elm_datetime_field_limit_set(Evas_Object *obj, Elm_Datetime_Field_Type fieldtype,
937 ELM_CHECK_WIDTYPE(obj, widtype);
939 Datetime_Field *field;
941 wd = elm_widget_data_get(obj);
942 if (!wd || (fieldtype >= ELM_DATETIME_AMPM)) return;
944 if (min > max) return;
946 field = wd->field_list + fieldtype;
947 if ((min > mapping[fieldtype].def_min && min < mapping[fieldtype].def_max)
948 || (field->type == ELM_DATETIME_YEAR))
950 if ((max > mapping[fieldtype].def_min && max < mapping[fieldtype].def_max)
951 || (field->type == ELM_DATETIME_YEAR))
954 _apply_field_limits(obj);
958 elm_datetime_value_get(const Evas_Object *obj, struct tm *currtime)
960 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
961 EINA_SAFETY_ON_NULL_RETURN_VAL(currtime, EINA_FALSE);
964 wd = elm_widget_data_get(obj);
965 if (!wd) return EINA_FALSE;
967 *currtime = wd->curr_time;
972 elm_datetime_value_set(Evas_Object *obj, const struct tm *newtime)
974 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
975 EINA_SAFETY_ON_NULL_RETURN_VAL(newtime, EINA_FALSE);
979 wd = elm_widget_data_get(obj);
980 if (!wd) return EINA_FALSE;
982 old_time = wd->curr_time;
983 wd->curr_time = *newtime;
984 // apply default field restrictions for curr_time
985 _apply_range_restrictions(obj, &wd->curr_time);
986 // validate the curr_time according to the min_limt and max_limt
987 _validate_datetime_limits(&wd->curr_time, &wd->min_limit, EINA_FALSE);
988 _validate_datetime_limits(&wd->max_limit, &wd->curr_time, EINA_TRUE);
989 _apply_field_limits(obj);
991 if (!_date_cmp(&old_time, &wd->curr_time))
992 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
998 elm_datetime_value_min_get(const Evas_Object *obj, struct tm *mintime)
1000 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1001 EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
1004 wd = elm_widget_data_get(obj);
1005 if (!wd) return EINA_FALSE;
1007 *mintime = wd->min_limit;
1012 elm_datetime_value_min_set(Evas_Object *obj, const struct tm *mintime)
1014 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1015 EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
1019 wd = elm_widget_data_get(obj);
1020 if (!wd) return EINA_FALSE;
1022 wd->min_limit = *mintime;
1023 old_time = wd->curr_time;
1024 // apply default field restrictions for min_limit
1025 _apply_range_restrictions(obj, &wd->min_limit);
1026 // validate curr_time and max_limt according to the min_limit
1027 _validate_datetime_limits(&wd->max_limit, &wd->min_limit, EINA_FALSE);
1028 _validate_datetime_limits(&wd->curr_time, &wd->min_limit, EINA_FALSE);
1029 _apply_field_limits(obj);
1031 if (!_date_cmp(&old_time, &wd->curr_time))
1032 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
1038 elm_datetime_value_max_get(const Evas_Object *obj, struct tm *maxtime)
1040 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1041 EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
1044 wd = elm_widget_data_get(obj);
1045 if (!wd) return EINA_FALSE;
1047 *maxtime = wd->max_limit;
1052 elm_datetime_value_max_set(Evas_Object *obj, const struct tm *maxtime)
1054 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1055 EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
1059 wd = elm_widget_data_get(obj);
1060 if (!wd) return EINA_FALSE;
1062 wd->max_limit = *maxtime;
1063 old_time = wd->curr_time;
1064 // apply default field restrictions for max_limit
1065 _apply_range_restrictions(obj, &wd->max_limit);
1066 // validate curr_time and min_limt according to the max_limit
1067 _validate_datetime_limits(&wd->max_limit, &wd->min_limit, EINA_TRUE);
1068 _validate_datetime_limits(&wd->max_limit, &wd->curr_time, EINA_TRUE);
1069 _apply_field_limits(obj);
1071 if (!_date_cmp(&old_time, &wd->curr_time))
1072 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);