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 <cedric@osg.samsung.com>
This commit is contained in:
katpavalli 2015-05-13 18:08:04 +02:00 committed by Cedric BAIL
parent a312e304bf
commit dca95fb45a
19 changed files with 672 additions and 19 deletions

View File

@ -321,6 +321,7 @@ Vorobiov Vitalii <vi.vorobiov@samsung.com>
m.biliavskyi <m.biliavskyi@samsung.com>
Vyacheslav Reutskiy <v.reutskiy@samsung.com>
Kumar Navneet <k.navneet@samsung.com>
Katpagavalli Anantharaj <katpagavalli@gmail.com>
Emotion
-------

View File

@ -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++;

View File

@ -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;

View File

@ -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

View File

@ -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;
@ -1169,6 +1177,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)
{
@ -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);

View File

@ -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)

View File

@ -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();

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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);
}
}
}
}
}

View File

@ -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;
/**
@ -1968,6 +1969,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);
/**
* @}
*/

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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
{
@ -296,6 +299,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)
{