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
EAPI int elm_policy_get(unsigned int policy);
/**
+ * Change the language of the current application
+ *
+ * The @p lang passed must be the full name of the locale to use, for
+ * example "en_US.utf8" or "es_ES@euro".
+ *
+ * Changing language with this function will make Elementary run through
+ * all its widgets, translating strings set with
+ * elm_object_domain_translatable_text_part_set(). This way, an entire
+ * UI can have its language changed without having to restart the program.
+ *
+ * For more complex cases, like having formatted strings that need
+ * translation, widgets will also emit a "language,changed" signal that
+ * the user can listen to to manually translate the text.
+ *
+ * @param lang Language to set, must be the full name of the locale
+ *
+ * @ingroup General
+ */
+ EAPI void elm_language_set(const char *lang);
+
+ /**
* Set a label of an object
*
* @param obj The Elementary object
#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
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);
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);
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);
// 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);
// 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);
}
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);
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);
}
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);
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);
elm_smart_scroller_widget_set(wd->scr, obj);
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)
{
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);
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)
{
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);
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)
{
}
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);
# 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;
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);
}
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);
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;
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
{
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,
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;
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);
}
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,
}
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;
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__,
_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,
{
Evas_Object *sobj;
Edje_Signal_Data *esd;
+ Elm_Translate_String_Data *ts;
INTERNAL_ENTRY
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);
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));
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);
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);
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);
#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()
*/
}
}
+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)
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__)
{
}
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);
}
/**
+ */
+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,