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_hide =
85 _elm_module_symbol_get(mod, "obj_hide");
86 ((Datetime_Mod_Api *)(mod->api))->field_create =
87 _elm_module_symbol_get(mod, "field_create");
88 ((Datetime_Mod_Api *)(mod->api))->field_value_display =
89 _elm_module_symbol_get(mod, "field_value_display");
95 _field_list_display(Evas_Object *obj)
97 Datetime_Field *field;
100 ELM_DATETIME_DATA_GET(obj, sd);
102 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
104 field = sd->field_list + idx;
105 if (field->fmt_exist && field->visible)
107 if ((dt_mod) && (dt_mod->field_value_display))
108 dt_mod->field_value_display(sd->mod_data, field->item_obj);
113 // FIXME: provide nl_langinfo on Windows if possible
114 // returns expanded format string for corresponding multi-field format character
116 _expanded_fmt_str_get(char ch)
122 #ifdef HAVE_LANGINFO_H
123 exp_fmt = nl_langinfo(D_T_FMT);
130 #ifdef HAVE_LANGINFO_H
131 exp_fmt = nl_langinfo(D_FMT);
138 #ifdef HAVE_LANGINFO_H
139 exp_fmt = nl_langinfo(T_FMT);
146 #ifdef HAVE_LANGINFO_H
147 exp_fmt = nl_langinfo(T_FMT_AMPM);
158 exp_fmt = "%H:%M:%S";
162 exp_fmt = "%m/%d/%y";
166 exp_fmt = "%Y-%m-%d";
178 _expand_format(char *dt_fmt)
180 char *ptr, *expanded_fmt, ch;
181 unsigned int idx = 0, len = 0;
182 char buf[ELM_DATETIME_MAX_FORMAT_LEN] = {0, };
183 Eina_Bool fmt_char = EINA_FALSE;
188 if ((fmt_char) && (strchr(multifield_formats, ch)))
190 /* replace the multi-field format characters with
191 * corresponding expanded format */
192 expanded_fmt = _expanded_fmt_str_get(ch);
193 len = strlen(expanded_fmt);
195 strncat(buf, expanded_fmt, len);
198 else buf[idx++] = ch;
200 if (ch == '%') fmt_char = EINA_TRUE;
201 else fmt_char = EINA_FALSE;
207 strncpy(dt_fmt, buf, ELM_DATETIME_MAX_FORMAT_LEN);
211 _field_list_arrange(Evas_Object *obj)
213 Datetime_Field *field;
214 char buf[BUFFER_SIZE];
217 ELM_DATETIME_DATA_GET(obj, sd);
219 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
221 field = sd->field_list + idx;
222 snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location);
223 evas_object_hide(elm_layout_content_unset(obj, buf));
226 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
228 field = sd->field_list + idx;
229 snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location);
230 if (field->visible && field->fmt_exist)
231 elm_layout_content_set(obj, buf, field->item_obj);
234 elm_layout_sizing_eval(obj);
235 _field_list_display(obj);
239 _parse_format(Evas_Object *obj,
242 Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE,
243 sep_lookup = EINA_FALSE;
244 unsigned int len = 0, idx = 0, location = 0;
245 char separator[MAX_SEPARATOR_LEN];
246 Datetime_Field *field = NULL;
249 ELM_DATETIME_DATA_GET(obj, sd);
251 while ((cur = *fmt_ptr))
255 fmt_parsing = EINA_FALSE;
256 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
258 if (strchr(mapping[idx].fmt_char, cur))
260 field = sd->field_list + idx;
261 /* ignore the fields already have or disabled
262 * valid formats, means already parsed &
263 * repeated, ignore. */
264 if (field->location != -1) break;
266 field->fmt_exist = EINA_TRUE;
267 field->location = location++;
268 sep_lookup = EINA_TRUE;
276 fmt_parsing = EINA_TRUE;
277 sep_parsing = EINA_FALSE;
278 // set the separator to previous field
280 if (field) eina_stringshare_replace(&field->separator, separator);
282 // ignore the set of chars (global, field specific) as field separators
284 (len < MAX_SEPARATOR_LEN - 1) &&
285 (field->type != ELM_DATETIME_AMPM) &&
286 (!strchr(ignore_separators, cur)) &&
287 (!strchr(mapping[idx].ignore_sep, cur)))
288 separator[len++] = cur;
289 if (sep_lookup) sep_parsing = EINA_TRUE;
290 sep_lookup = EINA_FALSE;
293 // return the number of valid fields parsed.
298 _reload_format(Evas_Object *obj)
300 unsigned int idx, field_count;
301 Datetime_Field *field;
302 char buf[BUFFER_SIZE];
305 ELM_DATETIME_DATA_GET(obj, sd);
307 // FIXME: provide nl_langinfo on Windows if possible
308 // fetch the default format from Libc.
309 if (!sd->user_format)
310 #ifdef HAVE_LANGINFO_H
311 strncpy(sd->format, nl_langinfo(D_T_FMT), ELM_DATETIME_MAX_FORMAT_LEN);
313 strncpy(sd->format, "", ELM_DATETIME_MAX_FORMAT_LEN);
315 sd->format[ELM_DATETIME_MAX_FORMAT_LEN - 1] = '\0';
317 dt_fmt = (char *)malloc(ELM_DATETIME_MAX_FORMAT_LEN);
320 strncpy(dt_fmt, sd->format, ELM_DATETIME_MAX_FORMAT_LEN);
322 _expand_format(dt_fmt);
324 // reset all the fields to disable state
325 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
327 field = sd->field_list + idx;
328 field->fmt_exist = EINA_FALSE;
329 field->location = -1;
332 field_count = _parse_format(obj, dt_fmt);
335 // assign locations to disabled fields for uniform usage
336 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
338 field = sd->field_list + idx;
339 if (field->location == -1) field->location = field_count++;
341 if (field->fmt_exist && field->visible)
343 snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
345 elm_layout_signal_emit(obj, buf, "elm");
347 if (field->separator && strcmp(field->separator, ""))
349 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_ENABLE_SIG_STR,
351 elm_layout_signal_emit(obj, buf, "elm");
352 snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
353 elm_layout_text_set(obj, buf, field->separator);
357 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
359 elm_layout_signal_emit(obj, buf, "elm");
364 snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
366 elm_layout_signal_emit(obj, buf, "elm");
367 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
369 elm_layout_signal_emit(obj, buf, "elm");
373 edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
374 _field_list_arrange(obj);
378 _elm_datetime_smart_translate(Evas_Object *obj)
380 ELM_DATETIME_DATA_GET(obj, sd);
382 if (!sd->user_format) _reload_format(obj);
383 else _field_list_display(obj);
385 evas_object_smart_callback_call(obj, SIG_LANGUAGE_CHANGED, NULL);
391 _datetime_items_get(const Evas_Object *obj)
393 Eina_List *items = NULL;
394 Datetime_Field *field;
397 Eina_Bool visible[ELM_DATETIME_TYPE_COUNT];
399 ELM_DATETIME_DATA_GET(obj, sd);
401 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
403 field = sd->field_list + idx;
404 if (field->fmt_exist && field->visible) visible[idx] = EINA_TRUE;
405 else visible[idx] = EINA_FALSE;
407 for (loc = 0; loc < ELM_DATETIME_TYPE_COUNT; loc++)
409 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
411 field = sd->field_list + idx;
412 if ((field->location == loc) && (visible[idx]))
413 items = eina_list_append(items, field->item_obj);
418 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
419 items = eina_list_append(items, sd->access_obj);
425 _elm_datetime_smart_focus_next(const Evas_Object *obj,
426 Elm_Focus_Direction dir,
430 const Eina_List *items;
431 Eina_List *(*list_free)(Eina_List *list);
432 void *(*list_data_get)(const Eina_List *list);
434 if ((items = elm_widget_focus_custom_chain_get(obj)))
436 list_data_get = eina_list_data_get;
441 items = _datetime_items_get(obj);
442 list_data_get = eina_list_data_get;
443 list_free = eina_list_free;
444 if (!items) return EINA_FALSE;
446 printf("count = %d\n", eina_list_count(items));
447 ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
448 if (list_free) list_free((Eina_List *)items);
454 _elm_datetime_smart_on_focus(Evas_Object *obj)
456 if (!elm_widget_focus_get(obj))
458 ELM_DATETIME_DATA_GET(obj, sd);
460 if ((dt_mod) && (dt_mod->obj_hide))
461 dt_mod->obj_hide(sd->mod_data);
468 _elm_datetime_smart_sizing_eval(Evas_Object *obj)
470 Datetime_Field *field;
471 Evas_Coord minw = -1, minh = -1;
472 unsigned int idx, field_count = 0;
474 ELM_DATETIME_DATA_GET(obj, sd);
476 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
478 field = sd->field_list + idx;
479 if ((field->visible) && (field->fmt_exist)) field_count++;
482 elm_coords_finger_size_adjust(field_count, &minw, 1, &minh);
483 edje_object_size_min_restricted_calc
484 (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
485 evas_object_size_hint_min_set(obj, minw, minh);
486 evas_object_size_hint_max_set(obj, -1, -1);
490 _elm_datetime_smart_theme(Evas_Object *obj)
492 Datetime_Field *field;
493 char buf[BUFFER_SIZE];
496 ELM_DATETIME_DATA_GET(obj, sd);
498 if (!ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->theme(obj))
501 if ((!dt_mod) || (!dt_mod->field_value_display)) return EINA_TRUE;
503 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
505 field = sd->field_list + idx;
506 if (field->fmt_exist && field->visible)
508 snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
510 elm_layout_signal_emit(obj, buf, "elm");
512 dt_mod->field_value_display(sd->mod_data, field->item_obj);
514 if (field->separator && strcmp(field->separator, ""))
516 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_ENABLE_SIG_STR,
518 elm_layout_signal_emit(obj, buf, "elm");
519 snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
520 elm_layout_text_set(obj, buf, field->separator);
524 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
526 elm_layout_signal_emit(obj, buf, "elm");
531 snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
533 elm_layout_signal_emit(obj, buf, "elm");
534 snprintf(buf, sizeof(buf), EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR,
536 elm_layout_signal_emit(obj, buf, "elm");
540 edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
541 elm_layout_sizing_eval(obj);
547 _max_days_get(int year,
555 localtime_r(&t, &time1);
556 time1.tm_year = year;
557 time1.tm_mon = month;
558 for (day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max;
563 if (time1.tm_mday == 1) break;
571 _date_cmp(struct tm *time1,
576 DATETIME_TM_ARRAY(timearr1, time1);
577 DATETIME_TM_ARRAY(timearr2, time2);
579 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
581 if (*timearr1[idx] != *timearr2[idx])
588 // validates curr_time/min_limt/max_limit according to the newly set value
590 _validate_datetime_limits(struct tm *time1,
597 if (!time1 || !time2) return;
599 t1 = (swap) ? time2 : time1;
600 t2 = (swap) ? time1 : time2;
602 DATETIME_TM_ARRAY(timearr1, time1);
603 DATETIME_TM_ARRAY(timearr2, time2);
604 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
606 if (*timearr1[idx] < *timearr2[idx])
608 memcpy(t1, t2, sizeof(struct tm));
611 else if (*timearr1[idx] > *timearr2[idx])
617 _apply_field_limits(Evas_Object *obj)
619 Datetime_Field *field;
620 unsigned int idx = 0;
623 ELM_DATETIME_DATA_GET(obj, sd);
625 DATETIME_TM_ARRAY(timearr, &sd->curr_time);
626 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
628 field = sd->field_list + idx;
630 if (val < field->min)
631 *timearr[idx] = field->min;
632 else if (val > field->max)
633 *timearr[idx] = field->max;
636 _field_list_display(obj);
640 _apply_range_restrictions(struct tm *tim)
647 DATETIME_TM_ARRAY(timearr, tim);
648 for (idx = ELM_DATETIME_MONTH; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
651 min = mapping[idx].def_min;
652 max = mapping[idx].def_max;
653 if (idx == ELM_DATETIME_DATE)
654 max = _max_days_get(tim->tm_year, tim->tm_mon);
663 _field_format_get(Evas_Object *obj,
664 Elm_Datetime_Field_Type field_type)
666 Datetime_Field *field;
668 ELM_DATETIME_DATA_GET(obj, sd);
670 field = sd->field_list + field_type;
671 if (!field) return NULL;
677 _field_limit_get(Evas_Object *obj,
678 Elm_Datetime_Field_Type field_type,
682 int min, max, max_days;
683 Datetime_Field *field;
686 ELM_DATETIME_DATA_GET(obj, sd);
688 field = sd->field_list + field_type;
694 DATETIME_TM_ARRAY(curr_timearr, &sd->curr_time);
695 DATETIME_TM_ARRAY(min_timearr, &sd->min_limit);
696 DATETIME_TM_ARRAY(max_timearr, &sd->max_limit);
698 for (idx = 0; idx < field->type; idx++)
699 if (*curr_timearr[idx] > *min_timearr[idx]) break;
700 if ((idx == field_type) && (min < *min_timearr[field_type]))
701 min = *min_timearr[field_type];
702 if (field_type == ELM_DATETIME_DATE)
704 max_days = _max_days_get(sd->curr_time.tm_year, sd->curr_time.tm_mon);
705 if (max > max_days) max = max_days;
707 for (idx = 0; idx < field->type; idx++)
708 if (*curr_timearr[idx] < *max_timearr[idx]) break;
709 if ((idx == field_type) && (max > *max_timearr[field_type]))
710 max = *max_timearr[field_type];
717 _field_list_init(Evas_Object *obj)
719 Datetime_Field *field;
723 ELM_DATETIME_DATA_GET(obj, sd);
726 localtime_r(&t, &sd->curr_time);
728 mapping[ELM_DATETIME_YEAR].def_min = _elm_config->year_min;
729 mapping[ELM_DATETIME_YEAR].def_max = _elm_config->year_max;
730 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
732 field = sd->field_list + idx;
733 field->type = ELM_DATETIME_YEAR + idx;
735 field->fmt_exist = EINA_FALSE;
736 field->visible = EINA_TRUE;
737 field->min = mapping[idx].def_min;
738 field->max = mapping[idx].def_max;
740 DATETIME_TM_ARRAY(min_timearr, &sd->min_limit);
741 DATETIME_TM_ARRAY(max_timearr, &sd->max_limit);
742 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT - 1; idx++)
744 *min_timearr[idx] = mapping[idx].def_min;
745 *max_timearr[idx] = mapping[idx].def_max;
750 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
754 buf = eina_strbuf_new();
756 ELM_DATETIME_DATA_GET(data, sd);
757 eina_strbuf_append_printf(buf,
758 "%d year, %d month, %d date, %d hour, %d minute",
759 sd->curr_time.tm_year, sd->curr_time.tm_mon + 1,
760 sd->curr_time.tm_mday, sd->curr_time.tm_hour,
761 sd->curr_time.tm_min);
763 ret = eina_strbuf_string_steal(buf);
764 eina_strbuf_free(buf);
769 _elm_datetime_smart_add(Evas_Object *obj)
772 Datetime_Field *field;
774 EVAS_SMART_DATA_ALLOC(obj, Elm_Datetime_Smart_Data);
776 ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->base.add(obj);
778 elm_layout_theme_set(obj, "datetime", "base", elm_widget_style_get(obj));
780 // module - initialise module for datetime
781 if (!dt_mod) dt_mod = _dt_mod_init();
782 if ((dt_mod) && (dt_mod->obj_hook)) priv->mod_data = dt_mod->obj_hook(obj);
784 // update module data
787 priv->mod_data->base = obj;
788 priv->mod_data->field_limit_get = _field_limit_get;
789 priv->mod_data->field_format_get = _field_format_get;
792 _field_list_init(obj);
795 if ((dt_mod) && (dt_mod->field_create))
797 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
799 field = priv->field_list + idx;
800 field->item_obj = dt_mod->field_create(priv->mod_data, idx);
804 _field_list_arrange(obj);
806 elm_widget_can_focus_set(obj, EINA_TRUE);
808 elm_layout_sizing_eval(obj);
811 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
813 priv->access_obj = _elm_access_edje_object_part_object_register
814 (obj, elm_layout_edje_get(obj), "access");
816 ai = _elm_access_object_get(priv->access_obj);
817 _elm_access_text_set(ai, ELM_ACCESS_TYPE, "date time");
818 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, obj);
823 _elm_datetime_smart_del(Evas_Object *obj)
828 ELM_DATETIME_DATA_GET(obj, sd);
830 for (idx = 0; idx < ELM_DATETIME_TYPE_COUNT; idx++)
832 tmp = sd->field_list + idx;
833 evas_object_del(tmp->item_obj);
834 eina_stringshare_del(tmp->separator);
837 if ((dt_mod) && (dt_mod->obj_unhook))
838 dt_mod->obj_unhook(sd->mod_data); // module - unhook
840 ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->base.del(obj);
844 _elm_datetime_smart_set_user(Elm_Datetime_Smart_Class *sc)
846 ELM_WIDGET_CLASS(sc)->base.add = _elm_datetime_smart_add;
847 ELM_WIDGET_CLASS(sc)->base.del = _elm_datetime_smart_del;
849 ELM_WIDGET_CLASS(sc)->translate = _elm_datetime_smart_translate;
850 ELM_WIDGET_CLASS(sc)->focus_next = _elm_datetime_smart_focus_next;
851 ELM_WIDGET_CLASS(sc)->on_focus = _elm_datetime_smart_on_focus;
852 ELM_WIDGET_CLASS(sc)->theme = _elm_datetime_smart_theme;
854 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_datetime_smart_sizing_eval;
857 EAPI const Elm_Datetime_Smart_Class *
858 elm_datetime_smart_class_get(void)
860 static Elm_Datetime_Smart_Class _sc =
861 ELM_DATETIME_SMART_CLASS_INIT_NAME_VERSION(ELM_DATETIME_SMART_NAME);
862 static const Elm_Datetime_Smart_Class *class = NULL;
863 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
868 _elm_datetime_smart_set(&_sc);
869 esc->callbacks = _smart_callbacks;
876 elm_datetime_add(Evas_Object *parent)
880 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
882 obj = elm_widget_add(_elm_datetime_smart_class_new(), parent);
883 if (!obj) return NULL;
885 if (!elm_widget_sub_object_add(parent, obj))
886 ERR("could not add %p as sub object of %p", obj, parent);
892 elm_datetime_format_get(const Evas_Object *obj)
894 ELM_DATETIME_CHECK(obj) NULL;
895 ELM_DATETIME_DATA_GET(obj, sd);
901 elm_datetime_format_set(Evas_Object *obj,
904 ELM_DATETIME_CHECK(obj);
905 ELM_DATETIME_DATA_GET(obj, sd);
909 strncpy(sd->format, fmt, ELM_DATETIME_MAX_FORMAT_LEN);
910 sd->format[ELM_DATETIME_MAX_FORMAT_LEN - 1] = '\0';
911 sd->user_format = EINA_TRUE;
913 else sd->user_format = EINA_FALSE;
919 elm_datetime_field_visible_get(const Evas_Object *obj,
920 Elm_Datetime_Field_Type fieldtype)
922 Datetime_Field *field;
923 ELM_DATETIME_CHECK(obj) EINA_FALSE;
924 ELM_DATETIME_DATA_GET(obj, sd);
926 if (fieldtype > ELM_DATETIME_AMPM) return EINA_FALSE;
928 field = sd->field_list + fieldtype;
930 return field->visible;
934 elm_datetime_field_visible_set(Evas_Object *obj,
935 Elm_Datetime_Field_Type fieldtype,
938 Datetime_Field *field;
940 ELM_DATETIME_CHECK(obj);
941 ELM_DATETIME_DATA_GET(obj, sd);
943 if (fieldtype > ELM_DATETIME_AMPM) return;
945 field = sd->field_list + fieldtype;
946 if (field->visible == visible) return;
948 field->visible = visible;
953 elm_datetime_field_limit_get(const Evas_Object *obj,
954 Elm_Datetime_Field_Type fieldtype,
958 Datetime_Field *field;
960 ELM_DATETIME_CHECK(obj);
961 ELM_DATETIME_DATA_GET(obj, sd);
963 if (fieldtype >= ELM_DATETIME_AMPM) return;
965 field = sd->field_list + fieldtype;
966 if (min) *min = field->min;
967 if (max) *max = field->max;
971 elm_datetime_field_limit_set(Evas_Object *obj,
972 Elm_Datetime_Field_Type fieldtype,
976 Datetime_Field *field;
978 ELM_DATETIME_CHECK(obj);
979 ELM_DATETIME_DATA_GET(obj, sd);
981 if (fieldtype >= ELM_DATETIME_AMPM) return;
983 if (min > max) return;
985 field = sd->field_list + fieldtype;
986 if (((min >= mapping[fieldtype].def_min) &&
987 (min <= mapping[fieldtype].def_max)) ||
988 (field->type == ELM_DATETIME_YEAR))
990 if (((max >= mapping[fieldtype].def_min) &&
991 (max <= mapping[fieldtype].def_max)) ||
992 (field->type == ELM_DATETIME_YEAR))
995 _apply_field_limits(obj);
999 elm_datetime_value_get(const Evas_Object *obj,
1000 struct tm *currtime)
1002 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1003 EINA_SAFETY_ON_NULL_RETURN_VAL(currtime, EINA_FALSE);
1004 ELM_DATETIME_DATA_GET(obj, sd);
1006 *currtime = sd->curr_time;
1011 elm_datetime_value_set(Evas_Object *obj,
1012 const struct tm *newtime)
1016 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1017 EINA_SAFETY_ON_NULL_RETURN_VAL(newtime, EINA_FALSE);
1018 ELM_DATETIME_DATA_GET(obj, sd);
1020 old_time = sd->curr_time;
1021 sd->curr_time = *newtime;
1022 // apply default field restrictions for curr_time
1023 _apply_range_restrictions(&sd->curr_time);
1024 // validate the curr_time according to the min_limt and max_limt
1025 _validate_datetime_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE);
1026 _validate_datetime_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE);
1027 _apply_field_limits(obj);
1029 if (!_date_cmp(&old_time, &sd->curr_time))
1030 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
1036 elm_datetime_value_min_get(const Evas_Object *obj,
1039 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1040 EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
1041 ELM_DATETIME_DATA_GET(obj, sd);
1043 *mintime = sd->min_limit;
1048 elm_datetime_value_min_set(Evas_Object *obj,
1049 const struct tm *mintime)
1053 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1054 EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
1055 ELM_DATETIME_DATA_GET(obj, sd);
1057 sd->min_limit = *mintime;
1058 old_time = sd->curr_time;
1059 // apply default field restrictions for min_limit
1060 _apply_range_restrictions(&sd->min_limit);
1061 // validate curr_time and max_limt according to the min_limit
1062 _validate_datetime_limits(&sd->max_limit, &sd->min_limit, EINA_FALSE);
1063 _validate_datetime_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE);
1064 _apply_field_limits(obj);
1066 if (!_date_cmp(&old_time, &sd->curr_time))
1067 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
1073 elm_datetime_value_max_get(const Evas_Object *obj,
1076 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1077 EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
1078 ELM_DATETIME_DATA_GET(obj, sd);
1080 *maxtime = sd->max_limit;
1085 elm_datetime_value_max_set(Evas_Object *obj,
1086 const struct tm *maxtime)
1090 ELM_DATETIME_CHECK(obj) EINA_FALSE;
1091 EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
1092 ELM_DATETIME_DATA_GET(obj, sd);
1094 sd->max_limit = *maxtime;
1095 old_time = sd->curr_time;
1096 // apply default field restrictions for max_limit
1097 _apply_range_restrictions(&sd->max_limit);
1098 // validate curr_time and min_limt according to the max_limit
1099 _validate_datetime_limits(&sd->max_limit, &sd->min_limit, EINA_TRUE);
1100 _validate_datetime_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE);
1101 _apply_field_limits(obj);
1103 if (!_date_cmp(&old_time, &sd->curr_time))
1104 evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);