edje: add ability to change the language on one specific edje object.

Summary:
   Add a new property to edje_object.eo for setting the language on one Edje_Object.

Test Plan:
Test Code to test this implementation is done as part of efl/src/examples/edje/edje-text.c and efl/src/examples/edje/text.edc
   edje_cc -md <dir path>/efl/src/examples/edje/ text.edc && gcc -o edje-text edje-text.c `pkg-config --libs --cflags ecore-evas edje evas ecore eo`
   ./edje-text

   1) Click On the text "Click here"
      The language gets changed as per the specific edje object.

   2) Click on the text object at bottom. "Click here"
      The system language gets changed and the below two edje objects language are changed globally.

Reviewers: cedric, shilpasingh

Subscribers: poornima.srinivasan, govi, rajeshps, cedric

Differential Revision: https://phab.enlightenment.org/D2559

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
katpavalli 2015-06-01 17:38:04 +02:00 committed by Cedric BAIL
parent cae31f824a
commit ff1184df2e
9 changed files with 556 additions and 65 deletions

View File

@ -5,7 +5,7 @@
* buffer one). See stdout/stderr for output.
*
* @verbatim
* edje_cc -md ~/efl/src/examples/edje/ text.edc && gcc -o edje-text edje-text.c `pkg-config --libs --cflags ecore-evas edje evas ecore`
* edje_cc -md . text.edc && gcc -o edje-text edje-text.c `pkg-config --libs --cflags ecore-evas edje evas ecore eo`
* @endverbatim
*/
@ -23,9 +23,10 @@
#include <Ecore_Evas.h>
#include <Edje.h>
#include <locale.h>
#include "Eo.h"
#define WIDTH (300)
#define HEIGHT (300)
#define WIDTH (500)
#define HEIGHT (500)
static int lang_idx = 0;
static const char *lang[] = {
@ -48,6 +49,18 @@ _on_text_change(void *data EINA_UNUSED, Evas_Object *obj, const char *part)
static void
_on_mouse_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
{
char *env;
lang_idx = (lang_idx + 1) % (sizeof (lang) / sizeof (lang[0]));
fprintf(stderr, "Setting lang of this edje object to '%s'\n", lang[lang_idx]);
env = getenv("LANGUAGE");
setenv("LANGUAGE", lang[lang_idx], 1);
eo_do(o, edje_obj_language_set(lang[lang_idx]));
setenv("LANGUAGE", env, 1);
}
static void
_on_mouse_down_text(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
{
lang_idx = (lang_idx + 1) % (sizeof (lang)/ sizeof (lang[0]));
fprintf(stderr, "Setting lang to '%s'\n", lang[lang_idx]);
@ -62,6 +75,9 @@ main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
Evas *evas;
Evas_Object *bg;
Evas_Object *edje_obj;
Evas_Object *edje_obj_one;
Evas_Object *edje_obj_two;
Evas_Object *edje_obj_three;
if (!ecore_evas_init())
return EXIT_FAILURE;
@ -87,23 +103,66 @@ main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
edje_obj = edje_object_add(evas);
edje_object_file_set(edje_obj, edje_file, "example_group");
evas_object_move(edje_obj, 20, 20);
evas_object_move(edje_obj, 0, 20);
evas_object_resize(edje_obj, WIDTH - 40, HEIGHT - 40);
evas_object_show(edje_obj);
edje_language_set("en_IN");
setenv("LANGUAGE", "en_IN", 1);
eo_do(edje_obj, edje_obj_language_set("en_IN"));
edje_object_text_change_cb_set(edje_obj, _on_text_change, NULL);
edje_object_part_text_set(edje_obj, "part_two", "<b>Click here");
edje_object_part_text_select_allow_set(edje_obj, "part_two", EINA_TRUE);
edje_object_part_text_select_all(edje_obj, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj, "part_two"));
edje_object_part_text_select_none(edje_obj, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj, "part_two"));
evas_object_event_callback_add(edje_obj, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, NULL);
edje_obj_one = edje_object_add(evas);
edje_object_file_set(edje_obj_one, edje_file, "example_group1");
evas_object_move(edje_obj_one, 0, 50);
evas_object_resize(edje_obj_one, WIDTH - 40, HEIGHT - 40);
evas_object_show(edje_obj_one);
eo_do(edje_obj_one, edje_obj_language_set("en_IN"));
edje_object_text_change_cb_set(edje_obj_one, _on_text_change, NULL);
edje_object_part_text_set(edje_obj_one, "part_two", "<b>Click here");
edje_object_part_text_select_allow_set(edje_obj_one, "part_two", EINA_TRUE);
edje_object_part_text_select_all(edje_obj_one, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj_one, "part_two"));
edje_object_part_text_select_none(edje_obj_one, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj_one, "part_two"));
evas_object_event_callback_add(edje_obj_one, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, NULL);
//Generic Language change
edje_obj_two = edje_object_add(evas);
edje_object_file_set(edje_obj_two, edje_file, "example_group2");
evas_object_move(edje_obj_two, 0, 250);
evas_object_resize(edje_obj_two, WIDTH - 40, HEIGHT - 40);
evas_object_show(edje_obj_two);
edje_language_set("en_IN");
edje_object_text_change_cb_set(edje_obj_two, _on_text_change, NULL);
edje_object_part_text_set(edje_obj_two, "part_two", "<b>Click here");
edje_object_part_text_select_allow_set(edje_obj_two, "part_two", EINA_TRUE);
edje_object_part_text_select_all(edje_obj_two, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj_two, "part_two"));
edje_object_part_text_select_none(edje_obj_two, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj_two, "part_two"));
evas_object_event_callback_add(edje_obj_two, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down_text, NULL);
edje_obj_three = edje_object_add(evas);
edje_object_file_set(edje_obj_three, edje_file, "example_group3");
evas_object_move(edje_obj_three, 0, 350);
evas_object_resize(edje_obj_three, WIDTH - 40, HEIGHT - 40);
evas_object_show(edje_obj_three);
edje_object_text_change_cb_set(edje_obj_three, _on_text_change, NULL);
edje_object_part_text_set(edje_obj_three, "part_two", "<b>Click here");
edje_object_part_text_select_allow_set(edje_obj_three, "part_two", EINA_TRUE);
edje_object_part_text_select_all(edje_obj_three, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj_three, "part_two"));
edje_object_part_text_select_none(edje_obj_three, "part_two");
printf("selection: %s\n", edje_object_part_text_selection_get(edje_obj_three, "part_two"));
evas_object_event_callback_add(edje_obj_three, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down_text, NULL);
ecore_evas_show(ee);
ecore_main_loop_begin();

View File

@ -18,20 +18,20 @@ collections {
name: "example_group";
max: 500 500;
min: 50 50;
translation {
file {
locale: en_IN;
source: domain_name.mo;
}
file {
locale: hi_IN;
source: domain_name.mo;
}
file {
locale: ta_IN;
source: domain_name.mo;
}
}
translation {
file {
locale: en_IN;
source: domain_name.mo; /* Can be either .po file or .mo file */
}
file {
locale: hi_IN;
source: domain_name.mo;
}
file {
locale: ta_IN;
source: domain_name.mo;
}
}
styles {
style {
name: "textblock_style_en";
@ -49,7 +49,7 @@ collections {
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
style {
name: "textblock_style_hi";
base: "font=Sans font_size=22 color=#00f wrap=word";
tag: "br" "\n";
@ -66,14 +66,138 @@ collections {
min: 50 50;
state: "default" 0.0;
color: 0 0 255 255; /* blue */
rel1.relative: 0.0 0.0;
rel2.relative: 1.0 0.5;
rel1.relative: 0.5 0.0;
rel2.relative: 0.5 0.0;
text {
text : "LOADING";
domain: "domain_name";
font: "arial";
size: 22;
min: 1 1;
ellipsis: -1;
}
}
}
part {
name: "part_two";
type: TEXTBLOCK;
select_mode: EXPLICIT;
source: "sel_group";
entry_mode: PLAIN;
description {
min: 50 50;
state: "default" 0.0;
rel1.relative: 0.0 0.25;
rel2.relative: 0.5 0.0;
text {
style: "textblock_style_en";
min: 1 1;
ellipsis: -1;
}
}
description {
inherit: "default" 0.0;
state: "one" 0.0;
text {
style: "textblock_style_hi";
min: 1 1;
}
}
description {
inherit: "default" 0.0;
state: "two" 0.0;
text {
style: "textblock_style_ta";
min: 1 1;
}
}
}
}
programs {
program {
signal: "edje,language,hi_IN";
source: "edje";
script {
set_state(PART:"part_two", "one", 1.0);
}
}
program {
signal: "edje,language,ta_IN";
source: "edje";
script {
set_state(PART:"part_two", "two", 1.0);
}
}
program {
signal: "edje,language,en_IN";
source: "edje";
script {
set_state(PART:"part_two", "default", 1.0);
}
}
}
}
group {
name: "example_group1";
max: 500 500;
min: 50 50;
translation {
file {
locale: en_IN;
source: domain_name.mo;
}
file {
locale: hi_IN;
source: domain_name.mo;
}
file {
locale: ta_IN;
source: domain_name.mo;
}
}
styles {
style {
name: "textblock_style_en1";
base: "font=Sans font_size=22 color=#f00 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
name: "textblock_style_ta1";
base: "font=Sans font_size=22 color=#000 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
name: "textblock_style_hi1";
base: "font=Sans font_size=22 color=#00f wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
}
parts {
part {
name: "part_one";
type: TEXT;
description {
min: 50 50;
state: "default" 0.0;
color: 0 0 255 255; /* blue */
rel1.relative: 0.5 0.25;
rel2.relative: 0.5 0.0;
text {
text : "LANG";
domain: "domain_name";
font: "arial";
size: 22;
min: 1 1;
ellipsis: -1;
}
}
}
@ -87,17 +211,18 @@ collections {
min: 50 50;
state: "default" 0.0;
rel1.relative: 0.0 0.5;
rel2.relative: 1.0 1.0;
rel2.relative: 1.0 0.0;
text {
style: "textblock_style_en";
style: "textblock_style_en1";
min: 1 1;
ellipsis: -1;
}
}
description {
inherit: "default" 0.0;
state: "one" 0.0;
text {
style: "textblock_style_hi";
style: "textblock_style_hi1";
min: 1 1;
}
}
@ -105,13 +230,13 @@ collections {
inherit: "default" 0.0;
state: "two" 0.0;
text {
style: "textblock_style_ta";
style: "textblock_style_ta1";
min: 1 1;
}
}
}
}
programs {
programs {
program {
signal: "edje,language,hi_IN";
source: "edje";
@ -119,14 +244,260 @@ collections {
set_state(PART:"part_two", "one", 1.0);
}
}
program {
program {
signal: "edje,language,ta_IN";
source: "edje";
script {
set_state(PART:"part_two", "two", 1.0);
}
}
program {
program {
signal: "edje,language,en_IN";
source: "edje";
script {
set_state(PART:"part_two", "default", 1.0);
}
}
}
}
group {
name: "example_group2";
max: 500 500;
min: 50 50;
translation {
file {
locale: en_IN;
source: domain_name.mo;
}
file {
locale: hi_IN;
source: domain_name.mo;
}
file {
locale: ta_IN;
source: domain_name.mo;
}
}
styles {
style {
name: "textblock_style_en2";
base: "font=Sans font_size=22 color=#f00 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
name: "textblock_style_ta2";
base: "font=Sans font_size=22 color=#000 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
name: "textblock_style_hi2";
base: "font=Sans font_size=22 color=#00f wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
}
parts {
part {
name: "part_one";
type: TEXT;
description {
min: 50 50;
state: "default" 0.0;
color: 0 0 255 255; /* blue */
rel1.relative: 0.5 0.25;
rel2.relative: 0.5 0.0;
text {
text : "SYSTEM LANGUAGE";
domain: "domain_name";
font: "arial";
size: 22;
min: 1 1;
ellipsis: -1;
}
}
}
part {
name: "part_two";
type: TEXTBLOCK;
select_mode: EXPLICIT;
source: "sel_group";
entry_mode: PLAIN;
description {
min: 50 50;
state: "default" 0.0;
rel1.relative: 0.0 0.5;
rel2.relative: 1.0 0.0;
text {
style: "textblock_style_en2";
min: 1 1;
ellipsis: -1;
}
}
description {
inherit: "default" 0.0;
state: "one" 0.0;
text {
style: "textblock_style_hi2";
min: 1 1;
}
}
description {
inherit: "default" 0.0;
state: "two" 0.0;
text {
style: "textblock_style_ta2";
min: 1 1;
}
}
}
}
programs {
program {
signal: "edje,language,hi_IN";
source: "edje";
script {
set_state(PART:"part_two", "one", 1.0);
}
}
program {
signal: "edje,language,ta_IN";
source: "edje";
script {
set_state(PART:"part_two", "two", 1.0);
}
}
program {
signal: "edje,language,en_IN";
source: "edje";
script {
set_state(PART:"part_two", "default", 1.0);
}
}
}
}
group {
name: "example_group3";
max: 500 500;
min: 50 50;
translation {
file {
locale: en_IN;
source: domain_name.mo;
}
file {
locale: hi_IN;
source: domain_name.mo;
}
file {
locale: ta_IN;
source: domain_name.mo;
}
}
styles {
style {
name: "textblock_style_en3";
base: "font=Sans font_size=22 color=#f00 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
name: "textblock_style_ta3";
base: "font=Sans font_size=22 color=#000 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
style {
name: "textblock_style_hi3";
base: "font=Sans font_size=22 color=#00f wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font_weight=Bold";
tag: "b" "+ font_weight=Bold";
tag: "tab" "\t";
}
}
parts {
part {
name: "part_one";
type: TEXT;
description {
min: 50 50;
state: "default" 0.0;
color: 0 0 255 255; /* blue */
rel1.relative: 0.5 0.25;
rel2.relative: 0.5 0.0;
text {
text : "CHANGED";
domain: "domain_name";
font: "arial";
size: 22;
min: 1 1;
ellipsis: -1;
}
}
}
part {
name: "part_two";
type: TEXTBLOCK;
select_mode: EXPLICIT;
source: "sel_group";
entry_mode: PLAIN;
description {
min: 50 50;
state: "default" 0.0;
rel1.relative: 0.0 0.5;
rel2.relative: 1.0 0.0;
text {
style: "textblock_style_en3";
min: 1 1;
ellipsis: -1;
}
}
description {
inherit: "default" 0.0;
state: "one" 0.0;
text {
style: "textblock_style_hi3";
min: 1 1;
}
}
description {
inherit: "default" 0.0;
state: "two" 0.0;
text {
style: "textblock_style_ta3";
min: 1 1;
}
}
}
}
programs {
program {
signal: "edje,language,hi_IN";
source: "edje";
script {
set_state(PART:"part_two", "one", 1.0);
}
}
program {
signal: "edje,language,ta_IN";
source: "edje";
script {
set_state(PART:"part_two", "two", 1.0);
}
}
program {
signal: "edje,language,en_IN";
source: "edje";
script {

View File

@ -44,6 +44,24 @@ class Edje.Object (Evas.Smart_Clipped, Efl.File)
rtl: bool; /*@ new value of flag EINA_TRUE/EINA_FALSE */
}
}
@property language {
set {
/*@
@brief Set the language for this object.
@since 1.1.0 */
}
get {
/*@
@brief Get the language for this object.
@return @c language.
@since 1.1.0 */
}
values {
language: const(char)*; /*@ The language value */
}
}
@property animation {
set {
/*@

View File

@ -1525,6 +1525,7 @@ struct _Edje
const char *path;
const char *group;
const char *parent;
const char *language;
Evas_Object *obj; /* the smart object */
Edje_File *file; /* the file the data comes form */
@ -2664,6 +2665,8 @@ void _edje_object_orientation_inform(Evas_Object *obj);
void _edje_lib_ref(void);
void _edje_lib_unref(void);
void _edje_language_signal_emit(Edje *ed, Evas_Object *obj, char *signal);
void _edje_subobj_register(Edje *ed, Evas_Object *ob);
void _edje_subobj_unregister(Edje *ed, Evas_Object *ob);

View File

@ -48,8 +48,10 @@ _set_translated_string(Edje *ed, Edje_Real_Part *ep)
snprintf(p, sizeof(p), "%s-%s", ed->file->fid, domain);
curlocale = setlocale(LC_ALL, "");
curpath = bindtextdomain(p, _edje_cache_path);
if (ed->language)
setlocale(LC_ALL, ed->language);
curpath = bindtextdomain(p, _edje_cache_path);
text = dgettext(p, text);
bindtextdomain(p, curpath);

View File

@ -299,6 +299,71 @@ _edje_util_thaw_edje(Edje *ed)
}
#endif
void
_edje_language_signal_emit(Edje *ed, Evas_Object *obj, char *signal)
{
int i;
for (i = 0; i < (int)ed->table_parts_size; i++)
{
Edje_Real_Part *rp = ed->table_parts[i];
if (rp->part->type == EDJE_PART_TYPE_TEXT ||
rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
{
Edje_Part_Description_Text *text;
text = (Edje_Part_Description_Text *) rp->param1.description;
if (text->text.text.translated)
text->text.text.translated = NULL;
if (rp->param2)
{
text = (Edje_Part_Description_Text *) rp->param2->description;
if (text->text.text.translated)
text->text.text.translated = NULL;
}
if (rp->custom)
{
text = (Edje_Part_Description_Text *) rp->custom->description;
if (text->text.text.translated)
text->text.text.translated = NULL;
}
}
}
edje_object_signal_emit(obj, signal, "edje");
edje_object_calc_force(obj);
}
EOLIAN void
_edje_object_language_set(Eo *obj, Edje *ed, const char *locale)
{
const char *lookup;
char *signal;
size_t length;
lookup = strstr(locale, ".");
length = lookup ? (size_t)(lookup - locale) : strlen(locale);
eina_stringshare_replace_length(&ed->language, locale, length);
signal = alloca(length + 15);
snprintf(signal, length + 15, "edje,language,%s", ed->language);
_edje_language_signal_emit(ed, obj, signal);
}
EOLIAN const char*
_edje_object_language_get(Eo *obj EINA_UNUSED, Edje *ed)
{
if (!ed->language)
return _edje_language;
return ed->language;
}
EAPI void
edje_language_set(const char *locale)
{
@ -323,39 +388,12 @@ edje_language_set(const char *locale)
EINA_LIST_FOREACH(_edje_edjes, l, obj)
{
Edje *ed = eo_data_scope_get(obj, EDJE_OBJECT_CLASS);
unsigned int i;
for (i = 0; i < ed->table_parts_size; i++)
{
Edje_Real_Part *rp = ed->table_parts[i];
if (ed->language)
continue;
if (rp->part->type == EDJE_PART_TYPE_TEXT ||
rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
{
Edje_Part_Description_Text *text;
text = (Edje_Part_Description_Text *) rp->param1.description;
if (text->text.text.translated)
text->text.text.translated = NULL;
if (rp->param2)
{
text = (Edje_Part_Description_Text *) rp->param2->description;
if (text->text.text.translated)
text->text.text.translated = NULL;
}
if (rp->custom)
{
text = (Edje_Part_Description_Text *) rp->custom->description;
if (text->text.text.translated)
text->text.text.translated = NULL;
}
}
}
edje_object_signal_emit(obj, signal, "edje");
edje_object_calc_force(obj);
_edje_language_signal_emit(ed, obj, signal);
}
}