edje: add ability to change the language on one specific edje object.
authorkatpavalli <katpaga.a@samsung.com>
Mon, 1 Jun 2015 15:38:04 +0000 (17:38 +0200)
committerCedric BAIL <cedric@osg.samsung.com>
Mon, 1 Jun 2015 15:50:02 +0000 (17:50 +0200)
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>
src/examples/edje/edje-text.c
src/examples/edje/en_IN/domain_name.mo
src/examples/edje/hi_IN/domain_name.mo
src/examples/edje/ta_IN/domain_name.mo
src/examples/edje/text.edc
src/lib/edje/edje_object.eo
src/lib/edje/edje_private.h
src/lib/edje/edje_text.c
src/lib/edje/edje_util.c

index 39ab128..7fc830c 100644 (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
  */
 
 #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[] = {
@@ -49,6 +50,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]);
    setenv("LANGUAGE", lang[lang_idx], 1);
@@ -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();
index f723b0c..0c1b2fc 100644 (file)
Binary files a/src/examples/edje/en_IN/domain_name.mo and b/src/examples/edje/en_IN/domain_name.mo differ
index 3abf694..3901b8c 100644 (file)
Binary files a/src/examples/edje/hi_IN/domain_name.mo and b/src/examples/edje/hi_IN/domain_name.mo differ
index 9d62bab..bee3485 100644 (file)
Binary files a/src/examples/edje/ta_IN/domain_name.mo and b/src/examples/edje/ta_IN/domain_name.mo differ
index 4c0bf30..ed0548d 100644 (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,15 @@ 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;
                }
             }
          }
@@ -86,18 +87,142 @@ collections {
             description {
                min: 50 50;
                state: "default" 0.0;
-               rel1.relative: 0.0 0.5;
-               rel2.relative: 1.0 1.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";
+               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;
+               }
+            }
+         }
+         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_en1";
+                  min: 1 1;
+                  ellipsis: -1;
+               }
+            }
+            description {
+               inherit: "default" 0.0;
+               state: "one" 0.0;
+               text {
+                  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 {
index 13f702e..3f76887 100644 (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 {
             /*@
index e5507e4..d888c36 100644 (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);
 
index 27a9ca7..a39d52c 100644 (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);
index fab4923..7c93697 100644 (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 (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;
-                    }
-               }
-          }
+        if (ed->language)
+          continue;
 
-        edje_object_signal_emit(obj, signal, "edje");
-        edje_object_calc_force(obj);
+        _edje_language_signal_emit(ed, obj, signal);
+        
      }
 }