2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 * Created on: Oct 9, 2013
25 #include <vconf-keys.h>
26 #include <unicode/ustring.h>
27 #include <unicode/udat.h>
28 #include <unicode/udatpg.h>
30 #include "setting-language.h"
31 #include "setting_view_toast.h"
35 static struct _lang_menu_item lang_menu_its[LANGUAGE_ITEM_COUNT];
36 static Evas_Object *g_lang_radio = NULL;
38 static void change_language_enabling(keynode_t *key, void *data)
40 if (is_connected_GM()) {
41 DBG("Setting - language can not change!!");
43 /* automatic freed!! */
44 struct _toast_data *toast = _create_toast(tmp_ad, _("IDS_ST_TPOP_CHANGE_LANGUAGE_ON_MOBILE_DEVICE"));
46 _show_toast(tmp_ad, toast);
49 elm_naviframe_item_pop(tmp_ad->nf);
55 void _initialize_language(void *data)
63 register_vconf_changing(VCONFKEY_WMS_WMANAGER_CONNECTED, change_language_enabling, NULL);
66 void _set_launguage_update_cb(void (*cb)(void *))
68 DBG("_set_launguage_update_cb() is called!");
71 DBG("callback is NULL");
78 void _clear_g_lang_menu_items()
80 DBG("_clear_g_lang_menu_items");
83 for (i = 0; i < LANGUAGE_ITEM_COUNT; i++) {
84 if (lang_menu_its[i].name)
85 free(lang_menu_its[i].name);
86 if (lang_menu_its[i].sub_name)
87 free(lang_menu_its[i].sub_name);
88 if (lang_menu_its[i].id)
89 free(lang_menu_its[i].id);
93 void _clear_lang_cb(void *data , Evas *e, Evas_Object *obj, void *event_info)
95 DBG("_clear_lang_cb");
102 if (ad->language_rdg) {
103 ad->language_rdg = NULL;
110 _clear_g_lang_menu_items();
112 unregister_vconf_changing(VCONFKEY_WMS_WMANAGER_CONNECTED, change_language_enabling);
114 ad->MENU_TYPE = SETTING_DISPLAY;
117 Ecore_Timer *lang_timer = NULL;
119 static Eina_Bool _update_language(void *data)
121 char *locale = vconf_get_str(VCONFKEY_LANGSET);
122 elm_language_set(locale);
123 /*elm_config_all_flush(); */
125 if (lang_update_cb) {
126 lang_update_cb(tmp_ad);
131 return ECORE_CALLBACK_CANCEL;
134 static int _set_dateformat(const char *region)
136 char *ret_str = NULL;
138 UChar customSkeleton[256] = { 0, };
139 UErrorCode status = U_ZERO_ERROR;
140 UDateTimePatternGenerator *pattern_generator;
142 UChar bestPattern[256] = { 0, };
143 char bestPatternString[256] = { 0, };
144 char *skeleton = "yMd";
146 uret = u_uastrncpy(customSkeleton, skeleton, strlen(skeleton));
148 pattern_generator = udatpg_open(region, &status);
150 int32_t bestPatternCapacity =
151 (int32_t)(sizeof(bestPattern) / sizeof((bestPattern)[0]));
152 (void)udatpg_getBestPattern(pattern_generator, customSkeleton,
153 u_strlen(customSkeleton), bestPattern,
154 bestPatternCapacity, &status);
156 ret_str = u_austrcpy(bestPatternString, bestPattern);
160 int len = strlen(bestPatternString);
161 char region_format[4] = {0, };
163 /* only save 'y', 'M', 'd' charactor */
164 for (; i < len; i++) {
165 if (bestPatternString[i] == 'y' && ymd[0] == 0) {
166 region_format[j++] = bestPatternString[i];
168 } else if (bestPatternString[i] == 'M' && ymd[1] == 0) {
169 region_format[j++] = bestPatternString[i];
171 } else if (bestPatternString[i] == 'd' && ymd[2] == 0) {
172 region_format[j++] = bestPatternString[i];
177 region_format[3] = '\0';
179 char *date_format_str[4] = {
180 "dMy", "Mdy", "yMd", "ydM"
182 int date_format_vconf_value = 1; /* default is "Mdy" */
183 for (i = 0; i < 4; i++) {
184 if (strlen(region_format) != 0 && !strcmp(region_format, date_format_str[i])) {
185 date_format_vconf_value = i;
189 DBG("bestPatternString : %s, format: %s, index: %d",
190 bestPatternString, region_format, date_format_vconf_value);
192 vconf_set_int(VCONFKEY_SETAPPL_DATE_FORMAT_INT, date_format_vconf_value);
197 void _gl_lang_sel_cb(void *data, Evas_Object *obj, void *event_info)
199 elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
201 int lang_index = (int)data;
204 snprintf(buf, sizeof(buf) - 1, "%s.UTF-8", lang_menu_its[lang_index].id);
206 vconf_set_str(VCONFKEY_LANGSET, buf);
207 vconf_set_str(VCONFKEY_REGIONFORMAT, buf);
209 _set_dateformat(lang_menu_its[lang_index].id);
211 const char *temp = vconf_get_str(VCONFKEY_LANGSET);
213 DBG("Setting - %s", temp);
216 elm_radio_value_set(g_lang_radio, lang_index);
219 char *locale = vconf_get_str(VCONFKEY_LANGSET);
220 elm_language_set(locale);
222 if (lang_update_cb) {
223 lang_update_cb(tmp_ad);
227 elm_naviframe_item_pop(tmp_ad->nf);
231 void _lang_sel_changed_cb(void *data, Evas_Object *obj, void *event_info)
236 char *_gl_lang_title_get(void *data, Evas_Object *obj, const char *part)
238 char buf[1024] = {0,};
239 Item_Data *id = data;
240 int index = id->index;
242 if (!strcmp(part, "elm.text.2")) {
243 snprintf(buf, sizeof(buf) - 1, "%s", lang_menu_its[index].sub_name);
244 } else if (!strcmp(part, "elm.text") || !strcmp(part, "elm.text.1")) {
245 snprintf(buf, sizeof(buf) - 1, "%s", lang_menu_its[index].name);
250 Evas_Object *_gl_lang_ridio_get(void *data, Evas_Object *obj, const char *part)
252 Evas_Object *radio = NULL;
253 Evas_Object *radio_main = evas_object_data_get(obj, "radio_main");
256 Item_Data *id = data;
257 int index = id->index;
259 if (!strcmp(part, "elm.icon")) {
260 radio = elm_radio_add(obj);
261 elm_object_style_set(radio, "list");
262 elm_radio_state_value_set(radio, index);
263 evas_object_smart_callback_add(radio, "changed", _lang_sel_changed_cb, (void *)index);
264 evas_object_size_hint_align_set(radio, EVAS_HINT_FILL, EVAS_HINT_FILL);
265 evas_object_size_hint_weight_set(radio, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
266 evas_object_propagate_events_set(radio, EINA_FALSE);
267 evas_object_repeat_events_set(radio, EINA_TRUE);
269 elm_radio_group_add(radio, radio_main);
271 const char *lang_set = vconf_get_str(VCONFKEY_LANGSET);
273 snprintf(buf, sizeof(buf) - 1, "%s.UTF-8", lang_menu_its[index].id);
274 char *alt_lang_set = strdup(buf);
276 if (!strcasecmp(lang_set, buf)) {
277 elm_radio_value_set(radio_main, index);
280 elm_genlist_item_show(id->item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
285 snprintf(buf, sizeof(buf) - 1, "%s.UTF8", lang_menu_its[index].id);
286 char *alt_lang_set2 = strdup(buf);
287 if (!strcasecmp(lang_set, buf)) {
288 elm_radio_value_set(radio_main, index);
291 elm_genlist_item_show(id->item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
296 DBG("Setting - current language is %s", lang_set);
304 static void _lang_gl_del(void *data, Evas_Object *obj)
306 /* FIXME: Unrealized callback can be called after this. */
307 /* Accessing Item_Data can be dangerous on unrealized callback. */
308 Item_Data *id = data;
315 _gl_menu_title_text_get(void *data, Evas_Object *obj, const char *part)
319 snprintf(buf, 1023, "%s", _("IDS_ST_BUTTON_LANGUAGE"));
323 Evas_Object *_create_lang_list(void *data)
325 DBG("_create_lang_list:clear");
329 DBG("%s", "_create_display_list - appdata is null");
332 Evas_Object *genlist = NULL;
333 Elm_Genlist_Item_Class *itc_temp = NULL;
334 struct _lang_menu_item *menu_its = NULL;
337 Evas_Object *layout = elm_layout_add(ad->nf);
338 elm_layout_file_set(layout, EDJE_PATH, "setting/genlist/layout");
339 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
340 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
342 Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
343 itc->item_style = "2text.1icon.1";
344 itc->func.text_get = _gl_lang_title_get;
345 itc->func.content_get = _gl_lang_ridio_get;
346 itc->func.del = _lang_gl_del;
348 Elm_Genlist_Item_Class *itc_1line = elm_genlist_item_class_new();
349 itc_1line->item_style = "1text.1icon.1";
350 itc_1line->func.text_get = _gl_lang_title_get;
351 itc_1line->func.content_get = _gl_lang_ridio_get;
352 itc_1line->func.del = _lang_gl_del;
354 genlist = elm_genlist_add(layout);
355 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
357 Evas_Object *circle_genlist = eext_circle_object_genlist_add(genlist, ad->circle_surface);
358 eext_circle_object_genlist_scroller_policy_set(circle_genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
359 eext_rotary_object_event_activated_set(circle_genlist, EINA_TRUE);
363 Elm_Genlist_Item_Class *title_item = elm_genlist_item_class_new();
364 title_item ->func.text_get = _gl_menu_title_text_get;
365 title_item->item_style = "title";
366 title_item->func.del = _lang_gl_del;
368 elm_genlist_item_append(genlist, title_item, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
370 elm_genlist_item_class_free(title_item);
372 menu_its = lang_menu_its;
374 Eina_List *lang_list = _get_language_list();
375 struct _lang_menu_item *node = NULL;
378 int lang_count = eina_list_count(lang_list);
380 DBG("Setting - language count: %d", lang_count);
383 node = (struct _lang_menu_item *) eina_list_data_get(lang_list);
385 lang_menu_its[index].name = strdup(node->name);
386 if (strlen(node->sub_name) > 0)
387 lang_menu_its[index].sub_name = strdup(node->sub_name);
389 lang_menu_its[index].sub_name = NULL;
390 lang_menu_its[index].id = strdup(node->id);
394 lang_list = eina_list_next(lang_list);
397 for (idx = 0; idx < lang_count; idx++) {
398 if (lang_menu_its[idx].sub_name != NULL) {
401 itc_temp = itc_1line;
403 Item_Data *id = calloc(sizeof(Item_Data), 1);
406 id->item = elm_genlist_item_append(
407 genlist, /* genlist object */
408 itc_temp, /* item class */
411 ELM_GENLIST_ITEM_NONE,
412 _gl_lang_sel_cb, /* call back */
417 ad->language_rdg = elm_radio_add(genlist);
418 elm_radio_state_value_set(ad->language_rdg, lang_count);
419 elm_radio_value_set(ad->language_rdg, lang_count);
421 g_lang_radio = ad->language_rdg;
423 evas_object_data_set(genlist, "radio_main", ad->language_rdg);
425 elm_genlist_item_class_free(itc);
426 elm_genlist_item_class_free(itc_1line);
429 Elm_Genlist_Item_Class *padding = elm_genlist_item_class_new();
430 padding->item_style = "padding";
431 padding->func.del = _lang_gl_del;
433 elm_genlist_item_append(genlist, padding, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
434 elm_genlist_item_class_free(padding);
436 elm_object_part_content_set(layout, "elm.genlist", genlist);
441 void _langlist_load()
444 if (is_file_exist(LANGLIST_FILE_PATH_IN_RW)) {
445 _parseLangListXML(LANGLIST_FILE_PATH_IN_RW);
447 _parseLangListXML(LANGLIST_FILE_PATH_IN_RO);
452 Eina_List *_get_language_list()
454 if (NULL == s_langlist) {
460 void _langlist_destroy()
462 Eina_List *list = s_langlist;
463 struct _lang_menu_item *node;
465 node = (struct _lang_menu_item *) eina_list_data_get(list);
470 free(node->sub_name);
474 list = eina_list_next(list);
476 s_langlist = eina_list_free(s_langlist);
479 static void _parseLangListXML(char *docname)
484 doc = xmlParseFile(docname);
486 DBG("Setting - Documentation is not parsed successfully");
490 cur = xmlDocGetRootElement(doc);
492 DBG("Setting - Empty documentation");
497 if (xmlStrcmp(cur->name, (const xmlChar *) "langlist")) {
498 DBG("Setting - Documentation of the wrong type, root node != settings");
503 cur = cur->xmlChildrenNode;
504 _tree_walk_langlist(cur);
513 static char *setting_language_string_replace(char *str, char *orig, char *repl)
515 static char buffer[124];
517 if (!(ch = strstr(str, orig))) {
520 strncpy(buffer, str, ch - str);
521 buffer[ch - str] = 0;
522 sprintf(buffer + (ch - str), "%s%s", repl, ch + strlen(orig));
527 static void _tree_walk_langlist(xmlNodePtr cur)
529 xmlNode *cur_node = NULL;
530 char *id = NULL; /* ex. ko_KR */
532 char *sub_name = NULL;
533 const char *dim = "(";
535 for (cur_node = cur; cur_node; cur_node = cur_node->next) {
536 if (cur_node->type == XML_ELEMENT_NODE) {
537 id = (char *)g_strdup((char *)xmlGetProp(cur_node, (const xmlChar *)"id"));
538 name = (char *)g_strdup((char *)xmlGetProp(cur_node, (const xmlChar *)"string"));
539 /*mcc = (char *)g_strdup((char*) xmlGetProp(cur_node, (const xmlChar *)"mcc")); */
541 struct _lang_menu_item *pitem = (struct _lang_menu_item *)calloc(1, sizeof(struct _lang_menu_item));
544 pitem->name = strdup(name);
546 sub_name = strdup(name);
547 if (sub_name && pitem->name)
548 pitem->sub_name = (char *)g_strdup(setting_language_string_replace(sub_name, pitem->name, ""));
553 s_langlist = eina_list_append(s_langlist, pitem);
559 const char *setting_get_lang_title(void)
565 if (s_langlist == NULL) {
569 Eina_List *lang_list = s_langlist;
570 Eina_List *elist = NULL;
572 struct _lang_menu_item *lang_entry;
575 char *language = NULL;
578 language = vconf_get_str(VCONFKEY_LANGSET);
580 DBG("current language : %s", language);
582 if (language == NULL) {
587 lang_entry = (struct _lang_menu_item *) eina_list_data_get(lang_list);
589 DBG("%s : language -> %s, locale -> %s", __func__, language, lang_entry->id);
591 snprintf(buf, sizeof(buf) - 1, "%s.UTF-8", lang_entry->id);
592 if (!strcmp(buf, language)) {
593 char pull_title_buf[128];
594 if (lang_entry->sub_name && strlen(lang_entry->sub_name) > 1)
595 snprintf(pull_title_buf, sizeof(pull_title_buf) - 1, "%s %s", lang_entry->name, lang_entry->sub_name);
597 snprintf(pull_title_buf, sizeof(pull_title_buf) - 1, "%s", lang_entry->name);
598 title = strdup(pull_title_buf);
602 lang_list = eina_list_next(lang_list);