1 #include <Elementary.h>
3 #include "elm_widget_datetime.h"
10 # include <langinfo.h>
13 EAPI const char ELM_DATETIME_SMART_NAME[] = "elm_datetime";
15 #define MAX_SEPARATOR_LEN 6
16 #define MIN_DAYS_IN_MONTH 28
17 #define BUFFER_SIZE 1024
19 /* interface between EDC & C code (field & signal names). values 0 to
20 * ELM_DATETIME_TYPE_COUNT are in the valid range, and must get in the
23 #define EDC_DATETIME_FOCUSIN_SIG_STR "elm,action,focus"
24 #define EDC_DATETIME_FOCUSOUT_SIG_STR "elm,action,unfocus"
25 #define EDC_PART_FIELD_STR "field%d"
26 #define EDC_PART_SEPARATOR_STR "separator%d"
27 #define EDC_PART_FIELD_ENABLE_SIG_STR "field%d,enable"
28 #define EDC_PART_FIELD_DISABLE_SIG_STR "field%d,disable"
29 #define EDC_PART_FIELD_SEPARATOR_ENABLE_SIG_STR "field%d,separator,enable"
30 #define EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR "field%d,separator,disable"
32 /* struct tm does not define the fields in the order year, month,
33 * date, hour, minute. values are reassigned to an array for easy
36 #define DATETIME_TM_ARRAY(intptr, tmptr) \
44 // default limits for individual fields
45 static Format_Map mapping[ELM_DATETIME_TYPE_COUNT] = {
46 [ELM_DATETIME_YEAR] = { "Yy", -1, -1, "" },
47 [ELM_DATETIME_MONTH] = { "mbBh", 0, 11, "" },
48 [ELM_DATETIME_DATE] = { "de", 1, 31, "" },
49 [ELM_DATETIME_HOUR] = { "IHkl", 0, 23, "" },
50 [ELM_DATETIME_MINUTE] = { "M", 0, 59, ":" },
51 [ELM_DATETIME_AMPM] = { "pP", 0, 1, "" }
54 static const char *multifield_formats = "cxXrRTDF";
55 static const char *ignore_separators = "() ";
56 static Datetime_Mod_Api *dt_mod = NULL;
58 static const char SIG_CHANGED[] = "changed";
59 static const char SIG_LANGUAGE_CHANGED[] = "language,changed";
60 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
62 {SIG_LANGUAGE_CHANGED, ""},
66 EVAS_SMART_SUBCLASS_NEW
67 (ELM_DATETIME_SMART_NAME, _elm_datetime, Elm_Datetime_Smart_Class,
68 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
70 static Datetime_Mod_Api *
73 Elm_Module *mod = NULL;
75 if (!(mod = _elm_module_find_as("datetime/api"))) return NULL;
77 mod->api = malloc(sizeof(Datetime_Mod_Api));
78 if (!mod->api) return NULL;
80 ((Datetime_Mod_Api *)(mod->api))->obj_hook =
81 _elm_module_symbol_get(mod, "obj_hook");
82 ((Datetime_Mod_Api *)(mod->api))->obj_unhook =
83 _elm_module_symbol_get(mod, "obj_unhook");
84 ((Datetime_Mod_Api *)(mod->api))->obj_theme_hook =
85 _elm_module_symbol_get(mod, "obj_theme_hook");
86 ((Datetime_Mod_Api *)(mod->api))->obj_format_hook =
87 _elm_module_symbol_get(mod, "obj_format_hook");
88 ((Datetime_Mod_Api *)(mod->api))->obj_focus_hook =
89 _elm_module_symbol_get(mod, "obj_focus_hook");
90 ((Datetime_Mod_Api *)(mod->api))->focus_object_list_get =
91 _elm_module_symbol_get(mod, "focus_object_list_get");
92 ((Datetime_Mod_Api *)(mod->api))->access_register =
93 _elm_module_symbol_get(mod, "access_register");
94 ((Datetime_Mod_Api *)(mod->api))->create_fields =
95 _elm_module_symbol_get(mod, "create_fields");
96 ((Datetime_Mod_Api *)(mod->api))->display_fields =
97 _elm_module_symbol_get(mod, "display_fields");
102 // FIXME: provide nl_langinfo on Windows if possible
103 // returns expanded format string for corresponding multi-field format character
105 _expanded_fmt_str_get(char ch)
111 #ifdef HAVE_LANGINFO_H
112 exp_fmt = nl_langinfo(D_T_FMT);
119 #ifdef HAVE_LANGINFO_H
120 exp_fmt = nl_langinfo(D_FMT);
127 #ifdef HAVE_LANGINFO_H
128 exp_fmt = nl_langinfo(T_FMT);
135 #ifdef HAVE_LANGINFO_H
136 exp_fmt = nl_langinfo(T_FMT_AMPM);
147 exp_fmt = "%H:%M:%S";
151 exp_fmt = "%m/%d/%y";
155 exp_fmt = "%Y-%m-%d";
167 _expand_format(char *dt_fmt)
169 char *ptr, *expanded_fmt, ch;
170 unsigned int idx = 0, len = 0;
171 char buf[ELM_DATETIME_MAX_FORMAT_LEN] = {0, };
172 Eina_Bool fmt_char = EINA_FALSE;
177 if ((fmt_char) && (strchr(multifield_formats, ch)))
179 /* replace the multi-field format characters with
180 * corresponding expanded format */
181 expanded_fmt = _expanded_fmt_str_get(ch);
182 len = strlen(expanded_fmt);
184 strncat(buf, expanded_fmt, len);
187 else buf[idx++] = ch;
189 if (ch == '%') fmt_char = EINA_TRUE;
190 else fmt_char = EINA_FALSE;
196 strncpy(dt_fmt, buf, ELM_DATETIME_MAX_FORMAT_LEN);
200 _parse_format(Evas_Object *obj,
203 Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE,
204 sep_lookup = EINA_FALSE;
205 unsigned int len = 0, idx = 0, location = 0;
206 char separator[MAX_SEPARATOR_LEN];
207 Datetime_Field *field = NULL;
210 ELM_DATETIME_DATA_GET(obj, sd);
212 while ((cur = *fmt_ptr))
216 /* some locales have format specifiers like %-d for Date.
217 * parse each field format as similar to LIBC snprintf() formatting */
218 if ((cur == ' ' || cur == '-'))
223 fmt_parsing = EINA_FALSE;
224 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
226 if (strchr(mapping[idx].fmt_char, cur))
228 field = sd->field_list + idx;
229 /* ignore the fields already have or disabled
230 * valid formats, means already parsed &
231 * repeated, ignore. */
232 if (field->location != -1) break;
234 field->fmt_exist = EINA_TRUE;
235 field->location = location++;
236 sep_lookup = EINA_TRUE;
244 fmt_parsing = EINA_TRUE;
245 sep_parsing = EINA_FALSE;
246 // set the separator to previous field
248 if (field) eina_stringshare_replace(&field->separator, separator);
250 // ignore the set of chars (global, field specific) as field separators
252 (len < MAX_SEPARATOR_LEN - 1) && field &&
253 (field->type != ELM_DATETIME_AMPM) &&
254 (!strchr(ignore_separators, cur)) &&
255 (!strchr(mapping[idx].ignore_sep, cur)))
256 separator[len++] = cur;
257 if (sep_lookup) sep_parsing = EINA_TRUE;
258 sep_lookup = EINA_FALSE;
262 //update the separator for last field
266 eina_stringshare_replace(&field->separator, separator);
269 // return the number of valid fields parsed.
274 _reload_format(Evas_Object *obj)
276 unsigned int idx, field_count;
277 Datetime_Field *field;
278 char buf[BUFFER_SIZE];
281 ELM_DATETIME_DATA_GET(obj, sd);
283 // FIXME: provide nl_langinfo on Windows if possible
284 // fetch the default format from Libc.
285 if (!sd->user_format)
286 #ifdef HAVE_LANGINFO_H
287 strncpy(sd->format, nl_langinfo(D_T_FMT), ELM_DATETIME_MAX_FORMAT_LEN);
289 strncpy(sd->format, "", ELM_DATETIME_MAX_FORMAT_LEN);
291 sd->format[ELM_DATETIME_MAX_FORMAT_LEN - 1] = '\0';
293 dt_fmt = (char *)malloc(ELM_DATETIME_MAX_FORMAT_LEN);
296 strncpy(dt_fmt, sd->format, ELM_DATETIME_MAX_FORMAT_LEN);
298 _expand_format(dt_fmt);
300 // reset all the fields to disable state
301 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
303 field = sd->field_list + idx;
304 field->fmt_exist = EINA_FALSE;
305 field->location = -1;
308 field_count = _parse_format(obj, dt_fmt);
311 // assign locations to disabled fields for uniform usage
312 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
314 field = sd->field_list + idx;
315 if (field->location == -1) field->location = field_count++;
317 if (field->fmt_exist && field->visible)
319 snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
321 elm_layout_signal_emit(obj, buf, "elm");
323 if (field->separator && strcmp(field->separator, ""))
325 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_ENABLE_SIG_STR,
327 elm_layout_signal_emit(obj, buf, "elm");
328 snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
329 elm_layout_text_set(obj, buf, field->separator);
333 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
335 elm_layout_signal_emit(obj, buf, "elm");
340 snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
342 elm_layout_signal_emit(obj, buf, "elm");
343 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
345 elm_layout_signal_emit(obj, buf, "elm");
349 if ((dt_mod) && (dt_mod->obj_format_hook))
350 dt_mod->obj_format_hook(sd->mod_data);
352 if ((dt_mod) && (dt_mod->display_fields))
353 dt_mod->display_fields(sd->mod_data);
357 _elm_datetime_smart_translate(Evas_Object *obj)
359 ELM_DATETIME_DATA_GET(obj, sd);
363 if ((dt_mod) && (dt_mod->display_fields))
364 dt_mod->display_fields(sd->mod_data);
369 evas_object_smart_callback_call(obj, SIG_LANGUAGE_CHANGED, NULL);
375 _datetime_items_get(const Evas_Object *obj)
377 Eina_List *items = NULL;
379 ELM_DATETIME_DATA_GET(obj, sd);
381 if ((dt_mod) && (dt_mod->focus_object_list_get))
382 items = dt_mod->focus_object_list_get(sd->mod_data);
388 _elm_datetime_smart_focus_next(const Evas_Object *obj,
389 Elm_Focus_Direction dir,
393 const Eina_List *items;
394 Eina_List *(*list_free)(Eina_List *list);
395 void *(*list_data_get)(const Eina_List *list);
397 if ((items = elm_widget_focus_custom_chain_get(obj)))
399 list_data_get = eina_list_data_get;
404 items = _datetime_items_get(obj);
405 list_data_get = eina_list_data_get;
406 list_free = eina_list_free;
407 if (!items) return EINA_FALSE;
410 ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
411 if (list_free) list_free((Eina_List *)items);
417 _elm_datetime_smart_on_focus(Evas_Object *obj)
419 ELM_DATETIME_DATA_GET(obj, sd);
421 if ((dt_mod) && (dt_mod->obj_focus_hook))
422 dt_mod->obj_focus_hook(sd->mod_data);
428 _elm_datetime_smart_sizing_eval(Evas_Object *obj)
430 Datetime_Field *field;
431 Evas_Coord minw = -1, minh = -1;
432 unsigned int idx, field_count = 0;
434 ELM_DATETIME_DATA_GET(obj, sd);
436 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
438 field = sd->field_list + idx;
439 if ((field->visible) && (field->fmt_exist)) field_count++;
442 elm_coords_finger_size_adjust(field_count, &minw, 1, &minh);
443 edje_object_size_min_restricted_calc
444 (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
445 evas_object_size_hint_min_set(obj, minw, minh);
446 evas_object_size_hint_max_set(obj, -1, -1);
450 _elm_datetime_smart_theme(Evas_Object *obj)
452 Datetime_Field *field;
453 char buf[BUFFER_SIZE];
456 ELM_DATETIME_DATA_GET(obj, sd);
458 if (!ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->theme(obj))
461 if (!dt_mod) return EINA_TRUE;
463 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
465 field = sd->field_list + idx;
466 if (field->fmt_exist && field->visible)
468 snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
470 elm_layout_signal_emit(obj, buf, "elm");
472 if (field->separator && strcmp(field->separator, ""))
474 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_ENABLE_SIG_STR,
476 elm_layout_signal_emit(obj, buf, "elm");
477 snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
478 elm_layout_text_set(obj, buf, field->separator);
482 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
484 elm_layout_signal_emit(obj, buf, "elm");
489 snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
491 elm_layout_signal_emit(obj, buf, "elm");
492 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
494 elm_layout_signal_emit(obj, buf, "elm");
497 elm_layout_sizing_eval(obj);
499 if (dt_mod->obj_theme_hook)
500 dt_mod->obj_theme_hook(sd->mod_data);
506 _max_days_get(int year,
514 localtime_r(&t, &time1);
515 time1.tm_year = year;
516 time1.tm_mon = month;
517 for (day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max;
521 /* FIXME: To restrict month wrapping because of summer time in some locales,
522 * ignore day light saving mode in mktime(). */
525 if (time1.tm_mday == 1) break;
532 _date_cmp(struct tm *time1,
537 DATETIME_TM_ARRAY(timearr1, time1);
538 DATETIME_TM_ARRAY(timearr2, time2);
540 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
542 if (*timearr1[idx] != *timearr2[idx])
549 // validates curr_time/min_limt/max_limit according to the newly set value
551 _validate_datetime_limits(struct tm *time1,
558 if (!time1 || !time2) return;
560 t1 = (swap) ? time2 : time1;
561 t2 = (swap) ? time1 : time2;
563 DATETIME_TM_ARRAY(timearr1, time1);
564 DATETIME_TM_ARRAY(timearr2, time2);
565 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
567 if (*timearr1[idx] < *timearr2[idx])
569 memcpy(t1, t2, sizeof(struct tm));
572 else if (*timearr1[idx] > *timearr2[idx])
578 _apply_field_limits(Evas_Object *obj)
580 Datetime_Field *field;
581 unsigned int idx = 0;
584 ELM_DATETIME_DATA_GET(obj, sd);
586 DATETIME_TM_ARRAY(timearr, &sd->curr_time);
587 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
589 field = sd->field_list + idx;
591 if (val < field->min)
592 *timearr[idx] = field->min;
593 else if (val > field->max)
594 *timearr[idx] = field->max;
597 if ((dt_mod) && (dt_mod->display_fields))
598 dt_mod->display_fields(sd->mod_data);
602 _apply_range_restrictions(struct tm *tim)
609 DATETIME_TM_ARRAY(timearr, tim);
610 for (idx = ELM_DATETIME_MONTH; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
613 min = mapping[idx].def_min;
614 max = mapping[idx].def_max;
615 if (idx == ELM_DATETIME_DATE)
616 max = _max_days_get(tim->tm_year, tim->tm_mon);
625 _field_format_get(Evas_Object *obj,
626 Elm_Datetime_Field_Type field_type)
628 Datetime_Field *field;
630 ELM_DATETIME_DATA_GET(obj, sd);
632 field = sd->field_list + field_type;
633 if (!field) return NULL;
639 _field_location_get(Evas_Object *obj, Elm_Datetime_Field_Type field_type,
642 Datetime_Field *field;
644 ELM_DATETIME_DATA_GET(obj, sd);
646 field = sd->field_list + field_type;
647 if (!field) return EINA_FALSE;
649 if (loc) *loc = field->location;
651 return (field->fmt_exist && field->visible);
655 _field_limit_get(Evas_Object *obj,
656 Elm_Datetime_Field_Type field_type,
660 int min, max, max_days;
661 Datetime_Field *field;
664 ELM_DATETIME_DATA_GET(obj, sd);
666 field = sd->field_list + field_type;
672 DATETIME_TM_ARRAY(curr_timearr, &sd->curr_time);
673 DATETIME_TM_ARRAY(min_timearr, &sd->min_limit);
674 DATETIME_TM_ARRAY(max_timearr, &sd->max_limit);
676 for (idx = 0; idx < field->type; idx++)
677 if (*curr_timearr[idx] > *min_timearr[idx]) break;
678 if ((idx == field_type) && (min < *min_timearr[field_type]))
679 min = *min_timearr[field_type];
680 if (field_type == ELM_DATETIME_DATE)
682 max_days = _max_days_get(sd->curr_time.tm_year, sd->curr_time.tm_mon);
683 if (max > max_days) max = max_days;
685 for (idx = 0; idx < field->type; idx++)
686 if (*curr_timearr[idx] < *max_timearr[idx]) break;
687 if ((idx == field_type) && (max > *max_timearr[field_type]))
688 max = *max_timearr[field_type];
695 _fields_min_max_get(Evas_Object *obj, struct tm *set_value,
696 struct tm *min_value, struct tm *max_value)
698 int min, max, max_days;
699 Datetime_Field *field;
702 ELM_DATETIME_DATA_GET(obj, sd);
704 if (!set_value || !min_value || !max_value) return;
706 DATETIME_TM_ARRAY(mod_set_timearr, set_value);
707 DATETIME_TM_ARRAY(mod_min_timearr, min_value);
708 DATETIME_TM_ARRAY(mod_max_timearr, max_value);
710 DATETIME_TM_ARRAY(min_timearr, &sd->min_limit);
711 DATETIME_TM_ARRAY(max_timearr, &sd->max_limit);
713 for (idx = 0; idx < ELM_DATETIME_AMPM; idx++)
715 field = sd->field_list + idx;
719 for (i = 0; i < idx; i++)
720 if (*mod_set_timearr[i] > *min_timearr[i]) break;
721 if ((i == idx) && (min < *min_timearr[idx]))
722 min = *min_timearr[idx];
724 if (idx == ELM_DATETIME_DATE)
726 max_days = _max_days_get(set_value->tm_year, set_value->tm_mon);
727 if (max > max_days) max = max_days;
729 for (i = 0; i < idx; i++)
730 if (*mod_set_timearr[i] < *max_timearr[i]) break;
731 if ((i == idx) && (max > *max_timearr[idx]))
732 max = *max_timearr[idx];
734 *mod_min_timearr[idx] = min;
735 *mod_max_timearr[idx] = max;
740 _field_list_init(Evas_Object *obj)
742 Datetime_Field *field;
746 ELM_DATETIME_DATA_GET(obj, sd);
749 localtime_r(&t, &sd->curr_time);
751 mapping[ELM_DATETIME_YEAR].def_min = _elm_config->year_min;
752 mapping[ELM_DATETIME_YEAR].def_max = _elm_config->year_max;
753 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
755 field = sd->field_list + idx;
756 field->type = ELM_DATETIME_YEAR + idx;
758 field->fmt_exist = EINA_FALSE;
759 field->visible = EINA_TRUE;
760 field->min = mapping[idx].def_min;
761 field->max = mapping[idx].def_max;
763 DATETIME_TM_ARRAY(min_timearr, &sd->min_limit);
764 DATETIME_TM_ARRAY(max_timearr, &sd->max_limit);
765 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
767 *min_timearr[idx] = mapping[idx].def_min;
768 *max_timearr[idx] = mapping[idx].def_max;
773 _elm_datetime_smart_add(Evas_Object *obj)
775 EVAS_SMART_DATA_ALLOC(obj, Elm_Datetime_Smart_Data);
777 ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->base.add(obj);
781 _elm_datetime_smart_del(Evas_Object *obj)
783 Datetime_Field *field;
786 ELM_DATETIME_DATA_GET(obj, sd);
788 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
790 field = sd->field_list + idx;
791 eina_stringshare_del(field->separator);
794 if ((dt_mod) && (dt_mod->obj_unhook))
795 dt_mod->obj_unhook(sd->mod_data);
797 ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->base.del(obj);
801 _elm_datetime_smart_set_user(Elm_Datetime_Smart_Class *sc)
803 ELM_WIDGET_CLASS(sc)->base.add = _elm_datetime_smart_add;
804 ELM_WIDGET_CLASS(sc)->base.del = _elm_datetime_smart_del;
805 ELM_WIDGET_CLASS(sc)->translate = _elm_datetime_smart_translate;
806 ELM_WIDGET_CLASS(sc)->focus_next = _elm_datetime_smart_focus_next;
807 ELM_WIDGET_CLASS(sc)->on_focus = _elm_datetime_smart_on_focus;
808 ELM_WIDGET_CLASS(sc)->theme = _elm_datetime_smart_theme;
809 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_datetime_smart_sizing_eval;
812 EAPI const Elm_Datetime_Smart_Class *
813 elm_datetime_smart_class_get(void)
815 static Elm_Datetime_Smart_Class _sc =
816 ELM_DATETIME_SMART_CLASS_INIT_NAME_VERSION(ELM_DATETIME_SMART_NAME);
817 static const Elm_Datetime_Smart_Class *class = NULL;
818 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
823 _elm_datetime_smart_set(&_sc);
824 esc->callbacks = _smart_callbacks;
831 elm_datetime_add(Evas_Object *parent)
835 Datetime_Field *field;
837 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
839 obj = elm_widget_add(_elm_datetime_smart_class_new(), parent);
840 if (!obj) return NULL;
842 if (!elm_widget_sub_object_add(parent, obj))
843 ERR("could not add %p as sub object of %p", obj, parent);
845 ELM_DATETIME_DATA_GET(obj, sd);
847 elm_layout_theme_set(obj, "datetime", "base", elm_widget_style_get(obj));
849 // module - initialise module for datetime
850 if (!dt_mod) dt_mod = _dt_mod_init();
852 if ((dt_mod) && (dt_mod->obj_hook))
853 sd->mod_data = dt_mod->obj_hook(obj);
855 // update module data
858 sd->mod_data->base = obj;
859 sd->mod_data->field_format_get = _field_format_get;
860 sd->mod_data->field_location_get = _field_location_get;
861 sd->mod_data->field_limit_get = _field_limit_get;
862 sd->mod_data->fields_min_max_get = _fields_min_max_get;
865 _field_list_init(obj);
868 if ((dt_mod) && (dt_mod->create_fields))
869 dt_mod->create_fields(sd->mod_data);
871 if ((dt_mod) && (dt_mod->display_fields))
872 dt_mod->display_fields(sd->mod_data);
874 if ((dt_mod) && (dt_mod->access_register))
875 dt_mod->access_register(sd->mod_data);
877 elm_widget_can_focus_set(obj, EINA_TRUE);
878 elm_layout_sizing_eval(obj);
884 elm_datetime_format_get(const Evas_Object *obj)
886 ELM_DATETIME_CHECK(obj) NULL;
887 ELM_DATETIME_DATA_GET(obj, sd);
893 elm_datetime_format_set(Evas_Object *obj,
896 ELM_DATETIME_CHECK(obj);
897 ELM_DATETIME_DATA_GET(obj, sd);
901 strncpy(sd->format, fmt, ELM_DATETIME_MAX_FORMAT_LEN);
902 sd->format[ELM_DATETIME_MAX_FORMAT_LEN - 1] = '\0';
903 sd->user_format = EINA_TRUE;
905 else sd->user_format = EINA_FALSE;
911 elm_datetime_field_visible_get(const Evas_Object *obj,
912 Elm_Datetime_Field_Type fieldtype)
914 Datetime_Field *field;
915 ELM_DATETIME_CHECK(obj) EINA_FALSE;
916 ELM_DATETIME_DATA_GET(obj, sd);
918 if (fieldtype > ELM_DATETIME_AMPM) return EINA_FALSE;
920 field = sd->field_list + fieldtype;
922 return field->visible;
926 elm_datetime_field_visible_set(Evas_Object *obj,
927 Elm_Datetime_Field_Type fieldtype,
930 Datetime_Field *field;
932 ELM_DATETIME_CHECK(obj);
933 ELM_DATETIME_DATA_GET(obj, sd);
935 if (fieldtype > ELM_DATETIME_AMPM) return;
937 field = sd->field_list + fieldtype;
938 if (field->visible == visible) return;
940 field->visible = visible;
945 elm_datetime_field_limit_get(const Evas_Object *obj,
946 Elm_Datetime_Field_Type fieldtype,
950 Datetime_Field *field;
952 ELM_DATETIME_CHECK(obj);
953 ELM_DATETIME_DATA_GET(obj, sd);
955 if (fieldtype >= ELM_DATETIME_AMPM) return;
957 field = sd->field_list + fieldtype;
958 if (min) *min = field->min;
959 if (max) *max = field->max;
963 elm_datetime_field_limit_set(Evas_Object *obj,
964 Elm_Datetime_Field_Type fieldtype,
968 Datetime_Field *field;
970 ELM_DATETIME_CHECK(obj);
971 ELM_DATETIME_DATA_GET(obj, sd);
973 if (fieldtype >= ELM_DATETIME_AMPM) return;
975 if (min > max) return;
977 field = sd->field_list + fieldtype;
978 if (((min >= mapping[fieldtype].def_min) &&
979 (min <= mapping[fieldtype].def_max)) ||
980 (field->type == ELM_DATETIME_YEAR))
982 if (((max >= mapping[fieldtype].def_min) &&
983 (max <= mapping[fieldtype].def_max)) ||
984 (field->type == ELM_DATETIME_YEAR))
987 _apply_field_limits(obj);
991 elm_datetime_value_get(const Evas_Object *obj,
994 ELM_DATETIME_CHECK(obj) EINA_FALSE;
995 EINA_SAFETY_ON_NULL_RETURN_VAL(currtime, EINA_FALSE);
996 ELM_DATETIME_DATA_GET(obj, sd);
998 *currtime = sd->curr_time;
1003 elm_datetime_value_set(Evas_Object *obj,
1004 const struct tm *newtime)
1008 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1009 EINA_SAFETY_ON_NULL_RETURN_VAL(newtime, EINA_FALSE);
1010 ELM_DATETIME_DATA_GET(obj, sd);
1012 old_time = sd->curr_time;
1013 sd->curr_time = *newtime;
1014 // apply default field restrictions for curr_time
1015 _apply_range_restrictions(&sd->curr_time);
1016 // validate the curr_time according to the min_limt and max_limt
1017 _validate_datetime_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE);
1018 _validate_datetime_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE);
1019 _apply_field_limits(obj);
1021 if (!_date_cmp(&old_time, &sd->curr_time))
1022 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
1028 elm_datetime_value_min_get(const Evas_Object *obj,
1031 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1032 EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
1033 ELM_DATETIME_DATA_GET(obj, sd);
1035 *mintime = sd->min_limit;
1040 elm_datetime_value_min_set(Evas_Object *obj,
1041 const struct tm *mintime)
1045 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1046 EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
1047 ELM_DATETIME_DATA_GET(obj, sd);
1049 sd->min_limit = *mintime;
1050 old_time = sd->curr_time;
1051 // apply default field restrictions for min_limit
1052 _apply_range_restrictions(&sd->min_limit);
1053 // validate curr_time and max_limt according to the min_limit
1054 _validate_datetime_limits(&sd->max_limit, &sd->min_limit, EINA_FALSE);
1055 _validate_datetime_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE);
1056 _apply_field_limits(obj);
1058 if (!_date_cmp(&old_time, &sd->curr_time))
1059 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
1065 elm_datetime_value_max_get(const Evas_Object *obj,
1068 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1069 EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
1070 ELM_DATETIME_DATA_GET(obj, sd);
1072 *maxtime = sd->max_limit;
1077 elm_datetime_value_max_set(Evas_Object *obj,
1078 const struct tm *maxtime)
1082 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1083 EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
1084 ELM_DATETIME_DATA_GET(obj, sd);
1086 sd->max_limit = *maxtime;
1087 old_time = sd->curr_time;
1088 // apply default field restrictions for max_limit
1089 _apply_range_restrictions(&sd->max_limit);
1090 // validate curr_time and min_limt according to the max_limit
1091 _validate_datetime_limits(&sd->max_limit, &sd->min_limit, EINA_TRUE);
1092 _validate_datetime_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE);
1093 _apply_field_limits(obj);
1095 if (!_date_cmp(&old_time, &sd->curr_time))
1096 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);