From b2d2c9c3a6d12e1c242befbb7c61abec92011276 Mon Sep 17 00:00:00 2001 From: ChunEon Park Date: Tue, 23 Apr 2013 17:15:34 +0900 Subject: [PATCH] elementary/widget - added elm_object_part_text_translatble_set() elementary/widget item - and add elm_object_item_domain_part_text_translatable_set(). commit 633cb4e0193f6b5abe4deed8377b4c6b10ce882a Author: ChunEon Park @hermet.pe.kr> Date: Tue Apr 23 16:49:49 2013 +0900 commit aa7d8ad206f6a0d247475800cb5c6c32d80a6009 Author: ChunEon Park @hermet.pe.kr> Date: Tue Apr 23 17:11:28 2013 +0900 Change-Id: Ia859d563d524bc92d2cc488f2214c8d72ff52b95 --- src/lib/elm_layout.c | 2 + src/lib/elm_main.c | 13 +++ src/lib/elm_object.h | 30 ++++++ src/lib/elm_object_item.h | 28 +++++ src/lib/elm_widget.c | 262 ++++++++++++++++++++++++++++++++++++---------- src/lib/elm_widget.h | 13 +++ 6 files changed, 290 insertions(+), 58 deletions(-) diff --git a/src/lib/elm_layout.c b/src/lib/elm_layout.c index ffb9ac7..4269d76 100644 --- a/src/lib/elm_layout.c +++ b/src/lib/elm_layout.c @@ -1490,6 +1490,8 @@ elm_layout_text_set(Evas_Object *obj, ELM_LAYOUT_CHECK(obj) EINA_FALSE; ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + text = elm_widget_part_text_translate(obj, part, text); + return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->text_set (obj, part, text); } diff --git a/src/lib/elm_main.c b/src/lib/elm_main.c index 8668a64..1920ac2 100644 --- a/src/lib/elm_main.c +++ b/src/lib/elm_main.c @@ -979,6 +979,13 @@ elm_object_translatable_part_text_get(const Evas_Object *obj, const char *part) return elm_widget_translatable_part_text_get(obj, part); } +EAPI void +elm_object_domain_part_text_translatable_set(Evas_Object *obj, const char *part, const char *domain, Eina_Bool translatable) +{ + EINA_SAFETY_ON_NULL_RETURN(obj); + elm_widget_domain_part_text_translatable_set(obj, part, domain, translatable); +} + EINA_DEPRECATED EAPI void elm_object_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *text) { @@ -1446,6 +1453,12 @@ elm_object_item_translatable_part_text_get(const Elm_Object_Item *it, const char } EAPI void +elm_object_item_domain_part_text_translatable_set(Elm_Object_Item *it, const char *part, const char *domain, Eina_Bool translatable) +{ + _elm_widget_item_domain_part_text_translatable_set((Elm_Widget_Item *)it, part, domain, translatable); +} + +EAPI void elm_object_access_info_set(Evas_Object *obj, const char *txt) { elm_widget_access_info_set(obj, txt); diff --git a/src/lib/elm_object.h b/src/lib/elm_object.h index 13e2fdd..743c53c 100644 --- a/src/lib/elm_object.h +++ b/src/lib/elm_object.h @@ -84,6 +84,36 @@ EAPI const char *elm_object_translatable_part_text_get(const Evas_Object *obj, c #define elm_object_translatable_text_get(obj) elm_object_translatable_part_text_get((obj), NULL) /** + * Mark the part text to be transltable or not. + * + * Once you mark the part text to be translatable, the text will be translated + * internally regardless of elm_object_part_text_set() and + * elm_object_domain_translatable_part_text_set(). In other case, if you set the + * Elementary policy that all text will be translatable in default, you can set + * the part text to not be translated by calling this API. + * + * @param obj The object containing the text part + * @param part The part name of the translatable text + * @param domain The translation domain to use + * @param translatable @c EINA_TRUE, the part text will be translated + * internally. @c EINA_FALSE, otherwise. + * + * @see elm_object_domain_part_text_translatable_set() + * @see elm_object_part_text_set() + * @see elm_policy() + * + * @since 1.8 + * + * @ingroup General + */ +EAPI void elm_object_domain_part_text_translatable_set(Evas_Object *obj, const char *part, const char *domain, Eina_Bool translatable); + +#define elm_object_part_text_translatable_set(obj, part, translatable) elm_object_domain_part_text_translatable_set((obj), (part), NULL, (translatable)) + +#define elm_object_domain_text_translatable_set(obj, domain, translatable) elm_object_domain_part_text_translatable_set((obj), NULL, (domain), (translatable)) + + +/** * Set the content on part of a given container widget * * @param obj The Elementary container widget diff --git a/src/lib/elm_object_item.h b/src/lib/elm_object_item.h index 3b529d4..d6ca768 100644 --- a/src/lib/elm_object_item.h +++ b/src/lib/elm_object_item.h @@ -164,6 +164,34 @@ EAPI const char *elm_object_item_translatable_part_text_get(const Elm_Object_Ite #define elm_object_item_translatable_text_get(it) elm_object_item_translatable_part_text_get((it), NULL) +/** + * Mark the part text to be transltable or not. + * + * Once you mark the part text to be translatable, the text will be translated + * internally regardless of elm_object_item_part_text_set() and + * elm_object_item_domain_translatable_part_text_set(). In other case, if you + * set the Elementary policy that all text will be translatable in default, you + * can set the part text to not be translated by calling this API. + * + * @param it The object item containing the text part + * @param part The part name of the translatable text + * @param domain The translation domain to use + * @param translatable @c EINA_TRUE, the part text will be translated + * internally. @c EINA_FALSE, otherwise. + * + * @see elm_object_item_domain_translatable_part_text_set() + * @see elm_object_item_part_text_set() + * @see elm_policy() + * + * @since 1.8 + * + * @ingroup General + */ +EAPI void elm_object_item_domain_part_text_translatable_set(Elm_Object_Item *it, const char *part, const char *domain, Eina_Bool translatable); + +#define elm_object_item_part_text_translatable_set(it, part, translatable) elm_object_item_domain_part_text_translatable_set((it), (part), NULL, (translatable)) + +#define elm_object_item_domain_text_translatable_set(it, domain, translatable) elm_object_item_domain_part_text_translatable_set((it), NULL, (domain), (translatable)) /** * Set the text to read out when in accessibility mode diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index 5a0aa5a..40d1d07 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -30,6 +30,7 @@ struct _Elm_Translate_String_Data Eina_Stringshare *id; Eina_Stringshare *domain; Eina_Stringshare *string; + Eina_Bool preset : 1; }; /* local subsystem globals */ @@ -3292,53 +3293,64 @@ elm_widget_text_part_get(const Evas_Object *obj, return NULL; } -static Eina_Bool -_translatable_part_text_set(Eina_List **translate_strings, const char *part, const char *domain, const char *label) +static Elm_Translate_String_Data * +_translate_string_data_get(Eina_List *translate_strings, const char *part) { - const char *str; - Eina_List *t, *l; - Elm_Translate_String_Data *ts = NULL; + Elm_Translate_String_Data *ts; + Eina_Stringshare *str; + Eina_List *l; + + if (eina_list_count(translate_strings) == 0) return NULL; - t = *translate_strings; str = eina_stringshare_add(part); - EINA_LIST_FOREACH(t, l, ts) + EINA_LIST_FOREACH(translate_strings, l, ts) { if (ts->id == str) break; else ts = NULL; } + eina_stringshare_del(str); - if (!ts && !label) - eina_stringshare_del(str); - else if (!ts) - { - ts = malloc(sizeof(Elm_Translate_String_Data)); - if (!ts) return EINA_FALSE; + return ts; +} - ts->id = str; - ts->domain = eina_stringshare_add(domain); - ts->string = eina_stringshare_add(label); - t = eina_list_append(t, ts); - } - else +static Elm_Translate_String_Data * +_part_text_translatable_set(Eina_List **translate_strings, const char *part, Eina_Bool translatable, Eina_Bool preset) +{ + Eina_List *t; + Elm_Translate_String_Data *ts = NULL; + t = *translate_strings; + ts = _translate_string_data_get(t, part); + + if (translatable) { - if (label) + if (!ts) { - eina_stringshare_replace(&ts->domain, domain); - eina_stringshare_replace(&ts->string, label); + ts = ELM_NEW(Elm_Translate_String_Data); + if (!ts) return NULL; + + ts->id = eina_stringshare_add(part); + t = eina_list_append(t, ts); } - else + if (preset) ts->preset = EINA_TRUE; + } + //Delete this exist one if this part has been not preset. + //see elm_widget_part_text_translatable_set() + else if ((preset) || (!ts->preset)) + { + if (ts) { - t = eina_list_remove_list(t, l); + t = eina_list_remove(t, ts); eina_stringshare_del(ts->id); eina_stringshare_del(ts->domain); eina_stringshare_del(ts->string); free(ts); + ts = NULL; } - eina_stringshare_del(str); } *translate_strings = t; - return EINA_TRUE; + + return ts; } EAPI void @@ -3348,53 +3360,106 @@ elm_widget_domain_translatable_part_text_set(Evas_Object *obj, const char *label) { API_ENTRY return; - - if (!_translatable_part_text_set(&sd->translate_strings, part, domain, - label)) return; + Elm_Translate_String_Data *ts; + if (!label) + { + _part_text_translatable_set(&sd->translate_strings, part, EINA_FALSE, + EINA_FALSE); + } + else + { + ts = _part_text_translatable_set(&sd->translate_strings, part, + EINA_TRUE, EINA_FALSE); + if (!ts) return; + if (!ts->string) ts->string = eina_stringshare_add(label); + else eina_stringshare_replace(&ts->string, label); + if (!ts->domain) ts->domain = eina_stringshare_add(domain); + else eina_stringshare_replace(&ts->domain, domain); #ifdef HAVE_GETTEXT - if (label && label[0]) - label = dgettext(domain, label); + if (label[0]) label = dgettext(domain, label); #endif + } + + sd->on_translate = EINA_TRUE; elm_widget_text_part_set(obj, part, label); + sd->on_translate = EINA_FALSE; } -static const char * -_translatable_part_text_get(Eina_List *translate_strings, const char *part) +EAPI const char * +elm_widget_translatable_part_text_get(const Evas_Object *obj, + const char *part) { + API_ENTRY return NULL; Elm_Translate_String_Data *ts; - const char*ret = NULL, *str; - Eina_List *l; + ts = _translate_string_data_get(sd->translate_strings, part); + if (ts) return ts->string; + return NULL; +} - str = eina_stringshare_add(part); - EINA_LIST_FOREACH(translate_strings, l, ts) - if (ts->id == str) - { - ret = ts->string; - break; - } - eina_stringshare_del(str); +EAPI void +elm_widget_domain_part_text_translatable_set(Evas_Object *obj, + const char *part, + const char *domain, + Eina_Bool translatable) +{ + API_ENTRY return; + Elm_Translate_String_Data *ts; + const char *text; - return ret; + ts = _part_text_translatable_set(&sd->translate_strings, part, + translatable, EINA_TRUE); + if (!ts) return; + if (!ts->domain) ts->domain = eina_stringshare_add(domain); + else eina_stringshare_replace(&ts->domain, domain); + + text = elm_widget_text_part_get(obj, part); + if (!text || !text[0]) return; + + if (!ts->string) ts->string = eina_stringshare_add(text); + +//Try to translate text since we don't know the text is already translated. +#ifdef HAVE_GETTEXT + text = dgettext(domain, text); +#endif + sd->on_translate = EINA_TRUE; + elm_widget_text_part_set(obj, part, text); + sd->on_translate = EINA_FALSE; +} + +static const char* +_part_text_translate(Eina_List *translate_strings, + const char *part, + const char *text) +{ + Elm_Translate_String_Data *ts; + ts = _translate_string_data_get(translate_strings, part); + if (!ts) return text; + + if (!ts->string) ts->string = eina_stringshare_add(text); + else eina_stringshare_replace(&ts->string, text); +#ifdef HAVE_GETTEXT + if (text && text[0]) + text = dgettext(ts->domain, text); +#endif + return text; } EAPI const char * -elm_widget_translatable_part_text_get(const Evas_Object *obj, - const char *part) +elm_widget_part_text_translate(Evas_Object *obj, const char *part, const char *text) { - API_ENTRY return NULL; - return _translatable_part_text_get(sd->translate_strings, part); + API_ENTRY return text; + + if (!sd->translate_strings || sd->on_translate) return text; + return _part_text_translate(sd->translate_strings, part, text); } EAPI void elm_widget_translate(Evas_Object *obj) { + API_ENTRY return; + const Eina_List *l; Evas_Object *child; -#ifdef HAVE_GETTEXT - Elm_Translate_String_Data *ts; -#endif - - API_ENTRY return; EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_translate(child); @@ -3404,10 +3469,14 @@ elm_widget_translate(Evas_Object *obj) sd->api->translate(obj); #ifdef HAVE_GETTEXT + Elm_Translate_String_Data *ts; EINA_LIST_FOREACH(sd->translate_strings, l, ts) { + if (!ts->string) continue; const char *s = dgettext(ts->domain, ts->string); + sd->on_translate = EINA_TRUE; elm_widget_text_part_set(obj, ts->id, s); + sd->on_translate = EINA_FALSE; } #endif } @@ -4272,14 +4341,29 @@ _elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item, const char *label) { ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); + Elm_Translate_String_Data *ts; - if (!_translatable_part_text_set(&item->translate_strings, part, domain, - label)) return; + if (!label) + { + _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE, + EINA_FALSE); + } + else + { + ts = _part_text_translatable_set(&item->translate_strings, part, + EINA_TRUE, EINA_FALSE); + if (!ts) return; + if (!ts->string) ts->string = eina_stringshare_add(label); + else eina_stringshare_replace(&ts->string, label); + if (!ts->domain) ts->domain = eina_stringshare_add(domain); + else eina_stringshare_replace(&ts->domain, domain); #ifdef HAVE_GETTEXT - if (label && label[0]) - label = dgettext(domain, label); + if (label[0]) label = dgettext(domain, label); #endif + } + item->on_translate = EINA_TRUE; _elm_widget_item_part_text_set(item, part, label); + item->on_translate = EINA_FALSE; } EAPI const char * @@ -4287,7 +4371,40 @@ _elm_widget_item_translatable_part_text_get(const Elm_Widget_Item *item, const char *part) { ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL); - return _translatable_part_text_get(item->translate_strings, part); + Elm_Translate_String_Data *ts; + ts = _translate_string_data_get(item->translate_strings, part); + if (ts) return ts->string; + return NULL; +} + +EAPI void +_elm_widget_item_domain_part_text_translatable_set(Elm_Widget_Item *item, + const char *part, + const char *domain, + Eina_Bool translatable) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); + Elm_Translate_String_Data *ts; + const char *text; + + ts = _part_text_translatable_set(&item->translate_strings, part, + translatable, EINA_TRUE); + if (!ts) return; + if (!ts->domain) ts->domain = eina_stringshare_add(domain); + else eina_stringshare_replace(&ts->domain, domain); + + text = _elm_widget_item_part_text_get(item, part); + if (!text || !text[0]) return; + + if (!ts->string) ts->string = eina_stringshare_add(text); + +//Try to translate text since we don't know the text is already translated. +#ifdef HAVE_GETTEXT + text = dgettext(domain, text); +#endif + item->on_translate = EINA_TRUE; + _elm_widget_item_part_text_set(item, part, text); + item->on_translate = EINA_FALSE; } typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip; @@ -4693,6 +4810,15 @@ _elm_widget_item_part_content_unset(Elm_Widget_Item *item, return item->content_unset_func((Elm_Object_Item *)item, part); } +static const char * +_elm_widget_item_part_text_translate(Elm_Widget_Item *item, + const char *part, + const char *label) +{ + if (!item->translate_strings || item->on_translate) return label; + return _part_text_translate(item->translate_strings, part, label); +} + EAPI void _elm_widget_item_part_text_set(Elm_Widget_Item *item, const char *part, @@ -4707,6 +4833,7 @@ _elm_widget_item_part_text_set(Elm_Widget_Item *item, return; } + label = _elm_widget_item_part_text_translate(item, part, label); item->text_set_func((Elm_Object_Item *)item, part, label); } @@ -4892,6 +5019,25 @@ _elm_widget_item_access_info_set(Elm_Widget_Item *item, else item->access_info = eina_stringshare_add(txt); } +EAPI void +_elm_widget_item_translate(Elm_Widget_Item *item) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); + +#ifdef HAVE_GETTEXT + Elm_Translate_String_Data *ts; + const Eina_List *l; + EINA_LIST_FOREACH(item->translate_strings, l, ts) + { + if (!ts->string) continue; + const char *s = dgettext(ts->domain, ts->string); + item->on_translate = EINA_TRUE; + _elm_widget_item_part_text_set(item, ts->id, s); + item->on_translate = EINA_FALSE; + } +#endif +} + /* happy debug functions */ #ifdef ELM_DEBUG static void diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h index 2df9778..8d1a32f 100644 --- a/src/lib/elm_widget.h +++ b/src/lib/elm_widget.h @@ -524,6 +524,7 @@ typedef struct _Elm_Widget_Smart_Data Eina_Bool can_access : 1; Eina_Bool highlighted : 1; Eina_Bool highlight_root : 1; + Eina_Bool on_translate : 1; } Elm_Widget_Smart_Data; /** @@ -666,6 +667,7 @@ struct _Elm_Widget_Item Eina_Bool disabled : 1; Eina_Bool on_deletion : 1; + Eina_Bool on_translate : 1; }; struct _Elm_Object_Item @@ -805,6 +807,8 @@ EAPI void elm_widget_text_part_set(Evas_Object *obj, const char *par EAPI const char *elm_widget_text_part_get(const Evas_Object *obj, const char *part); EAPI void elm_widget_domain_translatable_part_text_set(Evas_Object *obj, const char *part, const char *domain, const char *text); EAPI const char *elm_widget_translatable_part_text_get(const Evas_Object *obj, const char *part); +EAPI void elm_widget_domain_part_text_translatable_set(Evas_Object *obj, const char *part, const char *domain, Eina_Bool translatable); +EAPI const char * elm_widget_part_text_translate(Evas_Object *obj, const char *part, const char *text); EAPI void elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content); EAPI Evas_Object *elm_widget_content_part_get(const Evas_Object *obj, const char *part); EAPI Evas_Object *elm_widget_content_part_unset(Evas_Object *obj, const char *part); @@ -862,6 +866,7 @@ EAPI void _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, E EAPI void _elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item, const char *part, const char *domain, const char *label); EAPI const char * _elm_widget_item_translatable_part_text_get(const Elm_Widget_Item *item, const char *part); EAPI void _elm_widget_item_translate(Elm_Widget_Item *item); +EAPI void _elm_widget_item_domain_part_text_translatable_set(Elm_Widget_Item *item, const char *part, const char *domain, Eina_Bool translatable); /** * Function to operate on a given widget's scrollabe children when necessary. @@ -1081,6 +1086,14 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out #define elm_widget_item_del_pre_hook_set(item, func) \ _elm_widget_item_del_pre_hook_set((Elm_Widget_Item *)item, (Elm_Widget_Del_Pre_Cb)func) +/** + * Convenience function to query del pre hook. + * @see _elm_widget_item_del_pre_hook_set() + */ +#define elm_widget_item_translate(item) \ + _elm_widget_item_translate((Elm_Widget_Item *)item) + + #define ELM_WIDGET_CHECK_OR_RETURN(obj, ...) \ do { \ if (!obj || !evas_object_smart_data_get(obj)) \ -- 2.7.4