clock: rewrite unicode using i18n API.
[apps/core/preloaded/indicator-win.git] / src / modules / clock / clock.c
1 /*
2  *  Indicator
3  *
4  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <vconf.h>
24 //#include <Ecore_X.h>
25 #include <utils_i18n.h>
26 #include <system_settings.h>
27
28 #include "common.h"
29 #include "indicator.h"
30 #include "main.h"
31 #include "indicator_gui.h"
32 #include "icon.h"
33 #include "util.h"
34 #include "modules.h"
35 #include "box.h"
36 #include "log.h"
37
38 #define SYSTEM_RESUME           "system_wakeup"
39
40 #define TIME_FONT_SIZE_24               ELM_SCALE_SIZE(30)
41 #define TIME_FONT_SIZE_12               ELM_SCALE_SIZE(30)
42 #define AMPM_FONT_SIZE          ELM_SCALE_SIZE(29)
43
44 #define TIME_FONT_COLOR         200, 200, 200, 255
45 #define AMPM_FONT_COLOR         200, 200, 200, 255
46 #define LABEL_STRING            "<font_size=%d>%s" \
47         "</font_size>"
48 #define LABEL_STRING_FONT               "%s</font>"
49
50 #define BATTERY_TIMER_INTERVAL          3
51 #define BATTERY_TIMER_INTERVAL_CHARGING 30
52
53 #define CLOCK_STR_LEN 128
54
55 enum {
56         INDICATOR_CLOCK_MODE_12H = 0,
57         INDICATOR_CLOCK_MODE_24H,
58         INDICATOR_CLOCK_MODE_MAX
59 };
60
61 int clock_mode = INDICATOR_CLOCK_MODE_12H;
62 int clock_hour = 0;
63 static const char *colon = ":";
64 static const char *ratio = "&#x2236;";
65
66 static int apm_length = 0;
67 static int apm_position = 0;
68 extern Ecore_Timer *clock_timer;
69
70 static i18n_udatepg_h _last_generator;
71 static char *_last_locale = NULL;
72 static int battery_charging = 0;
73
74 static int register_clock_module(void *data);
75 static int unregister_clock_module(void);
76 static int language_changed_cb(void *data);
77 static int region_changed_cb(void *data);
78 static int wake_up_cb(void *data);
79 #ifdef _SUPPORT_SCREEN_READER
80 static int register_clock_tts(void *data,int win_type);
81 #endif
82
83 #define ICON_PRIORITY   INDICATOR_PRIORITY_FIXED8
84 #define MODULE_NAME             "clock"
85
86 static void indicator_get_apm_by_region(char* output, void* data);
87 static void indicator_get_time_by_region(char* output, void* data);
88
89 static void ICU_set_timezone(const char *timezone);
90
91 icon_s sysclock = {
92         .type = INDICATOR_TXT_ICON,
93         .name = MODULE_NAME,
94         .priority = ICON_PRIORITY,
95         .always_top = EINA_FALSE,
96         .img_obj = {0,},
97         .obj_exist = EINA_FALSE,
98         .exist_in_view = EINA_FALSE,
99         .init = register_clock_module,
100         .fini = unregister_clock_module,
101         .lang_changed = NULL,
102         .region_changed = region_changed_cb,
103         .lang_changed = language_changed_cb,
104         .wake_up = wake_up_cb,
105 };
106
107
108
109 void cal_delete_last_generator(void)
110 {
111         if (_last_locale) {
112                 free(_last_locale);
113                 _last_locale = NULL;
114         }
115         if (_last_generator) {
116                 i18n_udatepg_destroy(_last_generator);
117                 _last_generator = NULL;
118         }
119 }
120
121
122
123 static i18n_udatepg_h __cal_get_pattern_generator(const char *locale, int *status)
124 {
125         if (!_last_generator || !_last_locale || strcmp(locale, _last_locale)) {
126
127                 cal_delete_last_generator();
128
129                 _last_locale = strdup(locale);
130
131                 int ret = i18n_udatepg_create(locale, &_last_generator);
132                 if (ret != I18N_ERROR_NONE) {
133                         _E("i18n_udatepg_create failed %d", ret);
134                         _last_generator = NULL;
135                 }
136         }
137         return _last_generator;
138 }
139
140
141
142 static void set_app_state(void* data)
143 {
144         sysclock.ad = data;
145 }
146
147
148
149 static void indicator_clock_changed_cb(void *data)
150 {
151         char time_str[CLOCK_STR_LEN] = {0,};
152         char time_buf[CLOCK_STR_LEN] = {0,};
153         char ampm_buf[CLOCK_STR_LEN] = {0,};
154         char ampm_str[CLOCK_STR_LEN] = {0,};
155         char buf[CLOCK_STR_LEN] = {0,};
156         char result[CLOCK_STR_LEN] = {0,};
157         char icu_apm[CLOCK_STR_LEN] = {0,};
158
159         struct tm *ts = NULL;
160         time_t ctime;
161         struct appdata *ad = NULL;
162         int len;
163         int font_size;
164         int ampm_size = AMPM_FONT_SIZE;
165
166         ret_if(!data);
167
168         ad = (struct appdata *)data;
169
170         if (icon_get_update_flag() == 0) return;
171
172         /* Set time */
173         ctime = time(NULL);
174         ts = localtime(&ctime);
175         if (ts == NULL) {
176                 _E("Fail to get localtime !");
177                 return;
178         }
179
180         if (clock_timer != NULL) {
181                 ecore_timer_del(clock_timer);
182                 clock_timer = NULL;
183         }
184
185         memset(time_str, 0x00, sizeof(time_str));
186         memset(ampm_str, 0x00, sizeof(ampm_str));
187         memset(time_buf, 0x00, sizeof(time_buf));
188         memset(ampm_buf, 0x00, sizeof(ampm_buf));
189         memset(buf, 0x00, sizeof(buf));
190
191         clock_timer = ecore_timer_add(60 - ts->tm_sec, (void *)indicator_clock_changed_cb, data);
192         if(!clock_timer) {
193                 _E("Fail to add timer !");
194         }
195
196         indicator_get_apm_by_region(icu_apm,data);
197         indicator_get_time_by_region(time_buf,data);
198
199
200         if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
201                 char bf1[32] = { 0, };
202                 int hour;
203                 static int pre_hour = 0;
204                 const char *region = NULL;
205
206                 int bRegioncheck = 0;
207                 char *lang1 = "it_IT";
208
209                 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
210                 ret_if(!region);
211
212                 if (strncmp(region,lang1,strlen(lang1)) == 0) bRegioncheck = 1;
213
214                 if (apm_length>=4 || bRegioncheck==1) {
215                         if (ts->tm_hour >= 0 && ts->tm_hour < 12) {
216                                 snprintf(ampm_buf, sizeof(ampm_buf),"%s","AM");
217                         } else {
218                                 snprintf(ampm_buf, sizeof(ampm_buf),"%s","PM");
219                         }
220                 } else {
221                         snprintf(ampm_buf, sizeof(ampm_buf),"%s",icu_apm);
222                 }
223
224                 strftime(bf1, sizeof(bf1), "%l", ts);
225                 hour = atoi(bf1);
226                 strftime(bf1, sizeof(bf1), ":%M", ts);
227
228                 font_size = TIME_FONT_SIZE_12;
229                 clock_hour = hour;
230
231                 if ((pre_hour<10 && hour>=10)||(pre_hour>=10 && hour<10)) {
232                         box_update_display(&(ad->win));
233                 }
234
235                 pre_hour = hour;
236         } else {
237                 font_size = TIME_FONT_SIZE_24;
238         }
239
240         snprintf(time_str, sizeof(time_str), LABEL_STRING, font_size, time_buf);
241         snprintf(ampm_str, sizeof(ampm_str), LABEL_STRING, ampm_size, ampm_buf);
242
243         if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
244                 if (apm_position == 0) {
245                         len = snprintf(buf, sizeof(buf), "%s %s", ampm_str, time_str);
246                 } else {
247                         len = snprintf(buf, sizeof(buf), "%s %s", time_str, ampm_str);
248                 }
249         } else {
250                 len = snprintf(buf, sizeof(buf), "%s", time_str);
251         }
252
253         snprintf(result, sizeof(result), LABEL_STRING_FONT, buf);
254         if (len < 0) {
255                 _E("Unexpected ERROR!");
256                 return;
257         }
258
259         _D("[CLOCK MODULE] Timer Status : %d Time: %s", clock_timer, result);
260         util_part_text_emit(data, "elm.text.clock", result);
261
262         return;
263 }
264
265
266
267 static void _clock_format_changed_cb(keynode_t *node, void *data)
268 {
269         struct appdata *ad = NULL;
270         int mode_24 = 0;
271         i18n_timezone_h timezone;
272
273         ret_if(!data);
274
275         ad = (struct appdata *)data;
276
277         if (vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224,&mode_24) < 0)
278         {
279                 ERR("Error getting VCONFKEY_REGIONFORMAT_TIME1224 value");
280                 return;
281         }
282
283         /* Check Time format. If timeformat have invalid value, Set to 12H */
284         if( mode_24==VCONFKEY_TIME_FORMAT_24)
285         {
286                 if(clock_mode == INDICATOR_CLOCK_MODE_12H)
287                 {
288                         clock_mode = INDICATOR_CLOCK_MODE_24H;
289                         box_update_display(&(ad->win));
290                 }
291         }
292         else
293         {
294                 if(clock_mode==INDICATOR_CLOCK_MODE_24H)
295                 {
296                         clock_mode = INDICATOR_CLOCK_MODE_12H;
297                         box_update_display(&(ad->win));
298                 }
299         }
300
301         char *timezone_str = util_get_timezone_str();
302
303         int ret = i18n_timezone_create(&timezone, timezone_str);
304         if (ret != I18N_ERROR_NONE) {
305                 _E("Unable to create timzone handle for %s: %d", timezone_str, ret);
306                 free(timezone_str);
307                 return;
308         }
309
310         ret = i18n_timezone_set_default(timezone);
311         if (ret != I18N_ERROR_NONE) {
312                 _E("Unable to set default timzone: %d", ret);
313                 i18n_timezone_destroy(timezone);
314                 free(timezone_str);
315                 return;
316         }
317
318         indicator_clock_changed_cb(data);
319         i18n_timezone_destroy(timezone);
320         free(timezone_str);
321 }
322
323
324
325 static void indicator_clock_charging_now_cb(keynode_t *node, void *data)
326 {
327         int status = 0;
328
329         retif(data == NULL, , "Invalid parameter!");
330
331
332         vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &status);
333
334         battery_charging = status;
335 }
336
337
338
339 static int language_changed_cb(void *data)
340 {
341         const char *pa_lang = vconf_get_str(VCONFKEY_LANGSET);
342         DBG("language_changed_cb %s",pa_lang);
343         indicator_clock_changed_cb(data);
344         return OK;
345 }
346
347
348
349 static int region_changed_cb(void *data)
350 {
351         _clock_format_changed_cb(NULL, data);
352         return OK;
353 }
354
355
356
357 static int wake_up_cb(void *data)
358 {
359         indicator_clock_changed_cb(data);
360
361         return OK;
362 }
363
364
365
366 /*static void _time_changed(system_settings_key_e key, void *data)
367 {
368         DBG("_time_changed");
369         _clock_format_changed_cb(NULL,data);
370 }*/
371
372
373
374 static void regionformat_changed(keynode_t *node, void *data)
375 {
376         DBG("regionformat_changed");
377         _clock_format_changed_cb(NULL,data);
378 }
379
380
381
382 static void timezone_int_changed(keynode_t *node, void *data)
383 {
384         DBG("timezone_int_changed");
385         _clock_format_changed_cb(NULL,data);
386 }
387
388
389
390 static void timezone_id_changed(keynode_t *node, void *data)
391 {
392         char *szTimezone = NULL;
393         szTimezone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
394
395         DBG("timezone_id_changed %s",szTimezone);
396         _clock_format_changed_cb(NULL,data);
397 }
398
399
400
401 static int register_clock_module(void *data)
402 {
403         int r = 0, ret = -1;
404
405         retif(data == NULL, FAIL, "Invalid parameter!");
406
407         set_app_state(data);
408
409         /*ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_TIME_CHANGED, _time_changed, data);
410         if (ret != OK) {
411                 r = r | ret;
412         }*/
413
414         ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, regionformat_changed, data);
415         if (ret != OK) {
416                 r = r | ret;
417         }
418
419         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT, timezone_int_changed, data);
420         if (ret != OK) {
421                 r = r | ret;
422         }
423
424         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID, timezone_id_changed, data);
425         if (ret != OK) {
426                 r = r | ret;
427         }
428
429         ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, regionformat_changed, data);
430         if (ret != OK) {
431                 r = r | ret;
432         }
433         _clock_format_changed_cb(NULL, data);
434         indicator_clock_charging_now_cb(NULL,data);
435
436         return r;
437 }
438
439
440
441 static int unregister_clock_module(void)
442 {
443         int ret;
444
445         //ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_TIME_CHANGED);
446         ret = ret | vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, regionformat_changed);
447         ret = ret | vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT, timezone_int_changed);
448         ret = ret | vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID, timezone_id_changed);
449         ret = ret | vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, regionformat_changed);
450
451         if (clock_timer != NULL) {
452                 ecore_timer_del(clock_timer);
453                 clock_timer = NULL;
454         }
455
456         cal_delete_last_generator();
457
458         return ret;
459 }
460
461
462
463 static inline char *_extend_heap(char *buffer, int *sz, int incsz)
464 {
465         char *tmp;
466
467         *sz += incsz;
468         tmp = realloc(buffer, *sz);
469         if (!tmp) {
470                 ERR("Heap");
471                 return NULL;
472         }
473
474         return tmp;
475 }
476
477
478
479 static char *_string_replacer(const char *src, const char *pattern, const char *replace)
480 {
481         const char *ptr;
482         char *tmp = NULL;
483         char *ret = NULL;
484         int idx = 0;
485         int out_idx = 0;
486         int out_sz = 0;
487         enum {
488                 STATE_START,
489                 STATE_FIND,
490                 STATE_CHECK,
491                 STATE_END,
492         } state;
493
494         if (!src || !pattern)
495                 return NULL;
496
497         out_sz = strlen(src);
498         ret = strdup(src);
499         if (!ret) {
500                 ERR("Heap");
501                 return NULL;
502         }
503
504         out_idx = 0;
505         for (state = STATE_START, ptr = src; state != STATE_END; ptr++) {
506                 switch (state) {
507                 case STATE_START:
508                         if (*ptr == '\0') {
509                                 state = STATE_END;
510                         } else if (!isblank(*ptr)) {
511                                 state = STATE_FIND;
512                                 ptr--;
513                         }
514                         break;
515                 case STATE_FIND:
516                         if (*ptr == '\0') {
517                                 state = STATE_END;
518                         } else if (*ptr == *pattern) {
519                                 state = STATE_CHECK;
520                                 ptr--;
521                                 idx = 0;
522                         } else {
523                                 ret[out_idx] = *ptr;
524                                 out_idx++;
525                                 if (out_idx == out_sz) {
526                                         tmp = _extend_heap(ret, &out_sz, strlen(replace) + 1);
527                                         if (!tmp) {
528                                                 free(ret);
529                                                 return NULL;
530                                         }
531                                         ret = tmp;
532                                 }
533                         }
534                         break;
535                 case STATE_CHECK:
536                         if (!pattern[idx]) {
537                                 /*!
538      * If there is no space for copying the replacement,
539      * Extend size of the return buffer.
540      */
541                                 if (out_sz - out_idx < strlen(replace) + 1) {
542                                         tmp = _extend_heap(ret, &out_sz, strlen(replace) + 1);
543                                         if (!tmp) {
544                                                 free(ret);
545                                                 return NULL;
546                                         }
547                                         ret = tmp;
548                                 }
549
550                                 strcpy(ret + out_idx, replace);
551                                 out_idx += strlen(replace);
552
553                                 state = STATE_FIND;
554                                 ptr--;
555                         } else if (*ptr != pattern[idx]) {
556                                 ptr -= idx;
557
558                                 /* Copy the first matched character */
559                                 ret[out_idx] = *ptr;
560                                 out_idx++;
561                                 if (out_idx == out_sz) {
562                                         tmp = _extend_heap(ret, &out_sz, strlen(replace) + 1);
563                                         if (!tmp) {
564                                                 free(ret);
565                                                 return NULL;
566                                         }
567
568                                         ret = tmp;
569                                 }
570
571                                 state = STATE_FIND;
572                         } else {
573                                 idx++;
574                         }
575                         break;
576                 default:
577                         break;
578                 }
579         }
580
581         ret[out_idx] = '\0';
582         return ret;
583 }
584
585
586
587 void indicator_get_apm_by_region(char* output,void *data)
588 {
589         retif(data == NULL, , "Data parameter is NULL");
590         retif(output == NULL, , "output parameter is NULL");
591
592         i18n_uchar u_custom_skeleton[CLOCK_STR_LEN] = { 0, };
593         i18n_uchar u_timezone[64] = {0,};
594         i18n_uchar u_best_pattern[CLOCK_STR_LEN] = { 0, };
595         i18n_uchar u_formatted[CLOCK_STR_LEN] = { 0, };
596
597         i18n_udate_format_h formatter;
598         int32_t best_pattern_len, formatted_len;
599
600         char s_best_pattern[CLOCK_STR_LEN] = { 0, };
601         char s_formatted[CLOCK_STR_LEN] = { 0, };
602
603         int status = 0;
604
605         i18n_udatepg_h pattern_generator = NULL;
606
607         char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
608         if(locale == NULL)
609         {
610                 ERR("[Error] get value of fail.");
611                 return;
612         }
613
614         /* Remove ".UTF-8" in locale */
615         char locale_tmp[32] = {0,};
616         strncpy(locale_tmp, locale, sizeof(locale_tmp)-1);
617         char *p = util_safe_str(locale_tmp, ".UTF-8");
618         if (p) {
619                 *p = 0;
620         }
621         free(locale);
622
623         i18n_ustring_copy_ua_n(u_custom_skeleton, "hhmm", ARRAY_SIZE(u_custom_skeleton));
624
625         pattern_generator = __cal_get_pattern_generator (locale_tmp, &status);
626         if (pattern_generator == NULL) {
627                 return ;
628         }
629
630         int ret = i18n_udatepg_get_best_pattern(pattern_generator, u_custom_skeleton, i18n_ustring_get_length(u_custom_skeleton),
631                         u_best_pattern, (int32_t)ARRAY_SIZE(u_best_pattern), &best_pattern_len);
632         if (ret != I18N_ERROR_NONE) {
633                 _E("i18n_udatepg_get_best_pattern failed: %d", ret);
634                 i18n_udatepg_destroy(pattern_generator);
635                 return;
636         }
637         i18n_udatepg_destroy(pattern_generator);
638
639         i18n_ustring_copy_au(s_best_pattern, u_best_pattern);
640         i18n_ustring_copy_ua(u_best_pattern, "a");
641
642         char *timezone_id = util_get_timezone_str();
643         DBG("TimeZone is %s", timezone_id);
644
645         if (s_best_pattern[0] == 'a') {
646                 apm_position = 0;
647         }
648         else {
649                 apm_position = 1;
650         }
651
652         i18n_udate date;
653         ret = i18n_ucalendar_get_now(&date);
654         if (ret != I18N_ERROR_NONE) {
655                 ERR("i18n_ucalendar_get_now failed: %d", ret);
656                 free(timezone_id);
657                 return;
658         }
659         if (timezone_id) {
660                 i18n_ustring_copy_ua_n(u_timezone, timezone_id, ARRAY_SIZE(u_timezone));
661         }
662
663         ret = i18n_udate_create(I18N_UDATE_PATTERN, I18N_UDATE_PATTERN, locale_tmp, timezone_id ? u_timezone : NULL, -1,
664                         u_best_pattern, -1, &formatter);
665         if (ret != I18N_ERROR_NONE) {
666                 free(timezone_id);
667                 return;
668         }
669
670         free(timezone_id);
671
672         ret = i18n_udate_format_date(formatter, date, u_formatted, ARRAY_SIZE(s_formatted), NULL, &formatted_len);
673         if (ret != I18N_ERROR_NONE) {
674                 i18n_udate_destroy(formatter);
675                 return;
676         }
677
678         i18n_udate_destroy(formatter);
679
680         i18n_ustring_copy_au(s_formatted, u_formatted);
681         apm_length = i18n_ustring_get_length(u_formatted);
682
683         if (strlen(s_formatted) < CLOCK_STR_LEN) {
684                 strncpy(output, s_formatted, strlen(s_formatted));
685         }
686         else {
687                 strncpy(output, s_formatted, CLOCK_STR_LEN - 1);
688         }
689
690         return;
691 }
692
693
694
695 void indicator_get_time_by_region(char* output,void *data)
696 {
697         retif(data == NULL, , "Data parameter is NULL");
698         retif(output == NULL, , "output parameter is NULL");
699
700         i18n_uchar u_custom_skeleton[CLOCK_STR_LEN] = { 0, };
701         i18n_uchar u_timezone[64] = {0,};
702         i18n_uchar u_best_pattern[CLOCK_STR_LEN] = { 0, };
703         i18n_uchar u_formatted[CLOCK_STR_LEN] = { 0, };
704
705         int status = 0;
706         i18n_udate_format_h formatter = NULL;
707
708         char s_best_pattern[CLOCK_STR_LEN] = { 0, };
709         char s_formatted[CLOCK_STR_LEN] = { 0, };
710         char *s_convert_formatted = NULL;
711
712         char s_time_skeleton[20] = {0,};
713         i18n_udatepg_h pattern_generator = NULL;
714
715         int32_t best_pattern_len, formatted_len;
716
717         if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
718                 strcpy(s_time_skeleton, "hm");
719         }
720         else {
721                 strcpy(s_time_skeleton, "Hm");
722         }
723         char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
724         if (locale == NULL) {
725                 ERR("[Error] get value of fail.");
726                 return;
727         }
728
729         /* Remove ".UTF-8" in locale */
730         char locale_tmp[32] = {0,};
731         strncpy(locale_tmp, locale, sizeof(locale_tmp)-1);
732         char *p = util_safe_str(locale_tmp, ".UTF-8");
733         if (p) {
734                 *p = 0;
735         }
736         free(locale);
737
738         i18n_ustring_copy_ua_n(u_custom_skeleton, s_time_skeleton, ARRAY_SIZE(u_custom_skeleton));
739
740         pattern_generator = __cal_get_pattern_generator (locale_tmp, &status);
741         if (pattern_generator == NULL) {
742                 return;
743         }
744
745         int ret = i18n_udatepg_get_best_pattern(pattern_generator, u_custom_skeleton, i18n_ustring_get_length(u_custom_skeleton),
746                                 u_best_pattern, ARRAY_SIZE(u_best_pattern), &best_pattern_len);
747         if (ret != I18N_ERROR_NONE) {
748                 _E("i18n_udatepg_get_best_pattern failed: %d", ret);
749                 i18n_udatepg_destroy(pattern_generator);
750                 return;
751         }
752
753         i18n_udatepg_destroy(pattern_generator);
754
755         char a_best_pattern[64] = {0,};
756         i18n_ustring_copy_au(a_best_pattern, u_best_pattern);
757
758         char *a_best_pattern_fixed = strtok(a_best_pattern, "a");
759         a_best_pattern_fixed = strtok(a_best_pattern_fixed, " ");
760         if (a_best_pattern_fixed) {
761                 i18n_ustring_copy_ua(u_best_pattern, a_best_pattern_fixed);
762         }
763
764         i18n_ustring_copy_au(s_best_pattern, u_best_pattern);
765
766         DBG("BestPattern is %s", s_best_pattern);
767
768         i18n_udate date;
769         ret = i18n_ucalendar_get_now(&date);
770         if (ret != I18N_ERROR_NONE) {
771                 ERR("i18n_ucalendar_get_now failed: %d", ret);
772                 return;
773         }
774
775         char* timezone_id = util_get_timezone_str();
776         DBG("TimeZone is %s", timezone_id);
777
778         if (timezone_id) {
779                 i18n_ustring_copy_ua_n(u_timezone, timezone_id, ARRAY_SIZE(u_timezone));
780         }
781
782         ret = i18n_udate_create(I18N_UDATE_PATTERN, I18N_UDATE_PATTERN, locale_tmp, timezone_id ? u_timezone : NULL, -1,
783                         u_best_pattern, -1, &formatter);
784         if (ret != I18N_ERROR_NONE) {
785                 free(timezone_id);
786                 return;
787         }
788
789         free(timezone_id);
790
791         ret = i18n_udate_format_date(formatter, date, u_formatted, ARRAY_SIZE(s_formatted), NULL, &formatted_len);
792         if (ret != I18N_ERROR_NONE) {
793                 i18n_udate_destroy(formatter);
794                 return;
795         }
796
797         i18n_udate_destroy(formatter);
798
799         i18n_ustring_copy_au(s_formatted, u_formatted);
800         DBG("DATE & TIME is %s %s %d %s", locale_tmp, s_formatted, i18n_ustring_get_length(u_formatted), s_best_pattern);
801
802         DBG("24H :: Before change %s", s_formatted);
803         s_convert_formatted = _string_replacer(s_formatted, colon, ratio);
804         DBG("24H :: After change %s", s_convert_formatted);
805
806         if (!s_convert_formatted) {
807                 DBG("_string_replacer return NULL");
808                 return;
809         }
810
811         if (strlen(s_convert_formatted) < CLOCK_STR_LEN) {
812                 strncpy(output, s_convert_formatted, strlen(s_convert_formatted));
813         }
814         else {
815                 strncpy(output, s_convert_formatted, CLOCK_STR_LEN - 1);
816         }
817
818         free(s_convert_formatted);
819
820         return;
821 }
822
823
824
825 static void ICU_set_timezone(const char *timezone)
826 {
827         i18n_timezone_h tmz;
828
829         if (timezone == NULL) {
830                 ERR("TIMEZONE is NULL");
831                 return;
832         }
833
834         int ret = i18n_timezone_create(&tmz, timezone);
835         if (ret != I18N_ERROR_NONE) {
836                 ERR("Unable to create timezone handle from %s: %d", timezone, ret);
837                 return;
838         }
839
840         ret = i18n_timezone_set_default(tmz);
841         if (ret != I18N_ERROR_NONE) {
842                 ERR("Unable to set default timezone to %s: %d", timezone, ret);
843         }
844
845         i18n_timezone_destroy(tmz);
846 }
847
848
849
850 #ifdef _SUPPORT_SCREEN_READER
851 static char *_access_info_cb(void *data, Evas_Object *obj)
852 {
853         Evas_Object *item = data;
854         char *tmp = NULL;
855         char time_str[32];
856         char time_buf[128], ampm_buf[128];
857         char buf[CLOCK_STR_LEN];
858         char buf1[CLOCK_STR_LEN];
859         int ret = 0;
860         int battery_capa = 0;
861         int hour = 0;
862         int minute = 0;
863         char strHour[128] = { 0, };
864         char strMin[128] = { 0, };
865
866
867         struct tm *ts = NULL;
868         time_t ctime;
869         int len;
870
871         retif(data == NULL,NULL, "Invalid parameter!");
872         char *timezone = util_get_timezone_str();
873         ICU_set_timezone(timezone);
874         if(timezone!=NULL)
875                 free(timezone);
876
877         /* Set time */
878         ctime = time(NULL);
879         ts = localtime(&ctime);
880         if (ts == NULL)
881                 return NULL;
882
883         memset(time_str, 0x00, sizeof(time_str));
884         memset(time_buf, 0x00, sizeof(time_buf));
885         memset(ampm_buf, 0x00, sizeof(ampm_buf));
886         memset(buf, 0x00, sizeof(buf));
887         memset(buf1, 0x00, sizeof(buf1));
888
889         if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
890                 char bf1[32] = { 0, };
891
892                 if (ts->tm_hour >= 0 && ts->tm_hour < 12)
893                         strncpy(ampm_buf, _("IDS_IDLE_OPT_AM_ABB"),sizeof(ampm_buf)-1);
894                 else
895                         strncpy(ampm_buf, _("IDS_IDLE_OPT_PM_ABB"),sizeof(ampm_buf)-1);
896
897                 strftime(bf1, sizeof(bf1), "%l", ts);
898                 hour = atoi(bf1);
899                 strftime(bf1, sizeof(bf1), "%M", ts);
900                 minute = atoi(bf1);
901         }
902         else{
903                 char bf1[32] = { 0, };
904
905                 strftime(bf1, sizeof(bf1), "%H", ts);
906                 hour = atoi(bf1);
907                 strftime(bf1, sizeof(bf1), "%M", ts);
908                 minute = atoi(bf1);
909         }
910
911         if(hour ==1)
912         {
913                 strncpy(strHour, _("IDS_COM_BODY_1_HOUR"),sizeof(strHour));
914         }
915         else
916         {
917                 snprintf(strHour, sizeof(strHour), _("IDS_COM_POP_PD_HOURS"),hour);
918         }
919
920         if(minute ==1)
921         {
922                 strncpy(strMin, _("IDS_COM_BODY_1_MINUTE"),sizeof(strMin));
923         }
924         else
925         {
926                 snprintf(strMin, sizeof(strMin), _("IDS_COM_BODY_PD_MINUTES"),minute);
927         }
928
929         if(clock_mode == INDICATOR_CLOCK_MODE_12H)
930                 snprintf(time_str, sizeof(time_str), "%s, %s, %s", strHour, strMin,ampm_buf);
931         else
932                 snprintf(time_str, sizeof(time_str), "%s, %s", strHour, strMin);
933
934
935         ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &battery_capa);
936         if (ret != OK)
937         {
938                 return NULL;
939         }
940         if (battery_capa < 0)
941         {
942                 return NULL;
943         }
944
945         if (battery_capa > 100)
946                 battery_capa = 100;
947         snprintf(buf1, sizeof(buf1), _("IDS_IDLE_BODY_PD_PERCENT_OF_BATTERY_POWER_REMAINING"), battery_capa);
948
949         snprintf(buf, sizeof(buf), "%s, %s, %s", time_str, buf1, _("IDS_IDLE_BODY_STATUS_BAR_ITEM"));
950
951         DBG("buf: %s", buf);
952         tmp = strdup(buf);
953         if (!tmp) return NULL;
954         return tmp;
955 }
956
957
958
959 static int register_clock_tts(void *data,int win_type)
960 {
961         int r = 0, ret = -1;
962
963         retif(data == NULL, FAIL, "Invalid parameter!");
964
965         Evas_Object *to = NULL;
966         Evas_Object *ao = NULL;
967         struct appdata *ad = data;
968
969         to = (Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(ad->win[win_type].layout), "elm.rect.clock.access");
970         ao = util_access_object_register(to, ad->win[win_type].layout);
971         util_access_object_info_cb_set(ao,ELM_ACCESS_INFO,_access_info_cb,data);
972         return 0;
973 }
974 #endif
975