Romain BECAN / Mbed 2 deprecated Mallette_RB10G1_V40

Dependencies:   TS_DISCO_F746NG mbed LCD_DISCO_F746NG BSP_DISCO_F746NG lvgl_RB FastPWM millis

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lv_i18n.c Source File

lv_i18n.c

00001 #include "./lv_i18n.h"
00002 
00003 
00004 ////////////////////////////////////////////////////////////////////////////////
00005 // Define plural operands
00006 // http://unicode.org/reports/tr35/tr35-numbers.html#Operands
00007 
00008 // Integer version, simplified
00009 
00010 #define UNUSED(x) (void)(x)
00011 
00012 static lv_i18n_phrase_t fr_texts[] = {
00013     {"M100", "1 Etat"},  
00014         {"M101", "1.1 Etat d'avancement"},    
00015         {"M102", "1.2 Informations générales"},   
00016     {"M200", "2 Je prélève"}, 
00017         {"M201", "2.1 Séquence unique"},    
00018         {"M202", "2.2 Séquences répétées"}, 
00019         {"M203", "2.3 Séquences prédéfinies"},   
00020     {"M300", "3 Je vérifie"},
00021         {"M301", "3.1 Etat des vérifications"},
00022         {"M302", "3.2 Volume"},
00023         {"M303", "3.3 Température 1"},
00024         {"M304", "3.4 Température 2"},
00025         {"M305", "3.5 Température 3"},
00026         {"M306", "3.6 Pression 1"},
00027         {"M307", "3.7 Pression 2"},
00028         {"M308", "3.8 Pression 2"},
00029         {"M309", "3.9 Humidité relative"},
00030     {"M400", "4 Je supervise"},
00031         {"M401", "4.1 Choix de langue"},
00032         {"M402", "4.2 Droits d'accès"},
00033         {"M403", "4.3 Exigences métrologiques"},
00034         {"M404", "4.4 Bibliothèque des étalons "},
00035         {"M405", "4.5 Paramètres généraux"},
00036     {"M500", "5 Je consulte les archives"},
00037         {"M501", "5.1 Prélevements"},   
00038         {"M502", "5.2 Vérifications / ajustages"},  
00039         {"M503", "5.2 Vérifications / ajustages"},        
00040     {"M600", "6 Constructeur"},
00041         {"M601", "6.1 Régulation"}, 
00042     {"Temps de cycle = %3.3f us", "Temps de cycle = %3.3f us"},
00043     {NULL, NULL} // End mark
00044 };
00045 
00046 static const lv_i18n_lang_t fr_lang = {
00047     .locale_name = "fr",
00048     .singulars = fr_texts,
00049 };
00050 
00051 static lv_i18n_phrase_t en_gb_texts[] = {    
00052     {"M100", "Measures"},
00053     {"M200", "Sample"},
00054     {"M300", "Setting"},
00055     {"M400", "Menu 4"},
00056     {"M500", "Menu 5"},
00057     {"M600", "Menu 6"},
00058     {"SM301", "language"},
00059     {"Temps de cycle = %3.3f us", "Cycle time= %3.3f us"},
00060     {"cat", "This is a cat"},
00061     {NULL, NULL} // End mark
00062 };
00063 
00064 
00065 static const lv_i18n_lang_t en_gb_lang = {
00066     .locale_name = "en-GB",
00067     .singulars = en_gb_texts,
00068 };
00069 
00070 const lv_i18n_language_pack_t lv_i18n_language_pack[] = {
00071     &en_gb_lang,
00072     &fr_lang,
00073     NULL // End mark
00074 };
00075 
00076 ////////////////////////////////////////////////////////////////////////////////
00077 
00078 
00079 // Internal state
00080 static const lv_i18n_language_pack_t * current_lang_pack;
00081 static const lv_i18n_lang_t * current_lang;
00082 
00083 
00084 /**
00085  * Reset internal state. For testing.
00086  */
00087 void __lv_i18n_reset(void)
00088 {
00089     current_lang_pack = NULL;
00090     current_lang = NULL;
00091 }
00092 
00093 /**
00094  * Set the languages for internationalization
00095  * @param langs pointer to the array of languages. (Last element has to be `NULL`)
00096  */
00097 int lv_i18n_init(const lv_i18n_language_pack_t * langs)
00098 {
00099     if(langs == NULL) return -1;
00100     if(langs[0] == NULL) return -1;
00101 
00102     current_lang_pack = langs;
00103     current_lang = langs[0];     /*Automatically select the first language*/
00104     return 0;
00105 }
00106 
00107 /**
00108  * Change the localization (language)
00109  * @param l_name name of the translation locale to use. E.g. "en-GB"
00110  */
00111 int lv_i18n_set_locale(const char * l_name)
00112 {
00113     if(current_lang_pack == NULL) return -1;
00114 
00115     uint16_t i;
00116 
00117     for(i = 0; current_lang_pack[i] != NULL; i++) {
00118         // Found -> finish
00119         if(strcmp(current_lang_pack[i]->locale_name, l_name) == 0) {
00120             current_lang = current_lang_pack[i];
00121             return 0;
00122         }
00123     }
00124 
00125     return -1;
00126 }
00127 
00128 
00129 static const char * __lv_i18n_get_text_core(lv_i18n_phrase_t * trans, const char * msg_id)
00130 {
00131     uint16_t i;
00132     for(i = 0; trans[i].msg_id != NULL; i++) {
00133         if(strcmp(trans[i].msg_id, msg_id) == 0) {
00134             /*The msg_id has found. Check the translation*/
00135             if(trans[i].translation) return trans[i].translation;
00136         }
00137     }
00138 
00139     return NULL;
00140 }
00141 
00142 
00143 /**
00144  * Get the translation from a message ID
00145  * @param msg_id message ID
00146  * @return the translation of `msg_id` on the set local
00147  */
00148 const char * lv_i18n_get_text(const char * msg_id)
00149 {
00150     if(current_lang == NULL) return msg_id;
00151 
00152     const lv_i18n_lang_t * lang = current_lang;
00153     const void * txt;
00154 
00155     // Search in current locale
00156     if(lang->singulars != NULL) {
00157         txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
00158         if (txt != NULL) return txt;
00159     }
00160 
00161     // Try to fallback
00162     if(lang == current_lang_pack[0]) return msg_id;
00163     lang = current_lang_pack[0];
00164 
00165     // Repeat search for default locale
00166     if(lang->singulars != NULL) {
00167         txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
00168         if (txt != NULL) return txt;
00169     }
00170 
00171     return msg_id;
00172 }
00173 
00174 /**
00175  * Get the translation from a message ID and apply the language's plural rule to get correct form
00176  * @param msg_id message ID
00177  * @param num an integer to select the correct plural form
00178  * @return the translation of `msg_id` on the set local
00179  */
00180 const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num)
00181 {
00182     if(current_lang == NULL) return msg_id;
00183 
00184     const lv_i18n_lang_t * lang = current_lang;
00185     const void * txt;
00186     lv_i18n_plural_type_t ptype;
00187 
00188     // Search in current locale
00189     if(lang->locale_plural_fn != NULL) {
00190         ptype = lang->locale_plural_fn(num);
00191 
00192         if(lang->plurals[ptype] != NULL) {
00193             txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
00194             if (txt != NULL) return txt;
00195         }
00196     }
00197 
00198     // Try to fallback
00199     if(lang == current_lang_pack[0]) return msg_id;
00200     lang = current_lang_pack[0];
00201 
00202     // Repeat search for default locale
00203     if(lang->locale_plural_fn != NULL) {
00204         ptype = lang->locale_plural_fn(num);
00205 
00206         if(lang->plurals[ptype] != NULL) {
00207             txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
00208             if (txt != NULL) return txt;
00209         }
00210     }
00211 
00212     return msg_id;
00213 }
00214 
00215 /**
00216  * Get the name of the currently used locale.
00217  * @return name of the currently used locale. E.g. "en-GB"
00218  */
00219 const char * lv_i18n_get_current_locale(void)
00220 {
00221     if(!current_lang) return NULL;
00222     return current_lang->locale_name;
00223 }