1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00
lvgl/lv_core/lv_i18n.c

257 lines
7.4 KiB
C
Raw Normal View History

/**
* @file lv_i18n.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_i18n.h"
#if USE_LV_I18N
#include "lv_obj.h"
#include "../lv_misc/lv_gc.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static const void * lv_i18n_get_text_core(lv_i18n_trans_t * trans, const char * msg_id);
/**********************
* STATIC VARIABLES
**********************/
2019-02-24 22:22:37 +01:00
static const lv_i18n_lang_pack_t * languages;
2019-02-21 12:37:33 +01:00
static const lv_i18n_lang_t * local_lang;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Set the languages for internationalization
* @param langs pointer to the array of languages. (Last element has to be `NULL`)
2019-02-24 22:22:37 +01:00
* @return 0: no error; < 0: error
*/
2019-02-24 22:22:37 +01:00
int lv_i18n_init(const lv_i18n_lang_pack_t * langs)
{
if(langs == NULL) {
LV_LOG_WARN("lv_i18n_init: `langs` can't be NULL");
2019-02-24 22:22:37 +01:00
return -1;
}
if(langs[0] == NULL) {
2019-02-24 22:22:37 +01:00
LV_LOG_WARN("lv_i18n_init: `langs` need to contain at least one translation");
return -1;
}
languages = langs;
local_lang = langs[0]; /*Automatically select the first language*/
2019-02-24 22:22:37 +01:00
return 0;
}
/**
* Change the localization (language)
* @param lang_code name of the translation to use. E.g. "en_GB"
2019-02-24 22:22:37 +01:00
* @return 0: no error; < 0: error
*/
2019-02-24 22:22:37 +01:00
int lv_i18n_set_local(const char * lang_code)
{
if(languages == NULL) {
LV_LOG_WARN("lv_i18n_set_local: The languages are not set with lv_i18n_init() yet");
2019-02-24 22:22:37 +01:00
return -1;
}
uint16_t i;
for(i = 0; languages[i] != NULL; i++) {
if(strcmp(languages[i]->name, lang_code) == 0) break; /*A language has found*/
}
/*The language wasn't found*/
if(languages[i] == NULL) {
LV_LOG_WARN("lv_i18n_set_local: The selected language doesn't found");
2019-02-24 22:22:37 +01:00
return -1;
}
local_lang = languages[i];
LV_LOG_INFO("lv_i18n_set_local: new local selected")
2019-02-24 22:22:37 +01:00
return 0;
}
/**
* Get the translation from a message ID
* @param msg_id message ID
* @return the translation of `msg_id` on the set local
*/
const void * lv_i18n_get_text(const char * msg_id)
{
if(local_lang == NULL) {
LV_LOG_WARN("lv_i18n_get_text: No language selected");
return msg_id;
}
2019-02-21 12:37:33 +01:00
const lv_i18n_lang_t * lang = local_lang;
if(lang->simple == NULL) {
if(lang == languages[0]) {
LV_LOG_WARN("lv_i18n_get_text: No translations are specified even on the default language.");
return msg_id;
} else {
LV_LOG_WARN("lv_i18n_get_text: No translations are specified on the current local. Fallback to the default language");
lang = languages[0];
}
if(lang->simple == NULL) {
LV_LOG_WARN("lv_i18n_get_text: No translations are specified even on the default language.");
return msg_id;
}
}
/*Find the translation*/
const void * txt = lv_i18n_get_text_core(lang->simple, msg_id);
if(txt == NULL) {
if(lang == languages[0]) {
LV_LOG_WARN("lv_i18n_get_text: No translation found even on the default language");
return msg_id;
} else {
LV_LOG_WARN("lv_i18n_get_text: No translation found on this language. Fallback to the default language");
lang = languages[0];
}
}
/*Try again with the default language*/
if(lang->simple == NULL) {
LV_LOG_WARN("lv_i18n_get_text: No translations are specified even on the default language.");
return msg_id;
}
txt = lv_i18n_get_text_core(lang->simple, msg_id);
if(txt == NULL) {
LV_LOG_WARN("lv_i18n_get_text: No translation found even on the default language");
return msg_id;
}
return txt;
}
/**
* Get the translation from a message ID and apply the language's plural rule to get correct form
* @param msg_id message ID
* @param num an integer to select the correct plural form
* @return the translation of `msg_id` on the set local
*/
const void * lv_i18n_get_text_plural(const char * msg_id, int32_t num)
{
if(local_lang == NULL) {
2019-02-21 12:37:33 +01:00
LV_LOG_WARN("lv_i18n_get_text_plural: No language selected");
return msg_id;
}
const lv_i18n_lang_t * lang = local_lang;
if(lang->plurals == NULL || lang->plural_rule == NULL) {
if(lang == languages[0]) {
LV_LOG_WARN("lv_i18n_get_text_plural: No plurals or plural rule has defined even on the default language");
return msg_id;
} else {
LV_LOG_WARN("lv_i18n_get_text_plural: o plurals or plural rule has defined for the language. Fallback to the default language");
lang = languages[0];
}
if(lang->plurals == NULL) {
LV_LOG_WARN("lv_i18n_get_text_plural: o plurals or plural rule has defined even on the default language");
return msg_id;
}
}
lv_i18n_plural_type_t ptype = lang->plural_rule(num);
if(lang->plurals[ptype] == NULL) {
if(lang == languages[0]) {
LV_LOG_WARN("lv_i18n_get_text_plural: No translations of the required plural form even on the default language.");
return msg_id;
} else {
LV_LOG_WARN("lv_i18n_get_text_plural:No translations of the required plural form for the language. Fallback to the default language");
lang = languages[0];
}
}
/*Find the translation*/
const void * txt = lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
if(txt == NULL) {
if(lang == languages[0]) {
LV_LOG_WARN("lv_i18n_get_text_plural: No translation found even on the default language");
return msg_id;
} else {
LV_LOG_WARN("lv_i18n_get_text_plural: No translation found on this language. Fallback to the default language");
lang = languages[0];
}
}
/*Try again with the default language*/
if(lang->plurals == NULL || lang->plural_rule == NULL) {
LV_LOG_WARN("lv_i18n_get_text_plural: No plurals or plural rule has defined even on the default language");
return msg_id;
}
ptype = lang->plural_rule(num);
if(lang->plurals[ptype] == NULL) {
LV_LOG_WARN("lv_i18n_get_text_plural: No translations of the required plural form even on the default language.");
return msg_id;
}
txt = lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
if(txt == NULL) {
LV_LOG_WARN("lv_i18n_get_text_plural: No translation found even on the default language");
return msg_id;
}
return txt;
}
/**
* Get the name of the currently used localization.
* @return name of the currently used localization. E.g. "en_GB"
*/
const void * lv_i18n_get_current_local(void)
{
if(local_lang) return local_lang->name;
else return NULL;
}
/**********************
* STATIC FUNCTIONS
**********************/
static const void * lv_i18n_get_text_core(lv_i18n_trans_t * trans, const char * msg_id)
{
uint16_t i;
for(i = 0; trans[i].msg_id != NULL; i++) {
if(strcmp(trans[i].msg_id, msg_id) == 0) {
/*The msg_id has found. Check the translation*/
if(trans[i].txt_trans) return trans[i].txt_trans;
}
}
LV_LOG_TRACE("lv_i18n_get_text_core: `msg_id` wasn't found");
return NULL;
}
#endif /*USE_LV_I18N*/