From aeb15382d311890c70309274e8c66e21397b0e1d Mon Sep 17 00:00:00 2001 From: sachiel Date: Wed, 19 Oct 2011 14:17:14 +0000 Subject: [PATCH] Get us some nice auto translation scheme First things first, I'm not sure I'm setting the right variable on the setlocale() call, so someone more knowledgeable can look at it and fix it. How this works, you say? Just like elm_object_text_part_set(), except now it will pass the string given through dgettext() with the given domain (NULL means it uses whatever the app set with textdomain()), and when changing language with elm_language_set(), it will re-set the strings with a new translation. git-svn-id: https://svn.enlightenment.org/svn/e/trunk/elementary@64179 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- po/Makevars | 2 +- src/lib/Elementary.h.in | 49 +++++++++++++++ src/lib/elc_fileselector.c | 8 +-- src/lib/elm_entry.c | 7 +++ src/lib/elm_genlist.c | 7 +++ src/lib/elm_label.c | 7 +++ src/lib/elm_list.c | 7 +++ src/lib/elm_main.c | 21 +++++++ src/lib/elm_priv.h | 3 +- src/lib/elm_toolbar.c | 7 +++ src/lib/elm_widget.c | 147 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/elm_widget.h | 11 ++++ src/lib/elm_win.c | 10 +++ src/lib/els_tooltip.c | 39 ++++++++++++ 14 files changed, 319 insertions(+), 6 deletions(-) diff --git a/po/Makevars b/po/Makevars index f128df8..cc4af06 100644 --- a/po/Makevars +++ b/po/Makevars @@ -8,7 +8,7 @@ subdir = po top_builddir = .. # These options get passed to xgettext. -XGETTEXT_OPTIONS = --keyword=E_ --from-code=UTF-8 --foreign-user +XGETTEXT_OPTIONS = --keyword=E_ --keyword=N_ --from-code=UTF-8 --foreign-user # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index 84afae5..146528a 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -975,6 +975,53 @@ extern "C" { #define elm_object_text_get(obj) elm_object_text_part_get((obj), NULL) /** + * Set the text for an objects part, marking it as translatable + * + * The string to set as @p text must be the original one. Do not pass the + * return of @c gettext() here. Elementary will translate the string + * internally and set it on the object using elm_object_text_part_set(), + * also storing the original string so that it can be automatically + * translated when the language is changed with elm_language_set(). + * + * The @p domain will be stored along to find the translation in the + * correct catalog. It can be NULL, in which case it will use whatever + * domain was set by the application with @c textdomain(). This is useful + * in case you are building a library on top of Elementary that will have + * its own translatable strings, that should not be mixed with those of + * programs using the library. + * + * @param obj The object + * @param part The name of the part to set + * @param domain The translation domain to use + * @param text The original, non-translated text to set + * + * @ingroup General + */ + EAPI void elm_object_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *text); + +#define elm_object_domain_translatable_text_set(obj, domain, text) elm_object_domain_translatable_text_part_set((obj), NULL, (domain), (text)) + +#define elm_object_translatable_text_set(obj, text) elm_object_domain_translatable_text_part_set((obj), NULL, NULL, (text)) + + /** + * Gets the original string set as translatable for an object + * + * When setting translated strings, the function elm_object_text_part_get() + * will return the translation returned by @c gettext(). To get the + * original string use this function. + * + * @param obj The object + * @param part The name of the part that was set + * + * @return The original, untranslated string + * + * @ingroup General + */ + EAPI const char *elm_object_translatable_text_part_get(const Evas_Object *obj, const char *part); + +#define elm_object_translatable_text_get(obj) elm_object_translatable_text_part_get((obj), NULL) + + /** * Set a content of an object * * @param obj The Elementary object @@ -15334,6 +15381,8 @@ extern "C" { EAPI void elm_object_tooltip_show(Evas_Object *obj) EINA_ARG_NONNULL(1); EAPI void elm_object_tooltip_hide(Evas_Object *obj) EINA_ARG_NONNULL(1); EAPI void elm_object_tooltip_text_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1, 2); + EAPI void elm_object_tooltip_domain_translatable_text_set(Evas_Object *obj, const char *domain, const char *text) EINA_ARG_NONNULL(1, 3); +#define elm_object_tooltip_translatable_text_set(obj, text) elm_object_tooltip_domain_translatable_text_set((obj), NULL, (text)) EAPI void elm_object_tooltip_content_cb_set(Evas_Object *obj, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb) EINA_ARG_NONNULL(1); EAPI void elm_object_tooltip_unset(Evas_Object *obj) EINA_ARG_NONNULL(1); EAPI void elm_object_tooltip_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1); diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c index 57c78dd..21cf153 100644 --- a/src/lib/elc_fileselector.c +++ b/src/lib/elc_fileselector.c @@ -833,7 +833,7 @@ elm_fileselector_add(Evas_Object *parent) bt = elm_button_add(parent); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); elm_button_icon_set(bt, ic); - elm_object_text_set(bt, E_("Up")); + elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Up")); evas_object_size_hint_align_set(bt, 0.0, 0.0); evas_object_smart_callback_add(bt, "clicked", _up, obj); @@ -848,7 +848,7 @@ elm_fileselector_add(Evas_Object *parent) bt = elm_button_add(parent); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); elm_button_icon_set(bt, ic); - elm_object_text_set(bt, E_("Home")); + elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Home")); evas_object_size_hint_align_set(bt, 0.0, 0.0); evas_object_smart_callback_add(bt, "clicked", _home, obj); @@ -992,7 +992,7 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, // cancel btn bt = elm_button_add(obj); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); - elm_object_text_set(bt, E_("Cancel")); + elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Cancel")); evas_object_smart_callback_add(bt, "clicked", _canc, obj); @@ -1002,7 +1002,7 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, // ok btn bt = elm_button_add(obj); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); - elm_object_text_set(bt, E_("OK")); + elm_object_domain_translatable_text_set(bt, PACKAGE, N_("OK")); evas_object_smart_callback_add(bt, "clicked", _ok, obj); diff --git a/src/lib/elm_entry.c b/src/lib/elm_entry.c index faf4db4..bdff80b 100644 --- a/src/lib/elm_entry.c +++ b/src/lib/elm_entry.c @@ -942,6 +942,12 @@ _content_get_hook(const Evas_Object *obj, const char *part) static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); +} + +static void _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) { Widget_Data *wd = elm_widget_data_get(obj); @@ -2824,6 +2830,7 @@ elm_entry_add(Evas_Object *parent) elm_widget_content_set_hook_set(obj, _content_set_hook); elm_widget_content_unset_hook_set(obj, _content_unset_hook); elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_translate_hook_set(obj, _translate_hook); evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, wd); wd->scroller = elm_smart_scroller_add(e); diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c index 97b1974..eccc693 100644 --- a/src/lib/elm_genlist.c +++ b/src/lib/elm_genlist.c @@ -683,6 +683,12 @@ _show_region_hook(void *data, } static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); +} + +static void _sizing_eval(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); @@ -3489,6 +3495,7 @@ elm_genlist_add(Evas_Object *parent) elm_widget_can_focus_set(obj, EINA_TRUE); elm_widget_event_hook_set(obj, _event_hook); elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj); + elm_widget_translate_hook_set(obj, _translate_hook); wd->scr = elm_smart_scroller_add(e); evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOUSE_DOWN, diff --git a/src/lib/elm_label.c b/src/lib/elm_label.c index de33fc5..d5c1934 100644 --- a/src/lib/elm_label.c +++ b/src/lib/elm_label.c @@ -562,6 +562,12 @@ _elm_label_label_get(const Evas_Object *obj, const char *item) return wd->label; } +static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); +} + EAPI Evas_Object * elm_label_add(Evas_Object *parent) { @@ -580,6 +586,7 @@ elm_label_add(Evas_Object *parent) elm_widget_can_focus_set(obj, EINA_FALSE); elm_widget_text_set_hook_set(obj, _elm_label_label_set); elm_widget_text_get_hook_set(obj, _elm_label_label_get); + elm_widget_translate_hook_set(obj, _translate_hook); wd->bgcolor = EINA_FALSE; wd->bg = evas_object_rectangle_add(e); diff --git a/src/lib/elm_list.c b/src/lib/elm_list.c index 44cdec4..64b009d 100644 --- a/src/lib/elm_list.c +++ b/src/lib/elm_list.c @@ -285,6 +285,12 @@ _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type ty return EINA_TRUE; } +static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); +} + static Eina_Bool _deselect_all_items(Widget_Data *wd) { @@ -1306,6 +1312,7 @@ elm_list_add(Evas_Object *parent) elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); elm_widget_event_hook_set(obj, _event_hook); + elm_widget_translate_hook_set(obj, _translate_hook); wd->self = obj; wd->scr = elm_smart_scroller_add(e); diff --git a/src/lib/elm_main.c b/src/lib/elm_main.c index 54f9ac3..b9b1d6c 100644 --- a/src/lib/elm_main.c +++ b/src/lib/elm_main.c @@ -875,6 +875,13 @@ elm_policy_get(unsigned int policy) return _elm_policies[policy]; } +EAPI void +elm_language_set(const char *lang) +{ + setlocale(LC_ALL, lang); + _elm_win_translate(); +} + EAPI Eina_Bool elm_object_mirrored_get(const Evas_Object *obj) { @@ -933,6 +940,20 @@ elm_object_text_part_get(const Evas_Object *obj, const char *part) } EAPI void +elm_object_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *text) +{ + EINA_SAFETY_ON_NULL_RETURN(obj); + elm_widget_domain_translatable_text_part_set(obj, part, domain, text); +} + +EAPI const char * +elm_object_translatable_text_part_get(const Evas_Object *obj, const char *part) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); + return elm_widget_translatable_text_part_get(obj, part); +} + +EAPI void elm_object_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content) { EINA_SAFETY_ON_NULL_RETURN(obj); diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h index 2744ade..40e4ba1 100644 --- a/src/lib/elm_priv.h +++ b/src/lib/elm_priv.h @@ -28,7 +28,7 @@ # define bindtextdomain(domain,dir) # define E_(string) (string) #endif - +#define N_(string) (string) typedef struct _Elm_Config Elm_Config; typedef struct _Elm_Module Elm_Module; @@ -158,6 +158,7 @@ struct _Elm_Module void _elm_win_shutdown(void); void _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme); +void _elm_win_translate(void); Eina_Bool _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style); Eina_Bool _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style); diff --git a/src/lib/elm_toolbar.c b/src/lib/elm_toolbar.c index d99762b..b06d801 100644 --- a/src/lib/elm_toolbar.c +++ b/src/lib/elm_toolbar.c @@ -355,6 +355,12 @@ _theme_hook(Evas_Object *obj) } static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); +} + +static void _sizing_eval(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); @@ -705,6 +711,7 @@ elm_toolbar_add(Evas_Object *parent) elm_widget_del_pre_hook_set(obj, _del_pre_hook); elm_widget_del_hook_set(obj, _del_hook); elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_translate_hook_set(obj, _translate_hook); elm_widget_can_focus_set(obj, EINA_FALSE); wd->more_item = NULL; diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index e167ea5..9079027 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -19,6 +19,7 @@ static const char SMART_NAME[] = "elm_widget"; typedef struct _Smart_Data Smart_Data; typedef struct _Edje_Signal_Data Edje_Signal_Data; typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data; +typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data; struct _Smart_Data { @@ -36,6 +37,7 @@ struct _Smart_Data void (*activate_func)(Evas_Object *obj); void (*disable_func)(Evas_Object *obj); void (*theme_func)(Evas_Object *obj); + void (*translate_func)(Evas_Object *obj); Eina_Bool (*event_func)(Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, @@ -95,6 +97,7 @@ struct _Smart_Data int child_drag_y_locked; Eina_List *edje_signals; + Eina_List *translate_strings; Eina_Bool drag_x_locked : 1; Eina_Bool drag_y_locked : 1; @@ -130,6 +133,13 @@ struct _Elm_Event_Cb_Data const void *data; }; +struct _Elm_Translate_String_Data +{ + const char *id; + const char *domain; + const char *string; +}; + /* local subsystem functions */ static void _smart_reconfigure(Smart_Data *sd); static void _smart_add(Evas_Object *obj); @@ -532,6 +542,14 @@ elm_widget_theme_hook_set(Evas_Object *obj, } EAPI void +elm_widget_translate_hook_set(Evas_Object *obj, + void (*func)(Evas_Object *obj)) +{ + API_ENTRY return; + sd->translate_func = func; +} + +EAPI void elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func)(Evas_Object *obj, Evas_Object *source, @@ -2226,6 +2244,100 @@ elm_widget_text_part_get(const Evas_Object *obj, const char *item) } EAPI void +elm_widget_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *label) +{ + const char *str; + Eina_List *l; + Elm_Translate_String_Data *ts = NULL; + API_ENTRY return; + + str = eina_stringshare_add(part); + EINA_LIST_FOREACH(sd->translate_strings, l, ts) + if (ts->id == str) + break; + else + ts = NULL; + + if (!ts && !label) + eina_stringshare_del(str); + else if (!ts) + { + ts = malloc(sizeof(Elm_Translate_String_Data)); + if (!ts) return; + + ts->id = str; + ts->domain = eina_stringshare_add(domain); + ts->string = eina_stringshare_add(label); + sd->translate_strings = eina_list_append(sd->translate_strings, ts); + } + else + { + if (label) + { + eina_stringshare_replace(&ts->domain, domain); + eina_stringshare_replace(&ts->string, label); + } + else + { + sd->translate_strings = eina_list_remove_list( + sd->translate_strings, l); + eina_stringshare_del(ts->id); + eina_stringshare_del(ts->domain); + eina_stringshare_del(ts->string); + free(ts); + } + eina_stringshare_del(str); + } + +#ifdef HAVE_GETTEXT + if (label && label[0]) + label = dgettext(domain, label); +#endif + elm_widget_text_part_set(obj, part, label); +} + +EAPI const char * +elm_widget_translatable_text_part_get(const Evas_Object *obj, const char *part) +{ + const char *str, *ret = NULL; + Eina_List *l; + Elm_Translate_String_Data *ts; + API_ENTRY return NULL; + + str = eina_stringshare_add(part); + EINA_LIST_FOREACH(sd->translate_strings, l, ts) + if (ts->id == str) + { + ret = ts->string; + break; + } + eina_stringshare_del(str); + return ret; +} + +EAPI void +elm_widget_translate(Evas_Object *obj) +{ + const Eina_List *l; + Evas_Object *child; + Elm_Translate_String_Data *ts; + + API_ENTRY return; + EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_translate(child); + if (sd->resize_obj) elm_widget_translate(sd->resize_obj); + if (sd->hover_obj) elm_widget_translate(sd->hover_obj); + if (sd->translate_func) sd->translate_func(obj); + +#ifdef HAVE_GETTEXT + EINA_LIST_FOREACH(sd->translate_strings, l, ts) + { + const char *s = dgettext(ts->domain, ts->string); + elm_widget_text_part_set(obj, ts->id, s); + } +#endif +} + +EAPI void elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content) { API_ENTRY return; @@ -2689,6 +2801,20 @@ _elm_widget_item_tooltip_label_create(void *data, return label; } +static Evas_Object * +_elm_widget_item_tooltip_trans_label_create(void *data, + Evas_Object *obj __UNUSED__, + Evas_Object *tooltip, + void *item __UNUSED__) +{ + Evas_Object *label = elm_label_add(tooltip); + if (!label) + return NULL; + elm_object_style_set(label, "tooltip"); + elm_object_translatable_text_set(label, data); + return label; +} + static void _elm_widget_item_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, @@ -2723,6 +2849,19 @@ _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, _elm_widget_item_tooltip_label_del_cb); } +EAPI void +_elm_widget_item_tooltip_translatable_text_set(Elm_Widget_Item *item, + const char *text) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); + EINA_SAFETY_ON_NULL_RETURN(text); + + text = eina_stringshare_add(text); + _elm_widget_item_tooltip_content_cb_set + (item, _elm_widget_item_tooltip_trans_label_create, text, + _elm_widget_item_tooltip_label_del_cb); +} + static Evas_Object * _elm_widget_item_tooltip_create(void *data, Evas_Object *obj) @@ -3165,6 +3304,7 @@ _smart_del(Evas_Object *obj) { Evas_Object *sobj; Edje_Signal_Data *esd; + Elm_Translate_String_Data *ts; INTERNAL_ENTRY @@ -3199,6 +3339,13 @@ _smart_del(Evas_Object *obj) eina_stringshare_del(esd->source); free(esd); } + EINA_LIST_FREE(sd->translate_strings, ts) + { + eina_stringshare_del(ts->id); + eina_stringshare_del(ts->domain); + eina_stringshare_del(ts->string); + free(ts); + } eina_list_free(sd->event_cb); /* should be empty anyway */ if (sd->del_func) sd->del_func(obj); if (sd->style) eina_stringshare_del(sd->style); diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h index f3af342..b581802 100644 --- a/src/lib/elm_widget.h +++ b/src/lib/elm_widget.h @@ -244,6 +244,7 @@ EAPI void elm_widget_focus_hook_set(Evas_Object *obj, void (*func) ( EAPI void elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); +EAPI void elm_widget_translate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info)); EAPI void elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source)); @@ -251,6 +252,7 @@ EAPI void elm_widget_signal_callback_add_hook_set(Evas_Object *obj, EAPI void elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data)); EAPI void elm_widget_theme(Evas_Object *obj); EAPI void elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force); +EAPI void elm_widget_translate(Evas_Object *obj); EAPI void elm_widget_focus_next_hook_set(Evas_Object *obj, Eina_Bool (*func) (const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)); EAPI void elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data); EAPI void elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data); @@ -369,6 +371,8 @@ EAPI void elm_widget_focus_tree_unfocusable_handle(Evas_Object *obj) EAPI void elm_widget_focus_disabled_handle(Evas_Object *obj); EAPI void elm_widget_text_part_set(Evas_Object *obj, const char *part, const char *label); EAPI const char *elm_widget_text_part_get(const Evas_Object *obj, const char *part); +EAPI void elm_widget_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *text); +EAPI const char *elm_widget_translatable_text_part_get(const Evas_Object *obj, const char *part); 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); @@ -379,6 +383,7 @@ EAPI void _elm_widget_item_del_cb_set(Elm_Widget_Item *item, Evas_Sm EAPI void _elm_widget_item_data_set(Elm_Widget_Item *item, const void *data); EAPI void *_elm_widget_item_data_get(const Elm_Widget_Item *item); EAPI void _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, const char *text); +EAPI void _elm_widget_item_tooltip_translatable_text_set(Elm_Widget_Item *item, const char *text); EAPI void _elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb); EAPI void _elm_widget_item_tooltip_unset(Elm_Widget_Item *item); EAPI void _elm_widget_item_tooltip_style_set(Elm_Widget_Item *item, const char *style); @@ -455,6 +460,12 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out #define elm_widget_item_tooltip_text_set(item, text) \ _elm_widget_item_tooltip_text_set((Elm_Widget_Item *)item, text) /** + * Convenience function to set widget item tooltip as a text string. + * @see _elm_widget_item_tooltip_text_set() + */ +#define elm_widget_item_tooltip_translatable_text_set(item, text) \ + _elm_widget_item_tooltip_translatable_text_set((Elm_Widget_Item *)item, text) +/** * Convenience function to set widget item tooltip. * @see _elm_widget_item_tooltip_content_cb_set() */ diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index 1bbfdce..cb8a6cf 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -863,6 +863,16 @@ _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme) } } +void +_elm_win_translate(void) +{ + const Eina_List *l; + Evas_Object *obj; + + EINA_LIST_FOREACH(_elm_win_list, l, obj) + elm_widget_translate(obj); +} + #ifdef HAVE_ELEMENTARY_X static Eina_Bool _elm_win_client_message(void *data, int type __UNUSED__, void *event) diff --git a/src/lib/els_tooltip.c b/src/lib/els_tooltip.c index 4bf7b89..e2aa61c 100644 --- a/src/lib/els_tooltip.c +++ b/src/lib/els_tooltip.c @@ -467,6 +467,18 @@ _elm_tooltip_label_create(void *data, Evas_Object *obj) return label; } +static Evas_Object * +_elm_tooltip_trans_label_create(void *data, Evas_Object *obj __UNUSED__, Evas_Object *tooltip) +{ + Evas_Object *label = elm_label_add(tooltip); + const char **text = data; + if (!label) + return NULL; + elm_object_style_set(label, "tooltip"); + elm_object_domain_translatable_text_set(label, text[0], text[1]); + return label; +} + static void _elm_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { @@ -474,6 +486,15 @@ _elm_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_i } static void +_elm_tooltip_trans_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + const char **text = data; + eina_stringshare_del(text[0]); + eina_stringshare_del(text[1]); + free(text); +} + +static void _elm_tooltip_data_clean(Elm_Tooltip *tt) { if (tt->del_cb) tt->del_cb((void *)tt->data, tt->owner, NULL); @@ -668,6 +689,24 @@ elm_object_tooltip_text_set(Evas_Object *obj, const char *text) } /** + */ +EAPI void +elm_object_tooltip_domain_translatable_text_set(Evas_Object *obj, const char *domain, const char *text) +{ + const char **data; + EINA_SAFETY_ON_NULL_RETURN(obj); + EINA_SAFETY_ON_NULL_RETURN(text); + + data = malloc(2 * sizeof(char *)); + if (!data) return; + data[0] = eina_stringshare_add(domain); + data[1] = eina_stringshare_add(text); + elm_object_tooltip_content_cb_set + (obj, _elm_tooltip_trans_label_create, data, + _elm_tooltip_trans_label_del_cb); +} + +/** * Set the content to be shown in the tooltip object * * Setup the tooltip to object. The object can have only one tooltip, -- 2.7.4