char input

Dependencies:   TS_DISCO_F746NG mbed LCD_DISCO_F746NG BSP_DISCO_F746NG lvgl_RB FastPWM millis

lv_i18n.c

Committer:
becanromain
Date:
2020-02-27
Revision:
6:519d681050af
Parent:
4:6a3d12663549

File content as of revision 6:519d681050af:

#include "./lv_i18n.h"


////////////////////////////////////////////////////////////////////////////////
// Define plural operands
// http://unicode.org/reports/tr35/tr35-numbers.html#Operands

// Integer version, simplified

#define UNUSED(x) (void)(x)

static lv_i18n_phrase_t fr_texts[] = {
    {"M100", "1 Etat"},  
        {"M101", "1.1 Etat d'avancement"},    
        {"M102", "1.2 Informations générales"},   
    {"M200", "2 Je prélève"}, 
        {"M201", "2.1 Séquence unique"},    
        {"M202", "2.2 Séquences répétées"}, 
        {"M203", "2.3 Séquences prédéfinies"},   
    {"M300", "3 Je vérifie"},
        {"M301", "3.1 Etat des vérifications"},
        {"M302", "3.2 Volume"},
        {"M303", "3.3 Température 1"},
        {"M304", "3.4 Température 2"},
        {"M305", "3.5 Température 3"},
        {"M306", "3.6 Pression 1"},
        {"M307", "3.7 Pression 2"},
        {"M308", "3.8 Pression 2"},
        {"M309", "3.9 Humidité relative"},
    {"M400", "4 Je supervise"},
        {"M401", "4.1 Choix de langue"},
        {"M402", "4.2 Droits d'accès"},
        {"M403", "4.3 Exigences métrologiques"},
        {"M404", "4.4 Bibliothèque des étalons "},
        {"M405", "4.5 Paramètres généraux"},
    {"M500", "5 Je consulte les archives"},
        {"M501", "5.1 Prélevements"},   
        {"M502", "5.2 Vérifications / ajustages"},  
        {"M503", "5.2 Vérifications / ajustages"},        
    {"M600", "6 Constructeur"},
        {"M601", "6.1 Régulation"}, 
    {"Temps de cycle = %3.3f us", "Temps de cycle = %3.3f us"},
    {NULL, NULL} // End mark
};

static const lv_i18n_lang_t fr_lang = {
    .locale_name = "fr",
    .singulars = fr_texts,
};

static lv_i18n_phrase_t en_gb_texts[] = {    
    {"M100", "Measures"},
    {"M200", "Sample"},
    {"M300", "Setting"},
    {"M400", "Menu 4"},
    {"M500", "Menu 5"},
    {"M600", "Menu 6"},
    {"SM301", "language"},
    {"Temps de cycle = %3.3f us", "Cycle time= %3.3f us"},
    {"cat", "This is a cat"},
    {NULL, NULL} // End mark
};


static const lv_i18n_lang_t en_gb_lang = {
    .locale_name = "en-GB",
    .singulars = en_gb_texts,
};

const lv_i18n_language_pack_t lv_i18n_language_pack[] = {
    &en_gb_lang,
    &fr_lang,
    NULL // End mark
};

////////////////////////////////////////////////////////////////////////////////


// Internal state
static const lv_i18n_language_pack_t * current_lang_pack;
static const lv_i18n_lang_t * current_lang;


/**
 * Reset internal state. For testing.
 */
void __lv_i18n_reset(void)
{
    current_lang_pack = NULL;
    current_lang = NULL;
}

/**
 * Set the languages for internationalization
 * @param langs pointer to the array of languages. (Last element has to be `NULL`)
 */
int lv_i18n_init(const lv_i18n_language_pack_t * langs)
{
    if(langs == NULL) return -1;
    if(langs[0] == NULL) return -1;

    current_lang_pack = langs;
    current_lang = langs[0];     /*Automatically select the first language*/
    return 0;
}

/**
 * Change the localization (language)
 * @param l_name name of the translation locale to use. E.g. "en-GB"
 */
int lv_i18n_set_locale(const char * l_name)
{
    if(current_lang_pack == NULL) return -1;

    uint16_t i;

    for(i = 0; current_lang_pack[i] != NULL; i++) {
        // Found -> finish
        if(strcmp(current_lang_pack[i]->locale_name, l_name) == 0) {
            current_lang = current_lang_pack[i];
            return 0;
        }
    }

    return -1;
}


static const char * __lv_i18n_get_text_core(lv_i18n_phrase_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].translation) return trans[i].translation;
        }
    }

    return NULL;
}


/**
 * Get the translation from a message ID
 * @param msg_id message ID
 * @return the translation of `msg_id` on the set local
 */
const char * lv_i18n_get_text(const char * msg_id)
{
    if(current_lang == NULL) return msg_id;

    const lv_i18n_lang_t * lang = current_lang;
    const void * txt;

    // Search in current locale
    if(lang->singulars != NULL) {
        txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
        if (txt != NULL) return txt;
    }

    // Try to fallback
    if(lang == current_lang_pack[0]) return msg_id;
    lang = current_lang_pack[0];

    // Repeat search for default locale
    if(lang->singulars != NULL) {
        txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
        if (txt != NULL) return txt;
    }

    return msg_id;
}

/**
 * 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 char * lv_i18n_get_text_plural(const char * msg_id, int32_t num)
{
    if(current_lang == NULL) return msg_id;

    const lv_i18n_lang_t * lang = current_lang;
    const void * txt;
    lv_i18n_plural_type_t ptype;

    // Search in current locale
    if(lang->locale_plural_fn != NULL) {
        ptype = lang->locale_plural_fn(num);

        if(lang->plurals[ptype] != NULL) {
            txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
            if (txt != NULL) return txt;
        }
    }

    // Try to fallback
    if(lang == current_lang_pack[0]) return msg_id;
    lang = current_lang_pack[0];

    // Repeat search for default locale
    if(lang->locale_plural_fn != NULL) {
        ptype = lang->locale_plural_fn(num);

        if(lang->plurals[ptype] != NULL) {
            txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
            if (txt != NULL) return txt;
        }
    }

    return msg_id;
}

/**
 * Get the name of the currently used locale.
 * @return name of the currently used locale. E.g. "en-GB"
 */
const char * lv_i18n_get_current_locale(void)
{
    if(!current_lang) return NULL;
    return current_lang->locale_name;
}