cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=dca95fb45af216068b5476f7110639cb3715b96b

commit dca95fb45af216068b5476f7110639cb3715b96b
Author: katpavalli <katpag...@samsung.com>
Date:   Wed May 13 18:08:04 2015 +0200

    edje: support translation on static strings in edc.
    
    Summary:
       Internationalisation of the static text specified as part of the edc is 
implemented.
       Problem: Static text when specified in the edc, remains unchanged when 
the system language is changed.
       Solution: Language support is provided even for the static strings in 
the edc.
    
    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
       Compile the code with the below  command
       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`
       ./edje-text
    
       1) change the language of the system using the command
          export LANGUAGE=hi
          ./edje.text
    
          Not the text Loading gets displayed in hindi language
    
       2) change the language of the system using the command
          export LANGUAGE=ta
          ./edje.text
    
          Not the text Loading gets displayed in tamil language
    
       3) change the language of the system using the command
          export LANGUAGE=en
          ./edje.text
    
          Not the text Loading gets displayed in english language
    As the number of .mo files in the /edje folder can be increased, those many 
languages can be supported
    
    Reviewers: cedric, shilpasingh
    
    Reviewed By: shilpasingh
    
    Subscribers: cedric, rajeshps, govi, poornima.srinivasan
    
    Differential Revision: https://phab.enlightenment.org/D2336
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 AUTHORS                                |   1 +
 src/bin/edje/edje_cc.c                 |   7 ++
 src/bin/edje/edje_cc.h                 |   1 +
 src/bin/edje/edje_cc_handlers.c        | 149 +++++++++++++++++++++++++++++++++
 src/bin/edje/edje_cc_out.c             | 114 +++++++++++++++++++++++++
 src/examples/edje/Makefile.am          |   4 +-
 src/examples/edje/edje-text.c          |  23 ++++-
 src/examples/edje/en_IN/domain_name.mo | Bin 0 -> 75 bytes
 src/examples/edje/hi_IN/domain_name.mo | Bin 0 -> 101 bytes
 src/examples/edje/ta_IN/domain_name.mo | Bin 0 -> 86 bytes
 src/examples/edje/text.edc             |  78 ++++++++++++++++-
 src/lib/edje/Edje_Common.h             |  14 +++-
 src/lib/edje/edje_data.c               |  20 +++++
 src/lib/edje/edje_embryo.c             |   2 +
 src/lib/edje/edje_load.c               |  99 ++++++++++++++++++++++
 src/lib/edje/edje_main.c               |  27 +++++-
 src/lib/edje/edje_private.h            |  28 +++++++
 src/lib/edje/edje_text.c               |  61 ++++++++++++--
 src/lib/edje/edje_util.c               |  63 ++++++++++++++
 19 files changed, 672 insertions(+), 19 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 46cb69b..e9f793f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -321,6 +321,7 @@ Vorobiov Vitalii <vi.vorob...@samsung.com>
 m.biliavskyi <m.biliavs...@samsung.com>
 Vyacheslav Reutskiy <v.reuts...@samsung.com>
 Kumar Navneet <k.navn...@samsung.com>
+Katpagavalli Anantharaj <katpagava...@gmail.com>
 
 Emotion
 -------
diff --git a/src/bin/edje/edje_cc.c b/src/bin/edje/edje_cc.c
index 45b4105..690ba23 100644
--- a/src/bin/edje/edje_cc.c
+++ b/src/bin/edje/edje_cc.c
@@ -13,6 +13,7 @@ static void main_help(void);
 
 Eina_Prefix  *pfx = NULL;
 Eina_List *snd_dirs = NULL;
+Eina_List *mo_dirs = NULL;
 Eina_List *vibration_dirs = NULL;
 Eina_List *img_dirs = NULL;
 Eina_List *fnt_dirs = NULL;
@@ -98,6 +99,7 @@ main_help(void)
       "-sd sound/directory      Add a directory to look in for relative path 
sounds samples\n"
       "-vd vibration/directory  Add a directory to look in for relative path 
vibration samples\n"
       "-dd data/directory       Add a directory to look in for relative path 
data.file entries\n"
+      "-md mo/directory         Add a directory to look in for relative path 
mo files\n"
       "-td temp/directory       Directory to store temporary files\n"
       "-l license               Specify the license of a theme (file with 
license text)\n"
       "-a authors               Specify AUTHORS (file with list of authors)\n"
@@ -210,6 +212,11 @@ main(int argc, char **argv)
              i++;
              snd_dirs = eina_list_append(snd_dirs, argv[i]);
           }
+        else if ((!strcmp(argv[i], "-md") || !strcmp(argv[i], "--mo_dir")) && 
(i < (argc - 1)))
+          {
+             i++;
+             mo_dirs = eina_list_append(mo_dirs, argv[i]);
+          }
         else if ((!strcmp(argv[i], "-vd") || !strcmp(argv[i], 
"--vibration_dir")) && (i < (argc - 1)))
           {
              i++;
diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h
index 5efb076..6b1e16c 100644
--- a/src/bin/edje/edje_cc.h
+++ b/src/bin/edje/edje_cc.h
@@ -253,6 +253,7 @@ extern Eina_List             *ext_dirs;
 extern Eina_List             *img_dirs;
 extern Eina_List             *fnt_dirs;
 extern Eina_List             *snd_dirs;
+extern Eina_List             *mo_dirs;
 extern Eina_List             *vibration_dirs;
 extern Eina_List             *data_dirs;
 extern char                  *file_in;
diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index 78d11bb..21751d3 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -343,6 +343,7 @@ static void 
st_collections_group_parts_part_description_color(void);
 static void st_collections_group_parts_part_description_color2(void);
 static void st_collections_group_parts_part_description_color3(void);
 static void st_collections_group_parts_part_description_text_text(void);
+static void st_collections_group_parts_part_description_text_domain(void);
 static void st_collections_group_parts_part_description_text_text_class(void);
 static void st_collections_group_parts_part_description_text_font(void);
 static void st_collections_group_parts_part_description_text_style(void);
@@ -460,6 +461,8 @@ static void st_collections_group_sound_tone(void);
 static void st_collections_group_vibration_sample_name(void);
 static void st_collections_group_vibration_sample_source(void);
 
+static void st_collections_group_translation_file_locale(void);
+static void st_collections_group_translation_file_source(void);
 #ifdef HAVE_EPHYSICS
 static void st_collections_group_physics_world_gravity(void);
 static void st_collections_group_physics_world_rate(void);
@@ -620,6 +623,10 @@ New_Statement_Handler statement_handlers[] =
      {"collections.font", st_fonts_font}, /* dup */
      FONT_STYLE_CC_STATEMENTS("collections.")
      {"collections.base_scale", st_collections_base_scale},
+     {"collections.translation.file.locale", 
st_collections_group_translation_file_locale},
+     {"collections.translation.file.source", 
st_collections_group_translation_file_source},
+     {"collections.group.translation.file.locale", 
st_collections_group_translation_file_locale},
+     {"collections.group.translation.file.source", 
st_collections_group_translation_file_source},
 
      {"collections.sounds.sample.name", 
st_collections_group_sound_sample_name},
      {"collections.sounds.sample.source", 
st_collections_group_sound_sample_source},
@@ -783,6 +790,7 @@ New_Statement_Handler statement_handlers[] =
      {"collections.group.parts.part.description.color2", 
st_collections_group_parts_part_description_color2},
      {"collections.group.parts.part.description.color3", 
st_collections_group_parts_part_description_color3},
      {"collections.group.parts.part.description.text.text", 
st_collections_group_parts_part_description_text_text},
+     {"collections.group.parts.part.description.text.domain", 
st_collections_group_parts_part_description_text_domain},
      {"collections.group.parts.part.description.text.text_class", 
st_collections_group_parts_part_description_text_text_class},
      {"collections.group.parts.part.description.text.font", 
st_collections_group_parts_part_description_text_font},
      {"collections.group.parts.part.description.text.style", 
st_collections_group_parts_part_description_text_style},
@@ -1095,6 +1103,10 @@ New_Object_Handler object_handlers[] =
      {"collections.sounds", NULL},
      {"collections.group.sounds", NULL}, /* dup */
      {"collections.sounds.sample", NULL},
+     {"collections.translation", NULL},
+     {"collections.translation.file", NULL},
+     {"collections.group.translation", NULL},/*dup*/
+     {"collections.group.translation.file", NULL},/*dup*/
      {"collections.group.sounds.sample", NULL}, /* dup */
      {"collections.vibrations", NULL},
      {"collections.group.vibrations", NULL}, /* dup */
@@ -3032,6 +3044,109 @@ st_collections_group_vibration_sample_source(void)
    check_arg_count(1);
 }
 
+/** @edcsubsection{collections_translation_file,
+ *                 translation.file} */
+
+/**
+    @page edcref
+    @block
+        file
+    @context
+        translation {
+            ..
+            file {
+                locale: "en_IN";
+                source: "domain_name.mo";
+            }
+            file {
+                locale: "en_US";
+                source: "domain_name.mo";
+            }
+        }
+    @description
+        The file block defines the mo file.
+    @endblock
+    @property
+        name
+    @parameters
+        [locale name] 
+    @effect
+        Used to include each mo file. The full path to the directory holding
+        the mo file can be defined later with edje_cc's "-md" option.
+
+    @since 1.15
+    @endproperty
+ */
+static void
+st_collections_group_translation_file_locale(void)
+{
+   Edje_Mo *mo_entry;
+   const char *tmp;
+   unsigned int i;
+
+   check_arg_count(1);
+
+   if (!edje_file->mo_dir)
+      edje_file->mo_dir = mem_alloc(SZ(Edje_Mo_Directory));
+
+   tmp = parse_str(0);
+
+   for (i = 0; i < edje_file->mo_dir->mo_entries_count; i++)
+     {
+        if (!strcmp(edje_file->mo_dir->mo_entries[i].locale, tmp))
+          {
+             free((char *)tmp);
+             return;
+          }
+     }
+
+   edje_file->mo_dir->mo_entries_count++;
+   mo_entry = realloc(edje_file->mo_dir->mo_entries, sizeof(Edje_Mo) * 
edje_file->mo_dir->mo_entries_count);
+
+   if (!mo_entry)
+     {
+        ERR("No enough memory.");
+        exit(-1);
+     }
+   edje_file->mo_dir->mo_entries = mo_entry;
+
+   mo_entry = edje_file->mo_dir->mo_entries + 
edje_file->mo_dir->mo_entries_count - 1;
+   memset(mo_entry, 0, sizeof (Edje_Mo));
+
+   mo_entry->locale = tmp;
+   mo_entry->id = edje_file->mo_dir->mo_entries_count - 1;
+}
+
+/**
+    @page edcref
+    @property
+        source
+    @parameters
+        [mo file name]
+    @effect
+        The mo source file name (Source should be a valid mo file.
+        Only mo files are supported now)
+    @since 1.15
+    @endproperty
+ */
+
+static void
+st_collections_group_translation_file_source(void)
+{
+   Edje_Mo *mo_entry;
+
+   check_arg_count(1);
+
+   if (!edje_file->mo_dir->mo_entries)
+     {
+        ERR("Invalid mo source definition.");
+        exit(-1);
+     }
+
+   mo_entry = edje_file->mo_dir->mo_entries + 
edje_file->mo_dir->mo_entries_count - 1;
+   mo_entry->mo_src = parse_str(0);
+}
+
 static void
 _link_combine(void)
 {
@@ -6540,6 +6655,7 @@ st_collections_group_parts_part_description_inherit(void)
               ted->text = tparent->text;
 
               ted->text.text.str = STRDUP(ted->text.text.str);
+              ted->text.domain = STRDUP(ted->text.domain);
               ted->text.text_class = STRDUP(ted->text.text_class);
               ted->text.font.str = STRDUP(ted->text.font.str);
               ted->text.filter.str = STRDUP(ted->text.filter.str);
@@ -8247,6 +8363,7 @@ 
st_collections_group_parts_part_description_fill_size_offset(void)
                 ..
                 text {
                     text:        "some string of text to display";
+                    domain:      "domain_name";
                     font:        "font_name";
                     size:         SIZE;
                     text_class:  "class_name";
@@ -8308,6 +8425,38 @@ 
st_collections_group_parts_part_description_text_text(void)
    ed->text.text.str = str;
 }
 
+/** @edcsubsection{collections_group_parts_description_domain,
+ *                 Group.Parts.Part.Description.Domain} */
+
+/**
+    @page edcref
+
+    @property
+        domain
+    @parameters
+        [domain name]
+    @effect
+        This is the domain name of the .mo file which has to be checked
+        for translation.
+    @endproperty
+*/
+static void
+st_collections_group_parts_part_description_text_domain(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+        file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.domain = parse_str(0);
+}
 /**
     @page edcref
 
diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c
index e162707..95798fb 100755
--- a/src/bin/edje/edje_cc_out.c
+++ b/src/bin/edje/edje_cc_out.c
@@ -116,6 +116,7 @@ typedef struct _Head_Write Head_Write;
 typedef struct _Fonts_Write Fonts_Write;
 typedef struct _Image_Write Image_Write;
 typedef struct _Sound_Write Sound_Write;
+typedef struct _Mo_Write Mo_Write;
 typedef struct _Vibration_Write Vibration_Write;
 typedef struct _Group_Write Group_Write;
 typedef struct _License_Write License_Write;
@@ -164,6 +165,13 @@ struct _Sound_Write
    int i;
 };
 
+struct _Mo_Write
+{
+   Eet_File *ef;
+   Edje_Mo *mo_entry;
+   char *errstr;
+};
+
 struct _Vibration_Write
 {
    Eet_File *ef;
@@ -1170,6 +1178,109 @@ data_write_sounds(Eet_File *ef, int *sound_num)
 }
 
 static void
+data_thread_mo(void *data, Ecore_Thread *thread EINA_UNUSED)
+{
+   Mo_Write *mw = data;
+   char buf[PATH_MAX];
+   Eina_List *ll;
+
+   char *dir_path = NULL;
+   char mo_path[PATH_MAX];
+   char moid_str[50];
+   Eina_File *f = NULL;
+   void *m = NULL;
+   int bytes = 0;
+
+   // Search the mo file in all the -md ( mo directory )
+   EINA_LIST_FOREACH(mo_dirs, ll, dir_path)
+     {
+        snprintf((char *)mo_path, sizeof(mo_path), "%s/%s/%s", dir_path, 
mw->mo_entry->locale, mw->mo_entry->mo_src);
+        f = eina_file_open(mo_path, 0);
+        if (f) break;
+     }
+   if (!f)
+     {
+        snprintf((char *)mo_path, sizeof(mo_path), "%s", mw->mo_entry->mo_src);
+        f = eina_file_open(mo_path, 0);
+     }
+
+   if (f) using_file(mo_path, 'S');
+
+   if (!f)
+     {
+         snprintf(buf, sizeof(buf), "Unable to load mo data of: %s", mo_path);
+         ERR("%s", buf);
+         mw->errstr = strdup(buf);
+         exit(-1);
+     }
+
+   snprintf(moid_str, sizeof(moid_str), "edje/mo/%i/%s/LC_MESSAGES", 
mw->mo_entry->id, mw->mo_entry->locale);
+   m = eina_file_map_all(f, EINA_FILE_WILLNEED);
+   if (m)
+     {
+         bytes = eet_write(mw->ef, moid_str, m, eina_file_size_get(f), 
EET_COMPRESSION_NONE);
+         if (eina_file_map_faulted(f, m))
+           {
+              snprintf(buf, sizeof(buf), "File access error when reading '%s'",
+              eina_file_filename_get(f));
+              ERR("%s", buf);
+              mw->errstr = strdup(buf);
+              eina_file_close(f);
+              exit(-1);
+           }
+         eina_file_map_free(f, m);
+     }
+   eina_file_close(f);
+
+   INF("Wrote %9i bytes (%4iKb) for \"%s\" %s mo entry \"%s\"",
+          bytes, (bytes + 512) / 1024, moid_str, "RAW PCM", 
mw->mo_entry->locale);
+
+}
+
+static void
+data_thread_mo_end(void *data, Ecore_Thread *thread EINA_UNUSED)
+{
+   Mo_Write *mw = data;
+   pending_threads--;
+   if (pending_threads <= 0) ecore_main_loop_quit();
+   if (mw->errstr)
+     {
+       error_and_abort(mw->ef, mw->errstr);
+       free(mw->errstr);
+     }
+   free(mw);
+}
+
+
+static void
+data_write_mo(Eet_File *ef, int *mo_num)
+{
+   if ((edje_file) && (edje_file->mo_dir))
+     {
+        int i;
+
+        for (i = 0; i < (int)edje_file->mo_dir->mo_entries_count; i++)
+          {
+             Mo_Write *mw;
+
+             mw = calloc(1, sizeof(Mo_Write));
+             if (!mw) continue;
+             mw->ef = ef;
+             mw->mo_entry = &edje_file->mo_dir->mo_entries[i];
+             *mo_num += 1;
+             pending_threads++;
+             if (threads)
+               ecore_thread_run(data_thread_mo, data_thread_mo_end, NULL, mw);
+             else
+               {
+                  data_thread_mo(mw, NULL);
+                  data_thread_mo_end(mw, NULL);
+               }
+          }
+     }
+}
+
+static void
 data_thread_vibrations(void *data, Ecore_Thread *thread EINA_UNUSED)
 {
    Vibration_Write *vw = data;
@@ -1986,6 +2097,7 @@ data_write(void)
    Eet_Error err;
    int image_num = 0;
    int sound_num = 0;
+   int mo_num = 0;
    int vibration_num = 0;
    int font_num = 0;
    int collection_num = 0;
@@ -2047,6 +2159,8 @@ data_write(void)
    INF("fonts: %3.5f", ecore_time_get() - t); t = ecore_time_get();
    data_write_sounds(ef, &sound_num);
    INF("sounds: %3.5f", ecore_time_get() - t); t = ecore_time_get();
+   data_write_mo(ef, &mo_num);
+   INF("mo: %3.5f", ecore_time_get() - t); t = ecore_time_get();
    data_write_vibrations(ef, &vibration_num);
    INF("vibrations: %3.5f", ecore_time_get() - t); t = ecore_time_get();
    data_write_license(ef);
diff --git a/src/examples/edje/Makefile.am b/src/examples/edje/Makefile.am
index 3755a4d..a311c5b 100644
--- a/src/examples/edje/Makefile.am
+++ b/src/examples/edje/Makefile.am
@@ -9,6 +9,8 @@ if ENABLE_MULTISENSE
 SND_DIR = -sd $(srcdir)
 endif
 
+MO_DIR = -md $(srcdir)
+
 #put here all EDCs one needs to the examples
 EDCS = \
 edje-group.edc \
@@ -67,7 +69,7 @@ endif
 DIST_EDCS += $(PHYSICS_EDCS)
 
 .edc.edj:
-       $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) $(SND_DIR) $< $(builddir)/$(@F)
+       $(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) $(SND_DIR) $(MO_DIR) $< 
$(builddir)/$(@F)
 
 
 EDJS = $(EDCS:%.edc=%.edj)
diff --git a/src/examples/edje/edje-text.c b/src/examples/edje/edje-text.c
index 8242ea9..39ab128 100644
--- a/src/examples/edje/edje-text.c
+++ b/src/examples/edje/edje-text.c
@@ -5,7 +5,7 @@
  * buffer one). See stdout/stderr for output.
  *
  * @verbatim
- * edje_cc text.edc && gcc -o edje-text edje-text.c `pkg-config --libs 
--cflags ecore-evas edje`
+ * 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`
  * @endverbatim
  */
 
@@ -22,10 +22,18 @@
 #include <Ecore.h>
 #include <Ecore_Evas.h>
 #include <Edje.h>
+#include <locale.h>
 
 #define WIDTH  (300)
 #define HEIGHT (300)
 
+static int lang_idx = 0;
+static const char *lang[] = {
+  "en_IN",
+  "ta_IN",
+  "hi_IN"
+};
+
 static void
 _on_delete(Ecore_Evas *ee EINA_UNUSED)
 {
@@ -38,6 +46,14 @@ _on_text_change(void *data EINA_UNUSED, Evas_Object *obj, 
const char *part)
    printf("text: %s\n", edje_object_part_text_unescaped_get(obj, part));
 }
 
+static void
+_on_mouse_down(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);
+   edje_language_set(lang[lang_idx]);
+}
 int
 main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
 {
@@ -77,9 +93,9 @@ main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
    evas_object_resize(edje_obj, WIDTH - 40, HEIGHT - 40);
    evas_object_show(edje_obj);
 
+   edje_language_set("en_IN");
    edje_object_text_change_cb_set(edje_obj, _on_text_change, NULL);
-   edje_object_part_text_set(edje_obj, "part_one", "one");
-   edje_object_part_text_set(edje_obj, "part_two", "<b>two");
+   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");
@@ -87,6 +103,7 @@ main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
    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);
    ecore_evas_show(ee);
 
    ecore_main_loop_begin();
diff --git a/src/examples/edje/en_IN/domain_name.mo 
b/src/examples/edje/en_IN/domain_name.mo
new file mode 100644
index 0000000..f723b0c
Binary files /dev/null and b/src/examples/edje/en_IN/domain_name.mo differ
diff --git a/src/examples/edje/hi_IN/domain_name.mo 
b/src/examples/edje/hi_IN/domain_name.mo
new file mode 100644
index 0000000..3abf694
Binary files /dev/null and b/src/examples/edje/hi_IN/domain_name.mo differ
diff --git a/src/examples/edje/ta_IN/domain_name.mo 
b/src/examples/edje/ta_IN/domain_name.mo
new file mode 100644
index 0000000..9d62bab
Binary files /dev/null and b/src/examples/edje/ta_IN/domain_name.mo differ
diff --git a/src/examples/edje/text.edc b/src/examples/edje/text.edc
index 257a078..4c0bf30 100644
--- a/src/examples/edje/text.edc
+++ b/src/examples/edje/text.edc
@@ -18,11 +18,40 @@ 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;
+       }
+    }
       styles {
          style {
-            name: "textblock_style";
-            base: "font=Sans font_size=22 color=#600 wrap=word";
+            name: "textblock_style_en";
+            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_ta";
+            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_hi";
+            base: "font=Sans font_size=22 color=#00f wrap=word";
             tag:  "br" "\n";
             tag:  "hilight" "+ font_weight=Bold";
             tag:  "b" "+ font_weight=Bold";
@@ -40,6 +69,8 @@ collections {
                rel1.relative: 0.0 0.0;
                rel2.relative: 1.0 0.5;
                text {
+                  text : "LOADING";
+                  domain: "domain_name";
                   font: "arial";
                   size: 22;
                   min: 1 1;
@@ -58,11 +89,50 @@ collections {
                rel1.relative: 0.0 0.5;
                rel2.relative: 1.0 1.0;
                text {
-                  style: "textblock_style";
+                  style: "textblock_style_en";
+                  min: 1 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);
+            }
+         }
+      }
    }
 }
diff --git a/src/lib/edje/Edje_Common.h b/src/lib/edje/Edje_Common.h
index 4060a87..d067486 100644
--- a/src/lib/edje/Edje_Common.h
+++ b/src/lib/edje/Edje_Common.h
@@ -1913,7 +1913,8 @@ typedef enum _Edje_Action_Type
    EDJE_ACTION_TYPE_PHYSICS_STOP             = 22, /**< @since 1.8 @brief 
Physics stop action value */
    EDJE_ACTION_TYPE_PHYSICS_ROT_SET          = 23, /**< @since 1.8 @brief 
Physics rotation set action value */
    EDJE_ACTION_TYPE_VIBRATION_SAMPLE         = 24, /**< @since 1.10 @brief 
vibration sample action value */
-   EDJE_ACTION_TYPE_LAST                     = 25  /**< Last action value */
+   EDJE_ACTION_TYPE_MO                       = 25, /**< @since 1.15 @brief Mo 
action value */
+   EDJE_ACTION_TYPE_LAST                     = 26  /**< Last action value */
 } Edje_Action_Type;
 
 /**
@@ -1969,6 +1970,17 @@ EAPI void         edje_freeze                     (void);
 EAPI void         edje_thaw                       (void);
 
 /**
+ * @brief Set's Edje language.
+ *
+ * This function sets the given language.
+ *
+ * @note: emits signal edje,language,"locale".
+ *
+ *
+ */
+EAPI void         edje_language_set               (const char *locale);
+
+/**
  * @}
  */
 
diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c
index f18637e..7af11c2 100644
--- a/src/lib/edje/edje_data.c
+++ b/src/lib/edje/edje_data.c
@@ -17,8 +17,10 @@ Eet_Data_Descriptor 
*_edje_edd_edje_image_directory_set_entry = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_limit = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_limit_pointer = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_sound_sample = NULL;
+Eet_Data_Descriptor *_edje_edd_edje_translation_file = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_sound_tone = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_sound_directory = NULL;
+Eet_Data_Descriptor *_edje_edd_edje_mo_directory = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_vibration_sample = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_vibration_directory = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_program = NULL;
@@ -204,8 +206,10 @@ _edje_edd_shutdown(void)
    FREED(_edje_edd_edje_limit);
    FREED(_edje_edd_edje_limit_pointer);
    FREED(_edje_edd_edje_sound_sample);
+   FREED(_edje_edd_edje_translation_file);
    FREED(_edje_edd_edje_sound_tone);
    FREED(_edje_edd_edje_sound_directory);
+   FREED(_edje_edd_edje_mo_directory);
    FREED(_edje_edd_edje_vibration_sample);
    FREED(_edje_edd_edje_vibration_directory);
    FREED(_edje_edd_edje_program);
@@ -334,6 +338,18 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_image_directory, 
Edje_Image_Directory, "entries", entries, _edje_edd_edje_image_directory_entry);
    EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_image_directory, 
Edje_Image_Directory, "sets", sets, _edje_edd_edje_image_directory_set);
 
+   /*MO*/
+
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Mo);
+   _edje_edd_edje_translation_file = eet_data_descriptor_file_new(&eddc);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_translation_file, Edje_Mo, 
"locale", locale, EET_T_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_translation_file, Edje_Mo, 
"mo_src", mo_src, EET_T_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_translation_file, Edje_Mo, 
"id", id, EET_T_INT);
+
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Mo_Directory);
+   _edje_edd_edje_mo_directory = eet_data_descriptor_file_new(&eddc);
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_mo_directory, 
Edje_Mo_Directory, "mo_entries", mo_entries, _edje_edd_edje_translation_file);
+
    /* Sound */
    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Sound_Sample);
    _edje_edd_edje_sound_sample =
@@ -432,6 +448,8 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "external_dir", 
external_dir, _edje_edd_edje_external_directory);
    EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "image_dir", 
image_dir, _edje_edd_edje_image_directory);
    EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "sound_dir", 
sound_dir, _edje_edd_edje_sound_directory);
+   EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "mo_dir", 
mo_dir, _edje_edd_edje_mo_directory);
+
    EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, 
"vibration_dir", vibration_dir, _edje_edd_edje_vibration_directory);
    EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "styles", 
styles, _edje_edd_edje_style);
    EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, 
"color_classes", color_classes, _edje_edd_edje_color_class);
@@ -815,6 +833,7 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.color3.b", text.color3.b, EET_T_UCHAR);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.color3.a", text.color3.a, EET_T_UCHAR);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.text", text.text, EET_T_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.domain", text.domain, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.text_class", text.text_class, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.style", text.style, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.font", text.font, EET_T_STRING);
@@ -849,6 +868,7 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.color3.b", text.color3.b, EET_T_UCHAR);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.color3.a", text.color3.a, EET_T_UCHAR);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.text", text.text, EET_T_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.domain", text.domain, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.text_class", text.text_class, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.style", text.style, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, 
Edje_Part_Description_Text, "text.font", text.font, EET_T_STRING);
diff --git a/src/lib/edje/edje_embryo.c b/src/lib/edje/edje_embryo.c
index c4ddf4e..b4207ea 100644
--- a/src/lib/edje/edje_embryo.c
+++ b/src/lib/edje/edje_embryo.c
@@ -1922,6 +1922,8 @@ _edje_embryo_fn_custom_state(Embryo_Program *ep, 
Embryo_Cell *params)
         text_desc->text.text_class = DUP(text_desc->text.text_class);
         text_desc->text.text.str = DUP(edje_string_get(&text_desc->text.text));
         text_desc->text.text.id = 0;
+        text_desc->text.text.translated = NULL;
+        text_desc->text.domain = DUP(text_desc->text.domain);
         text_desc->text.font.str = DUP(edje_string_get(&text_desc->text.font));
         text_desc->text.font.id = 0;
         text_desc->text.style.str = 
DUP(edje_string_get(&text_desc->text.style));
diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c
index 905aefc..b3f3519 100644
--- a/src/lib/edje/edje_load.c
+++ b/src/lib/edje/edje_load.c
@@ -50,6 +50,83 @@ _edje_smart_nested_smart_class_new(void)
    return smart;
 }
 
+void
+_edje_extract_mo_files(Edje *ed)
+{
+   Eina_Strbuf *mo_id_str;
+   const void *data;
+   const char *cache_path;
+   const char *filename;
+   unsigned int crc;
+   time_t t;
+   size_t sz;
+   unsigned int i;
+   int len;
+
+   cache_path = efreet_cache_home_get();
+
+   t = eina_file_mtime_get(ed->file->f);
+   sz = eina_file_size_get(ed->file->f);
+   filename = eina_file_filename_get(ed->file->f);
+   crc = eina_crc(filename, strlen(filename), 0xffffffff, EINA_TRUE);
+
+   snprintf(ed->file->fid, sizeof(ed->file->fid), "%lld-%lld-%x",
+            (long long int)t,
+            (long long int)sz,
+            crc);
+
+   mo_id_str = eina_strbuf_new();
+
+   for (i = 0; i < ed->file->mo_dir->mo_entries_count; i++)
+     {
+        Edje_Mo *mo_entry;
+        char out[PATH_MAX];
+        char outdir[PATH_MAX];
+
+        mo_entry = &ed->file->mo_dir->mo_entries[i];
+
+        eina_strbuf_append_printf(mo_id_str,
+                                  "edje/mo/%i/%s/LC_MESSAGES",
+                                  mo_entry->id,
+                                  mo_entry->locale);
+        data = eet_read_direct(ed->file->ef,
+                               eina_strbuf_string_get(mo_id_str),
+                               &len);
+
+        if (data)
+          {
+             snprintf(outdir, sizeof(outdir),
+                      "%s/edje/%s/LC_MESSAGES",
+                      cache_path, mo_entry->locale);
+             ecore_file_mkpath(outdir);
+             snprintf(out, sizeof(out), "%s/%s-%s",
+                      outdir, ed->file->fid, mo_entry->mo_src);
+             if (ecore_file_exists(out))
+               {
+                  if (ed->file->mtime > ecore_file_mod_time(out))
+                    ecore_file_remove(out);
+               }
+             if (!ecore_file_exists(out))
+               {
+                  FILE *f;
+
+                  f = fopen(out, "wb");
+                  if (f)
+                    {
+                       if (fwrite(data, len, 1, f) != 1)
+                         ERR("Could not write mo: %s: %s", out, 
strerror(errno));
+                       fclose(f);
+                    }
+                  else
+                    ERR("Could not open for writing mo: %s: %s", out, 
strerror(errno));
+               }
+          }
+
+        eina_strbuf_reset(mo_id_str);
+     }
+
+   eina_strbuf_free(mo_id_str);
+}
 
 Evas_Object *
 edje_smart_nested_add(Evas *evas)
@@ -389,6 +466,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const 
Eina_File *file, const ch
    Eina_Array parts;
    int group_path_started = 0;
    Evas_Object *nested_smart = NULL;
+   char lang[PATH_MAX];
 
    /* Get data pointer of top-of-stack */
    int idx = eina_array_count(nested) - 1;
@@ -441,6 +519,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const 
Eina_File *file, const ch
    _edje_textblock_style_all_update(ed);
 
    ed->has_entries = EINA_FALSE;
+   if (ed->file && ed->file->mo_dir)
+     _edje_extract_mo_files(ed);
 
    if (ed->collection)
      {
@@ -1103,6 +1183,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const 
Eina_File *file, const ch
                       }
                  }
 
+               snprintf(lang, sizeof(lang), "edje,language,%s", 
_edje_language);
+               edje_object_signal_emit(obj, lang, "edje");
+
                if (edje_object_mirrored_get(obj))
                  edje_object_signal_emit(obj, "edje,state,rtl", "edje");
                else
@@ -1591,6 +1674,21 @@ _edje_file_free(Edje_File *edf)
         free(edf->vibration_dir);
      }
 
+   if (edf->mo_dir)
+     {
+        unsigned int i;
+        if (edf->free_strings)
+          {
+             for (i = 0; i < edf->mo_dir->mo_entries_count; ++i)
+               {
+                  eina_stringshare_del(edf->mo_dir->mo_entries[i].locale);
+                  eina_stringshare_del(edf->mo_dir->mo_entries[i].mo_src);
+               }
+          }
+        free(edf->mo_dir->mo_entries);
+        free(edf->mo_dir);
+   }
+
    if (edf->external_dir)
      {
         if (edf->external_dir->entries) free(edf->external_dir->entries);
@@ -1773,6 +1871,7 @@ _edje_collection_free_part_description_clean(int type, 
Edje_Part_Description_Com
               text = (Edje_Part_Description_Text *) desc;
 
               eina_stringshare_del(text->text.text.str);
+              eina_stringshare_del(text->text.domain);
               eina_stringshare_del(text->text.text_class);
               eina_stringshare_del(text->text.style.str);
               eina_stringshare_del(text->text.font.str);
diff --git a/src/lib/edje/edje_main.c b/src/lib/edje/edje_main.c
index cbb8d46..9c474dc 100644
--- a/src/lib/edje/edje_main.c
+++ b/src/lib/edje/edje_main.c
@@ -27,6 +27,8 @@ static const Edje_Calc_Params_Physics default_calc_physics = {
 EAPI int
 edje_init(void)
 {
+   Eina_Strbuf *str;
+
    if (++_edje_init_count != 1)
      return _edje_init_count;
 
@@ -64,7 +66,13 @@ edje_init(void)
    if (!evas_init())
      {
        ERR("Evas init failed");
-       goto shutdown_embryo;
+       goto shutdown_eet;
+     }
+
+   if (!efreet_init())
+     {
+        ERR("Efreet init failed");
+        goto shutdown_evas;
      }
 
    _edje_scale = FROM_DOUBLE(1.0);
@@ -99,6 +107,13 @@ edje_init(void)
    _edje_calc_params_map_cow = eina_cow_add("Edje Calc Params Map", sizeof 
(Edje_Calc_Params_Map), 8, &default_calc_map, EINA_TRUE);
    _edje_calc_params_physics_cow= eina_cow_add("Edje Calc Params Physics", 
sizeof (Edje_Calc_Params_Physics), 8, &default_calc_physics, EINA_TRUE);
 
+   _edje_language = eina_stringshare_add(getenv("LANGUAGE"));
+
+   str = eina_strbuf_new();
+   eina_strbuf_append_printf(str, "%s/edje", efreet_cache_home_get());
+   _edje_cache_path = eina_stringshare_add(eina_strbuf_string_get(str));
+   eina_strbuf_free(str);
+
    eina_log_timing(_edje_default_log_dom,
                   EINA_LOG_STATE_STOP,
                   EINA_LOG_STATE_INIT);
@@ -117,6 +132,10 @@ edje_init(void)
    _edje_text_class_members_free();
    _edje_text_class_hash_free();
    _edje_edd_shutdown();
+   efreet_shutdown();
+ shutdown_evas:
+   evas_shutdown();
+ shutdown_eet:
    eet_shutdown();
  shutdown_embryo:
    embryo_shutdown();
@@ -145,6 +164,11 @@ _edje_shutdown_core(void)
    _edje_color_class_members_free();
    _edje_color_class_hash_free();
 
+   eina_stringshare_del(_edje_cache_path);
+   eina_stringshare_del(_edje_language);
+   _edje_cache_path = NULL;
+   _edje_language = NULL;
+
    eina_mempool_del(_edje_real_part_state_mp);
    eina_mempool_del(_edje_real_part_mp);
    _edje_real_part_state_mp = NULL;
@@ -170,6 +194,7 @@ _edje_shutdown_core(void)
      ecore_imf_shutdown();
 #endif
 
+   efreet_shutdown();
    evas_shutdown();
    eet_shutdown();
    embryo_shutdown();
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index 5d9592b..d3e120c 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -14,6 +14,10 @@
 # endif
 #endif
 
+#ifdef ENABLE_NLS
+# include <libintl.h>
+#endif
+
 #include <locale.h>
 #include <libgen.h>
 #include <string.h>
@@ -48,6 +52,7 @@
 # include <Ecore_IMF_Evas.h>
 #endif
 #include <Embryo.h>
+#include <Efreet.h>
 
 #ifdef HAVE_EIO
 # include <Eio.h>
@@ -277,6 +282,7 @@ struct _Edje_Aspect
 struct _Edje_String
 {
    const char *str;
+   const char *translated;
    unsigned int id;
 };
 
@@ -324,6 +330,9 @@ typedef struct _Edje_Plugin                          
Edje_Plugin;
 typedef struct _Edje_Sound_Sample                    Edje_Sound_Sample;
 typedef struct _Edje_Sound_Tone                      Edje_Sound_Tone;
 typedef struct _Edje_Sound_Directory                 Edje_Sound_Directory;
+typedef struct _Edje_Mo                              Edje_Mo;
+typedef struct _Edje_Mo_Directory                    Edje_Mo_Directory;
+
 typedef struct _Edje_Vibration_Sample                Edje_Vibration_Sample;
 typedef struct _Edje_Vibration_Directory             Edje_Vibration_Directory;
 typedef struct _Edje_Program                         Edje_Program;
@@ -527,6 +536,7 @@ struct _Edje_File
    Edje_Model_Directory           *model_dir;
    Edje_Sound_Directory           *sound_dir;
    Edje_Vibration_Directory       *vibration_dir;
+   Edje_Mo_Directory              *mo_dir;
 
    Eina_List                      *styles;
 
@@ -550,6 +560,7 @@ struct _Edje_File
 
    Eet_File                       *ef;
    Eina_File                      *f;
+   char                            fid[8+8+8+2];
 
    unsigned char                   free_strings : 1;
    unsigned char                   dangling : 1;
@@ -687,6 +698,19 @@ struct _Edje_Sound_Directory
    unsigned int tones_count;
 };
 
+struct _Edje_Mo /*Mo Sample*/
+{
+   const char *locale; /* the nominal name of the Mo */
+   const char *mo_src;  /* Mo source file */
+   int   id; /* the id no. of the Mo file */
+};
+
+struct _Edje_Mo_Directory
+{
+   Edje_Mo *mo_entries;  /* an array of Edje_Mo entries */
+   unsigned int mo_entries_count;
+};
+
 struct _Edje_Vibration_Sample
 {
    const char *name;
@@ -1281,6 +1305,7 @@ struct _Edje_Part_Description_Spec_Proxy
 struct _Edje_Part_Description_Spec_Text
 {
    Edje_String    text; /* if "" or NULL, then leave text unchanged */
+   char          *domain;
    char          *text_class; /* how to apply/modify the font */
    Edje_String    style; /* the text style if a textblock */
    Edje_String    font; /* if a specific font is asked for */
@@ -2156,6 +2181,9 @@ extern Eina_Cow *_edje_calc_params_physics_cow;
 
 extern Eina_Hash       *_edje_file_hash;
 
+extern const char      *_edje_language;
+extern const char      *_edje_cache_path;
+
 EAPI extern Eina_Mempool *_emp_RECTANGLE;
 EAPI extern Eina_Mempool *_emp_TEXT;
 EAPI extern Eina_Mempool *_emp_IMAGE;
diff --git a/src/lib/edje/edje_text.c b/src/lib/edje/edje_text.c
index 057d6d0..27a9ca7 100644
--- a/src/lib/edje/edje_text.c
+++ b/src/lib/edje/edje_text.c
@@ -14,6 +14,7 @@
  * function everywhere instead of calling evas_object_geometry_get()
  * directly.
  */
+
 static inline void
 part_get_geometry(Edje_Real_Part *rp, Evas_Coord *w, Evas_Coord *h)
 {
@@ -26,6 +27,38 @@ part_get_geometry(Edje_Real_Part *rp, Evas_Coord *w, 
Evas_Coord *h)
      }
 }
 
+const char *
+_set_translated_string(Edje *ed, Edje_Real_Part *ep)
+{
+   const char *domain = NULL;
+   const char *text = NULL;
+   Edje_Part_Description_Text *chosen_desc;
+
+   chosen_desc = (Edje_Part_Description_Text*)ep->chosen_description;
+   domain = chosen_desc->text.domain;
+   text = edje_string_get(&chosen_desc->text.text);
+
+   if (domain && text)
+     {
+#ifdef ENABLE_NLS
+        char p[PATH_MAX];
+        char *curpath;
+        char *curlocale;
+
+        snprintf(p, sizeof(p), "%s-%s", ed->file->fid, domain);
+
+        curlocale = setlocale(LC_ALL, "");
+        curpath = bindtextdomain(p, _edje_cache_path);
+
+        text = dgettext(p, text);
+
+        bindtextdomain(p, curpath);
+        setlocale(LC_ALL, curlocale);
+#endif
+     }
+   return text;
+}
+
 void
 _edje_text_init(void)
 {
@@ -162,18 +195,18 @@ void
 _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
                         Edje_Calc_Params *params,
                         Edje_Part_Description_Text *chosen_desc,
-                       Eina_Bool calc_only)
+                        Eina_Bool calc_only)
 {
-   const char  *text = NULL;
-   const char  *font;
-   char                *font2 = NULL;
+   const char   *text = NULL;
+   const char   *font;
+   char         *font2 = NULL;
    char         *sfont = NULL;
-   int          size;
+   int           size;
    const char   *filter, *source_name;
    Eina_List    *filter_sources = NULL, *prev_sources = NULL, *li;
-   Evas_Coord   tw, th;
-   Evas_Coord   sw, sh;
-   int          inlined_font = 0, free_text = 0;
+   Evas_Coord    tw, th;
+   Evas_Coord    sw, sh;
+   int           inlined_font = 0, free_text = 0;
    Eina_Bool     same_text = EINA_FALSE;
    FLOAT_T       sc;
 
@@ -181,7 +214,17 @@ _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
        (!ep->typedata.text)) return;
    sc = DIV(ed->scale, ed->file->base_scale);
    if (sc == ZERO) sc = DIV(_edje_scale, ed->file->base_scale);
-   text = edje_string_get(&chosen_desc->text.text);
+
+   if (chosen_desc->text.domain)
+     {
+        if (!chosen_desc->text.text.translated)
+          chosen_desc->text.text.translated = _set_translated_string(ed, ep);
+        if (chosen_desc->text.text.translated)
+          text = chosen_desc->text.text.translated;
+     }
+
+   if (!text)
+     text = edje_string_get(&chosen_desc->text.text);
    font = _edje_text_class_font_get(ed, chosen_desc, &size, &sfont);
    filter = chosen_desc->text.filter.str;
 
diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c
index cec0ffb..fab4923 100644
--- a/src/lib/edje/edje_util.c
+++ b/src/lib/edje/edje_util.c
@@ -28,6 +28,9 @@ int _edje_util_freeze_val = 0;
 int _edje_util_freeze_calc_count = 0;
 Eina_List *_edje_util_freeze_calc_list = NULL;
 
+const char *_edje_language = NULL;
+const char *_edje_cache_path = NULL;
+
 typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
 struct _Edje_List_Foreach_Data
 {
@@ -297,6 +300,66 @@ _edje_util_thaw_edje(Edje *ed)
 #endif
 
 EAPI void
+edje_language_set(const char *locale)
+{
+   Evas_Object *obj;
+   Eina_List *l;
+   const char *lookup;
+   char *signal;
+   char *loc;
+   int length;
+
+   lookup = strstr(locale, ".");
+   length = lookup ? lookup - locale : (int) strlen(locale);
+   loc = alloca(length + 1);
+   memcpy(loc, locale, length);
+   loc[length] = '\0';
+
+   eina_stringshare_replace(&_edje_language, loc);
+
+   signal = alloca(length + 15);
+   snprintf(signal, length + 15, "edje,language,%s", loc);
+
+   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;
+                    }
+               }
+          }
+
+        edje_object_signal_emit(obj, signal, "edje");
+        edje_object_calc_force(obj);
+     }
+}
+
+EAPI void
 edje_thaw(void)
 {
 #ifdef FASTFREEZE

-- 


Reply via email to