Merge "[copy&paste] add interface for OSP"
[framework/uifw/elementary.git] / src / lib / elm_datetime.c
index d4b92c8..8736e8d 100644 (file)
@@ -1,8 +1,14 @@
-#include <locale.h>
-#include <langinfo.h>
 #include <Elementary.h>
 #include "elm_priv.h"
 
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
+
 typedef struct _Widget_Data Widget_Data;
 typedef struct _Datetime_Field Datetime_Field;
 typedef struct _Datetime_Mod_Api Datetime_Mod_Api;
@@ -68,19 +74,21 @@ struct _Format_Map
    char *fmt_char;
    int def_min;
    int def_max;
+   char *ignore_sep;
 };
 
 // default limits for individual fields
-static const Format_Map mapping[DATETIME_TYPE_COUNT] = {
-   [ELM_DATETIME_YEAR]   =  { "Yy",   0, 137 },
-   [ELM_DATETIME_MONTH]  =  { "mbBh", 0,  11  },
-   [ELM_DATETIME_DATE]   =  { "de",   1,  31  },
-   [ELM_DATETIME_HOUR]   =  { "IHkl", 0,  23  },
-   [ELM_DATETIME_MINUTE] =  { "M",    0,  59  },
-   [ELM_DATETIME_AMPM]   =  { "pP",   0,  1   }
+static Format_Map mapping[DATETIME_TYPE_COUNT] = {
+   [ELM_DATETIME_YEAR]   =  { "Yy",  -1,  -1, "" },
+   [ELM_DATETIME_MONTH]  =  { "mbBh", 0,  11, "" },
+   [ELM_DATETIME_DATE]   =  { "de",   1,  31, "" },
+   [ELM_DATETIME_HOUR]   =  { "IHkl", 0,  23, "" },
+   [ELM_DATETIME_MINUTE] =  { "M",    0,  59, ":" },
+   [ELM_DATETIME_AMPM]   =  { "pP",   0,   1, "" }
 };
 
 static const char *multifield_formats = "cxXrRTDF";
+static const char *ignore_separators = "()";
 
 static Datetime_Mod_Api *dt_mod = NULL;
 static const char *widtype = NULL;
@@ -317,7 +325,7 @@ _theme_hook(Evas_Object *obj)
              snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR, field->location);
              edje_object_signal_emit(wd->base, buf, "elm");
              snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
-             edje_object_part_text_set(wd->base, buf, field->separator);
+             edje_object_part_text_escaped_set(wd->base, buf, field->separator);
              dt_mod->field_value_display(wd->mod_data, field->item_obj);
           }
         else
@@ -341,7 +349,7 @@ _max_days_get(int year, int month)
    localtime_r(&t, &time1);
    time1.tm_year = year;
    time1.tm_mon = month;
-   for(day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max; day++)
+   for (day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max; day++)
      {
         time1.tm_mday = day;
         mktime(&time1);
@@ -545,6 +553,7 @@ _field_list_arrange(Evas_Object *obj)
    _field_list_display(obj);
 }
 
+// FIXME: provide nl_langinfo on Windows if possible
 // returns expanded format string for corresponding multi-field format character
 static char *
 _expanded_fmt_str_get(char ch)
@@ -553,16 +562,32 @@ _expanded_fmt_str_get(char ch)
    switch (ch)
      {
       case 'c':
+#ifdef HAVE_LANGINFO_H
          exp_fmt = nl_langinfo(D_T_FMT);
+#else
+         exp_fmt = "";
+#endif
          break;
       case 'x':
+#ifdef HAVE_LANGINFO_H
          exp_fmt = nl_langinfo(D_FMT);
+#else
+         exp_fmt = "";
+#endif
          break;
       case 'X':
+#ifdef HAVE_LANGINFO_H
          exp_fmt = nl_langinfo(T_FMT);
+#else
+         exp_fmt = "";
+#endif
          break;
       case 'r':
+#ifdef HAVE_LANGINFO_H
          exp_fmt = nl_langinfo(T_FMT_AMPM);
+#else
+         exp_fmt = "";
+#endif
          break;
       case 'R':
          exp_fmt =  "%H:%M";
@@ -617,7 +642,7 @@ _parse_format(Evas_Object *obj, char *fmt_ptr)
 {
    Widget_Data *wd;
    Datetime_Field *field = NULL;
-   unsigned int len = 0, idx, location = 0;
+   unsigned int len = 0, idx = 0, location = 0;
    char separator[MAX_SEPARATOR_LEN];
    char cur;
    Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE,
@@ -629,6 +654,7 @@ _parse_format(Evas_Object *obj, char *fmt_ptr)
      {
         if (fmt_parsing)
           {
+             fmt_parsing = EINA_FALSE;
              for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
                {
                   if (strchr(mapping[idx].fmt_char, cur))
@@ -640,25 +666,25 @@ _parse_format(Evas_Object *obj, char *fmt_ptr)
                        field->fmt[1] = cur;
                        field->fmt_exist = EINA_TRUE;
                        field->location = location++;
-                       fmt_parsing = EINA_FALSE;
                        sep_lookup = EINA_TRUE;
                        len = 0;
                        break;
                     }
                }
           }
-        if (cur == ' ') separator[len++] = cur;
-        else if (cur == '%') fmt_parsing = EINA_TRUE;
-        if ((cur == ' ') || (cur == '%'))
+        if (cur == '%')
           {
+             fmt_parsing = EINA_TRUE;
              sep_parsing = EINA_FALSE;
              // set the separator to previous field
              separator[len] = 0;
              if (field) eina_stringshare_replace(&field->separator, separator);
           }
-        if (sep_parsing && (len < MAX_SEPARATOR_LEN-1) &&
-            (field->type != ELM_DATETIME_AMPM) &&
-            (!((field->type == ELM_DATETIME_MINUTE) && (cur ==':'))))
+
+        // ignore the set of chars (global, field specific) as field separators.
+        if (sep_parsing && (len < MAX_SEPARATOR_LEN - 1) &&
+            (field->type != ELM_DATETIME_AMPM) && (!strchr(ignore_separators, cur)) &&
+            (!strchr(mapping[idx].ignore_sep, cur)))
            separator[len++] = cur;
         if (sep_lookup) sep_parsing = EINA_TRUE;
         sep_lookup = EINA_FALSE;
@@ -680,11 +706,17 @@ _reload_format(Evas_Object *obj)
    wd = elm_widget_data_get(obj);
    if (!wd) return;
 
+   // FIXME: provide nl_langinfo on Windows if possible
    // fetch the default format from Libc.
    if (!wd->user_format)
+#ifdef HAVE_LANGINFO_H
      strncpy(wd->format, nl_langinfo(D_T_FMT), MAX_FORMAT_LEN);
+#else
+     strncpy(wd->format, "", MAX_FORMAT_LEN);
+#endif
 
    dt_fmt = (char *)malloc(MAX_FORMAT_LEN);
+   if (!dt_fmt) return;
    strncpy(dt_fmt, wd->format, MAX_FORMAT_LEN);
 
    _expand_format(dt_fmt);
@@ -719,7 +751,7 @@ _reload_format(Evas_Object *obj)
              edje_object_signal_emit(wd->base, buf, "elm");
           }
         snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, (field->location + 1));
-        edje_object_part_text_set(wd->base, buf, field->separator);
+        edje_object_part_text_escaped_set(wd->base, buf, field->separator);
      }
    edje_object_message_signal_process(wd->base);
    _field_list_arrange(obj);
@@ -739,6 +771,8 @@ _field_list_init(Evas_Object *obj)
    t = time(NULL);
    localtime_r(&t, &wd->curr_time);
 
+   mapping[ELM_DATETIME_YEAR].def_min = _elm_config->year_min;
+   mapping[ELM_DATETIME_YEAR].def_max = _elm_config->year_max;
    for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++)
      {
         field = wd->field_list + idx;