d9e9881398525a8c87c47959dbc96a1d82de8202
[framework/uifw/e17.git] / src / modules / conf_intl / e_int_config_intl.c
1 #include "e.h"
2
3 typedef struct _E_Intl_Pair E_Intl_Pair;
4 typedef struct _E_Intl_Langauge_Node E_Intl_Language_Node;
5 typedef struct _E_Intl_Region_Node E_Intl_Region_Node;
6
7 static void        *_create_data             (E_Config_Dialog *cfd);
8 static void         _free_data               (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
9 static int          _advanced_apply_data     (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
10 static Evas_Object *_advanced_create_widgets (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
11 static int          _basic_apply_data        (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
12 static Evas_Object *_basic_create_widgets    (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
13
14 static void _ilist_basic_language_cb_change (void *data, Evas_Object *obj);
15 static void _ilist_language_cb_change       (void *data, Evas_Object *obj);
16 static void _ilist_region_cb_change         (void *data, Evas_Object *obj);
17 static void _ilist_codeset_cb_change        (void *data, Evas_Object *obj);
18 static void _ilist_modifier_cb_change       (void *data, Evas_Object *obj);
19 static int  _lang_list_sort                 (const void *data1, const void *data2);
20 static void _lang_list_load                 (void *data);
21 static int  _region_list_sort               (const void *data1, const void *data2);
22 static void _region_list_load               (void *data);
23 static int  _basic_lang_list_sort           (const void *data1, const void *data2);
24
25 /* Fill the clear lists, fill with language, select */
26 /* Update lanague */
27 static void      _cfdata_language_go        (const char *lang, const char *region, const char *codeset, const char *modifier, E_Config_Dialog_Data *cfdata);
28 static Eina_Bool _lang_hash_cb              (const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata);
29 static Eina_Bool _region_hash_cb            (const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata);
30 static Eina_Bool _language_hash_free_cb     (const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__);
31 static Eina_Bool _region_hash_free_cb       (const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__);
32 static void      _intl_current_locale_setup (E_Config_Dialog_Data *cfdata);
33 static const char *_intl_charset_upper_get  (const char *charset);
34
35 struct _E_Intl_Pair
36 {
37    const char *locale_key;
38    const char *locale_translation;
39 };
40
41 /* We need to store a map of languages -> Countries -> Extra
42  *
43  * Extra:
44  * Each region has its own Encodings
45  * Each region has its own Modifiers
46  */
47
48 struct _E_Intl_Langauge_Node
49 {
50    const char *lang_code;               /* en */
51    const char *lang_name;               /* English (trans in ilist) */
52    int         lang_available;          /* defined in e translation */
53    Eina_Hash  *region_hash;             /* US->utf8 */
54 };
55
56 struct _E_Intl_Region_Node
57 {
58    const char *region_code;             /* US */
59    const char *region_name;             /* United States */
60    Eina_List  *available_codesets;
61    Eina_List  *available_modifiers;
62 };
63
64 struct _E_Config_Dialog_Data
65 {
66    E_Config_Dialog *cfd;
67    Evas *evas;
68
69    /* Current data */
70    char *cur_language;
71    
72    const char *cur_blang;
73
74    const char *cur_lang;
75    const char *cur_reg;
76    const char *cur_cs;
77    const char *cur_mod;
78
79    int  lang_dirty;
80
81    Eina_Hash *locale_hash;
82    Eina_List *lang_list;
83    Eina_List *region_list;
84    Eina_List *blang_list;
85
86    struct
87      {
88         Evas_Object     *blang_list;
89
90         Evas_Object     *lang_list;
91         Evas_Object     *reg_list;
92         Evas_Object     *cs_list;
93         Evas_Object     *mod_list;
94         
95         Evas_Object     *locale_entry;
96      } 
97    gui;
98 };
99
100 const E_Intl_Pair basic_language_predefined_pairs[ ] = {
101      {"bg_BG.UTF-8", "Български"},
102      {"ca_ES.UTF-8", "Català"},
103      {"zh_CN.UTF-8", "Chinese (Simplified)"},
104      {"zh_TW.UTF-8", "Chinese (Traditional)"},
105      {"cs_CZ.UTF-8", "Čeština"},
106      {"da_DK.UTF-8", "Dansk"},
107      {"nl_NL.UTF-8", "Nederlands"},
108      {"en_US.UTF-8", "English"},
109      {"en_GB.UTF-8", "British English"},
110      {"fi_FI.UTF-8", "Suomi"},
111      {"fr_FR.UTF-8", "Français"},
112      {"de_DE.UTF-8", "Deutsch"},
113      {"hu_HU.UTF-8", "Magyar"},
114      {"it_IT.UTF-8", "Italiano"},
115      {"ja_JP.UTF-8", "日本語"},
116      {"ko_KR.UTF-8", "한국어"},
117      {"nb_NO.UTF-8", "Norsk Bokmål"},
118      {"pl_PL.UTF-8", "Polski"},
119      {"pt_BR.UTF-8", "Português"},
120      {"ru_RU.UTF-8", "Русский"},
121      {"sk_SK.UTF-8", "Slovenčina"},
122      {"sl_SI.UTF-8", "Slovenščina"},
123      {"es_AR.UTF-8", "Español"},
124      {"sv_SE.UTF-8", "Svenska"},
125      {"el_GR.UTF-8", "Ελληνικά"},
126      { NULL, NULL }
127 };
128
129 const E_Intl_Pair language_predefined_pairs[ ] = {
130        {"aa", "Qafár af"},
131        {"af", "Afrikaans"},
132        {"ak", "Akan"},
133        {"am", "አማርኛ"},
134        {"an", "Aragonés"},
135        {"ar", "ةيبرعلا"},
136        {"as", "অসমীয়া"},
137        {"az", "Azərbaycan dili"},
138        {"be", "Беларуская мова"},
139        {"bg", "Български"},
140        {"bn", "বাংলা"},
141        {"br", "Brezhoneg"},
142        {"bs", "Bosanski"},
143        {"byn", "ብሊና"},
144        {"ca", "Català"},
145        {"cch", "Atsam"},
146        {"cs", "Čeština"},
147        {"cy", "Cymraeg"},
148        {"da", "Dansk"},
149        {"de", "Deutsch"},
150        {"dv", "ދިވެހި"},
151        {"dz", "Dzongkha"},
152        {"ee", "Eʋegbe"},
153        {"el", "Ελληνικά"},
154        {"en", "English"},
155        {"eo", "Esperanto"},
156        {"es", "Español"},
157        {"et", "Eesti keel"},
158        {"eu", "Euskara"},
159        {"fa", "یسراف"},
160        {"fi", "Suomi"},
161        {"fo", "Føroyskt"},
162        {"fr", "Français"},
163        {"fur", "Furlan"},
164        {"ga", "Gaeilge"},
165        {"gaa", "Gã"},
166        {"gez", "ግዕዝ"},
167        {"gl", "Galego"},
168        {"gu", "Gujarati"},
169        {"gv", "Yn Ghaelg"},
170        {"ha", "Hausa"},
171        {"haw", "ʻŌlelo Hawaiʻi"},
172        {"he", "תירבע"},
173        {"hi", "Hindi"},
174        {"hr", "Hrvatski"},
175        {"hu", "Magyar"},
176        {"hy", "Հայերեն"},
177        {"ia", "Interlingua"},
178        {"id", "Indonesian"},
179        {"ig", "Igbo"},
180        {"is", "Íslenska"},
181        {"it", "Italiano"},
182        {"iu", "ᐃᓄᒃᑎᑐᑦ"},
183        {"iw", "תירבע"},
184        {"ja", "日本語"},
185        {"ka", "ქართული"},
186        {"kaj", "Jju"},
187        {"kam", "Kikamba"},
188        {"kcg", "Tyap"},
189        {"kfo", "Koro"},
190        {"kk", "Qazaq"},
191        {"kl", "Kalaallisut"},
192        {"km", "Khmer"},
193        {"kn", "ಕನ್ನಡ"},
194        {"ko", "한국어"},
195        {"kok", "Konkani"},
196        {"ku", "یدروك"},
197        {"kw", "Kernowek"},
198        {"ky", "Кыргыз тили"},
199        {"ln", "Lingála"},
200        {"lo", "ພາສາລາວ"},
201        {"lt", "Lietuvių kalba"},
202        {"lv", "Latviešu"},
203        {"mi", "Te Reo Māori"},
204        {"mk", "Македонски"},
205        {"ml", "മലയാളം"},
206        {"mn", "Монгол"},
207        {"mr", "मराठी"},
208        {"ms", "Bahasa Melayu"},
209        {"mt", "Malti"},
210        {"nb", "Norsk Bokmål"},
211        {"ne", "नेपाली"},
212        {"nl", "Nederlands"},
213        {"nn", "Norsk Nynorsk"},
214        {"no", "Norsk"},
215        {"nr", "isiNdebele"},
216        {"nso", "Sesotho sa Leboa"},
217        {"ny", "Chicheŵa"},
218        {"oc", "Occitan"},
219        {"om", "Oromo"},
220        {"or", "ଓଡ଼ିଆ"},
221        {"pa", "ਪੰਜਾਬੀ"},
222        {"pl", "Polski"},
223        {"ps", "وتښپ"},
224        {"pt", "Português"},
225        {"ro", "Română"},
226        {"ru", "Русский"},
227        {"rw", "Kinyarwanda"},
228        {"sa", "संस्कृतम्"},
229        {"se", "Davvisápmi"},
230        {"sh", "Srpskohrvatski/Српскохрватски"},
231        {"sid", "Sidámo 'Afó"},
232        {"sk", "Slovenčina"},
233        {"sl", "Slovenščina"},
234        {"so", "af Soomaali"},
235        {"sq", "Shqip"},
236        {"sr", "Српски"},
237        {"ss", "Swati"},
238        {"st", "Southern Sotho"},
239        {"sv", "Svenska"},
240        {"sw", "Swahili"},
241        {"syr", "Syriac"},
242        {"ta", "தமிழ்"},
243        {"te", "తెలుగు"},
244        {"tg", "Тоҷикӣ"},
245        {"th", "ภาษาไทย"},
246        {"ti", "ትግርኛ"},
247        {"tig", "ቲግሬ"},
248        {"tl", "Tagalog"},
249        {"tn", "Setswana"},
250        {"tr", "Türkçe"},
251        {"ts", "Tsonga"},
252        {"tt", "Татарча"},
253        {"uk", "Українська мова"},
254        {"ur", "ودراُ"},
255        {"uz", "O‘zbek"},
256        {"ve", "Venda"},
257        {"vi", "Tiếng Việt"},
258        {"wa", "Walon"},
259        {"wal", "Walamo"},
260        {"xh", "Xhosa"},
261        {"yi", "שידיִי"},
262        {"yo", "èdèe Yorùbá"},
263        {"zh", "汉语/漢語"},
264        {"zu", "Zulu"},
265        { NULL, NULL}
266 };
267
268 const E_Intl_Pair region_predefined_pairs[ ] = {
269        { "AF", "Afghanistan"},
270        { "AX", "Åland"},
271        { "AL", "Shqipëria"},
272        { "DZ", "Algeria"},
273        { "AS", "Amerika Sāmoa"},
274        { "AD", "Andorra"},
275        { "AO", "Angola"},
276        { "AI", "Anguilla"},
277        { "AQ", "Antarctica"},
278        { "AG", "Antigua and Barbuda"},
279        { "AR", "Argentina"},
280        { "AM", "Հայաստան"},
281        { "AW", "Aruba"},
282        { "AU", "Australia"},
283        { "AT", "Österreich"},
284        { "AZ", "Azərbaycan"},
285        { "BS", "Bahamas"},
286        { "BH", "Bahrain"},
287        { "BD", "বাংলাদেশ"},
288        { "BB", "Barbados"},
289        { "BY", "Беларусь"},
290        { "BE", "Belgium"},
291        { "BZ", "Belize"},
292        { "BJ", "Bénin"},
293        { "BM", "Bermuda"},
294        { "BT", "Bhutan"},
295        { "BO", "Bolivia"},
296        { "BA", "Bosnia and Herzegovina"},
297        { "BW", "Botswana"},
298        { "BV", "Bouvetøya"},
299        { "BR", "Brazil"},
300        { "IO", "British Indian Ocean Territory"},
301        { "BN", "Brunei Darussalam"},
302        { "BG", "България"},
303        { "BF", "Burkina Faso"},
304        { "BI", "Burundi"},
305        { "KH", "Cambodia"},
306        { "CM", "Cameroon"},
307        { "CA", "Canada"},
308        { "CV", "Cape Verde"},
309        { "KY", "Cayman Islands"},
310        { "CF", "Central African Republic"},
311        { "TD", "Chad"},
312        { "CL", "Chile"},
313        { "CN", "中國"},
314        { "CX", "Christmas Island"},
315        { "CC", "Cocos (keeling) Islands"},
316        { "CO", "Colombia"},
317        { "KM", "Comoros"},
318        { "CG", "Congo"},
319        { "CD", "Congo"},
320        { "CK", "Cook Islands"},
321        { "CR", "Costa Rica"},
322        { "CI", "Cote d'Ivoire"},
323        { "HR", "Hrvatska"},
324        { "CU", "Cuba"},
325        { "CY", "Cyprus"},
326        { "CZ", "Česká republika"},
327        { "DK", "Danmark"},
328        { "DJ", "Djibouti"},
329        { "DM", "Dominica"},
330        { "DO", "República Dominicana"},
331        { "EC", "Ecuador"},
332        { "EG", "Egypt"},
333        { "SV", "El Salvador"},
334        { "GQ", "Equatorial Guinea"},
335        { "ER", "Eritrea"},
336        { "EE", "Eesti"},
337        { "ET", "Ethiopia"},
338        { "FK", "Falkland Islands (malvinas)"},
339        { "FO", "Faroe Islands"},
340        { "FJ", "Fiji"},
341        { "FI", "Finland"},
342        { "FR", "France"},
343        { "GF", "French Guiana"},
344        { "PF", "French Polynesia"},
345        { "TF", "French Southern Territories"},
346        { "GA", "Gabon"},
347        { "GM", "Gambia"},
348        { "GE", "Georgia"},
349        { "DE", "Deutschland"},
350        { "GH", "Ghana"},
351        { "GI", "Gibraltar"},
352        { "GR", "Greece"},
353        { "GL", "Greenland"},
354        { "GD", "Grenada"},
355        { "GP", "Guadeloupe"},
356        { "GU", "Guam"},
357        { "GT", "Guatemala"},
358        { "GG", "Guernsey"},
359        { "GN", "Guinea"},
360        { "GW", "Guinea-Bissau"},
361        { "GY", "Guyana"},
362        { "HT", "Haiti"},
363        { "HM", "Heard Island and Mcdonald Islands"},
364        { "VA", "Holy See (Vatican City State)"},
365        { "HN", "Honduras"},
366        { "HK", "Hong Kong"},
367        { "HU", "Magyarország"},
368        { "IS", "Iceland"},
369        { "IN", "India"},
370        { "ID", "Indonesia"},
371        { "IR", "Iran"},
372        { "IQ", "Iraq"},
373        { "IE", "Éire"},
374        { "IM", "Isle Of Man"},
375        { "IL", "Israel"},
376        { "IT", "Italia"},
377        { "JM", "Jamaica"},
378        { "JP", "日本"},
379        { "JE", "Jersey"},
380        { "JO", "Jordan"},
381        { "KZ", "Kazakhstan"},
382        { "KE", "Kenya"},
383        { "KI", "Kiribati"},
384        { "KP", "Korea"},
385        { "KR", "Korea"},
386        { "KW", "Kuwait"},
387        { "KG", "Kyrgyzstan"},
388        { "LA", "Lao People's Democratic Republic"},
389        { "LV", "Latvija"},
390        { "LB", "Lebanon"},
391        { "LS", "Lesotho"},
392        { "LR", "Liberia"},
393        { "LY", "Libyan Arab Jamahiriya"},
394        { "LI", "Liechtenstein"},
395        { "LT", "Lietuva"},
396        { "LU", "Lëtzebuerg"},
397        { "MO", "Macao"},
398        { "MK", "Македонија"},
399        { "MG", "Madagascar"},
400        { "MW", "Malawi"},
401        { "MY", "Malaysia"},
402        { "MV", "Maldives"},
403        { "ML", "Mali"},
404        { "MT", "Malta"},
405        { "MH", "Marshall Islands"},
406        { "MQ", "Martinique"},
407        { "MR", "Mauritania"},
408        { "MU", "Mauritius"},
409        { "YT", "Mayotte"},
410        { "MX", "Mexico"},
411        { "FM", "Micronesia"},
412        { "MD", "Moldova"},
413        { "MC", "Monaco"},
414        { "MN", "Mongolia"},
415        { "MS", "Montserrat"},
416        { "MA", "Morocco"},
417        { "MZ", "Mozambique"},
418        { "MM", "Myanmar"},
419        { "NA", "Namibia"},
420        { "NR", "Nauru"},
421        { "NP", "Nepal"},
422        { "NL", "Nederland"},
423        { "AN", "Netherlands Antilles"},
424        { "NC", "New Caledonia"},
425        { "NZ", "New Zealand"},
426        { "NI", "Nicaragua"},
427        { "NE", "Niger"},
428        { "NG", "Nigeria"},
429        { "NU", "Niue"},
430        { "NF", "Norfolk Island"},
431        { "MP", "Northern Mariana Islands"},
432        { "NO", "Norge"},
433        { "OM", "Oman"},
434        { "PK", "Pakistan"},
435        { "PW", "Palau"},
436        { "PS", "Palestinian Territory"},
437        { "PA", "Panama"},
438        { "PG", "Papua New Guinea"},
439        { "PY", "Paraguay"},
440        { "PE", "Peru"},
441        { "PH", "Philippines"},
442        { "PN", "Pitcairn"},
443        { "PL", "Poland"},
444        { "PT", "Portugal"},
445        { "PR", "Puerto Rico"},
446        { "QA", "Qatar"},
447        { "RE", "Reunion"},
448        { "RO", "Romania"},
449        { "RU", "Russian Federation"},
450        { "RW", "Rwanda"},
451        { "SH", "Saint Helena"},
452        { "KN", "Saint Kitts and Nevis"},
453        { "LC", "Saint Lucia"},
454        { "PM", "Saint Pierre and Miquelon"},
455        { "VC", "Saint Vincent and the Grenadines"},
456        { "WS", "Samoa"},
457        { "SM", "San Marino"},
458        { "ST", "Sao Tome and Principe"},
459        { "SA", "Saudi Arabia"},
460        { "SN", "Senegal"},
461        { "CS", "Serbia and Montenegro"},
462        { "SC", "Seychelles"},
463        { "SL", "Sierra Leone"},
464        { "SG", "Singapore"},
465        { "SK", "Slovakia"},
466        { "SI", "Slovenia"},
467        { "SB", "Solomon Islands"},
468        { "SO", "Somalia"},
469        { "ZA", "South Africa"},
470        { "GS", "South Georgia and the South Sandwich Islands"},
471        { "ES", "Spain"},
472        { "LK", "Sri Lanka"},
473        { "SD", "Sudan"},
474        { "SR", "Suriname"},
475        { "SJ", "Svalbard and Jan Mayen"},
476        { "SZ", "Swaziland"},
477        { "SE", "Sweden"},
478        { "CH", "Switzerland"},
479        { "SY", "Syrian Arab Republic"},
480        { "TW", "Taiwan"},
481        { "TJ", "Tajikistan"},
482        { "TZ", "Tanzania"},
483        { "TH", "Thailand"},
484        { "TL", "Timor-Leste"},
485        { "TG", "Togo"},
486        { "TK", "Tokelau"},
487        { "TO", "Tonga"},
488        { "TT", "Trinidad and Tobago"},
489        { "TN", "Tunisia"},
490        { "TR", "Turkey"},
491        { "TM", "Turkmenistan"},
492        { "TC", "Turks and Caicos Islands"},
493        { "TV", "Tuvalu"},
494        { "UG", "Uganda"},
495        { "UA", "Ukraine"},
496        { "AE", "United Arab Emirates"},
497        { "GB", "United Kingdom"},
498        { "US", "United States"},
499        { "UM", "United States Minor Outlying Islands"},
500        { "UY", "Uruguay"},
501        { "UZ", "Uzbekistan"},
502        { "VU", "Vanuatu"},
503        { "VE", "Venezuela"},
504        { "VN", "Viet Nam"},
505        { "VG", "Virgin Islands"},
506        { "VI", "Virgin Islands"},
507        { "WF", "Wallis and Futuna"},
508        { "EH", "Western Sahara"},
509        { "YE", "Yemen"},
510        { "ZM", "Zambia"},
511        { "ZW", "Zimbabwe"},
512        { NULL, NULL}
513 };
514
515 /* This comes from 
516    $ man charsets
517  * and 
518    $ locale -a | grep -v @ | grep "\." | cut -d . -f 2 | sort -u
519  *
520  * On some machines is complains if codesets don't look like this
521  * On linux its not really a problem but BSD has issues. So we neet to 
522  * make sure that locale -a output gets converted to upper-case form in
523  * all situations just to be safe. 
524  */
525 const E_Intl_Pair charset_predefined_pairs[ ] = {
526        /* These are in locale -a but not in charsets */
527        {"cp1255", "CP1255"},
528        {"euc", "EUC"},
529        {"georgianps", "GEORGIAN-PS"},
530        {"iso885914", "ISO-8859-14"},
531        {"koi8t", "KOI8-T"},
532        {"tcvn", "TCVN"},
533        {"ujis", "UJIS"},
534
535        /* These are from charsets man page */
536        {"big5", "BIG5"},
537        {"big5hkscs", "BIG5-HKSCS"},
538        {"cp1251", "CP1251"},
539        {"eucjp", "EUC-JP"},
540        {"euckr", "EUC-KR"},
541        {"euctw", "EUC-TW"},
542        {"gb18030", "GB18030"},
543        {"gb2312", "GB2312"},
544        {"gbk", "GBK"},
545        {"iso88591", "ISO-8859-1"},
546        {"iso885913", "ISO-8859-13"},
547        {"iso885915", "ISO-8859-15"},
548        {"iso88592", "ISO-8859-2"},
549        {"iso88593", "ISO-8859-3"},
550        {"iso88595", "ISO-8859-5"},
551        {"iso88596", "ISO-8859-6"},
552        {"iso88597", "ISO-8859-7"},
553        {"iso88598", "ISO-8859-8"},
554        {"iso88599", "ISO-8859-9"},
555        {"koi8r", "KOI8-R"},
556        {"koi8u", "KOI8-U"},
557        {"tis620", "TIS-620"},
558        {"utf8", "UTF-8"},
559        { NULL, NULL }
560 };
561
562 E_Config_Dialog *
563 e_int_config_intl(E_Container *con, const char *params __UNUSED__)
564 {
565    E_Config_Dialog *cfd;
566    E_Config_Dialog_View *v;
567
568    if (e_config_dialog_find("E", "language/language_settings")) return NULL;
569    v = E_NEW(E_Config_Dialog_View, 1);
570    
571    v->create_cfdata = _create_data;
572    v->free_cfdata = _free_data;
573    v->advanced.create_widgets = _advanced_create_widgets;
574    v->advanced.apply_cfdata = _advanced_apply_data;
575    v->basic.create_widgets = _basic_create_widgets;
576    v->basic.apply_cfdata = _basic_apply_data;
577    
578    cfd = e_config_dialog_new(con,
579                              _("Language Settings"),
580                              "E", "language/language_settings",
581                              "preferences-desktop-locale", 0, v, NULL);
582    return cfd;
583 }
584
585 /* Build hash tables used for locale navigation. The locale information is 
586  * gathered using the locale -a command. 
587  *
588  * Below the following terms are used:
589  * ll - Locale Language Code (Example en)
590  * RR - Locale Region code (Example US)
591  * enc - Locale Encoding (Example UTF-8)
592  * mod - Locale Modifier (Example EURO)
593  */
594 static void
595 _fill_data(E_Config_Dialog_Data *cfdata)
596 {
597    Eina_List    *e_lang_list;
598    FILE         *output;
599    
600    e_lang_list = e_intl_language_list();
601    
602    /* Get list of all locales and start making map */
603    output = popen("locale -a", "r");
604    if ( output ) 
605      {
606         char line[32];
607         while (fscanf(output, "%[^\n]\n", line) == 1)
608           {
609              E_Locale_Parts *locale_parts;
610
611              locale_parts = e_intl_locale_parts_get(line);
612
613              if (locale_parts)
614                {
615                   char *basic_language;
616
617                   basic_language = e_intl_locale_parts_combine(locale_parts, E_INTL_LOC_LANG | E_INTL_LOC_REGION);
618                   if (basic_language)
619                     {
620                        int i;
621                        
622                        i = 0;
623                        while (basic_language_predefined_pairs[i].locale_key)
624                          {
625                             /* if basic language is supported by E and System*/
626                             if (!strncmp(basic_language_predefined_pairs[i].locale_key, 
627                                      basic_language, strlen(basic_language)))
628                               {
629                                  if (!eina_list_data_find(cfdata->blang_list, &basic_language_predefined_pairs[i]))
630                                    cfdata->blang_list = eina_list_append(cfdata->blang_list, &basic_language_predefined_pairs[i]);
631                                  break;
632                               }
633                             i++;
634                          }
635                     }
636                   E_FREE(basic_language);
637
638                   /* If the language is a valid ll_RR[.enc[@mod]] locale add it to the hash */
639                   if (locale_parts->lang)
640                     {
641                        E_Intl_Language_Node *lang_node;
642                        E_Intl_Region_Node  *region_node;
643
644                        /* Add the language to the new locale properties to the hash */
645                        /* First check if the LANGUAGE exists in there already */
646
647                        lang_node  = eina_hash_find(cfdata->locale_hash, locale_parts->lang);
648                        if (!lang_node)
649                          {
650                             Eina_List *next;
651                             int i;
652
653                             /* create new node */
654                             lang_node = E_NEW(E_Intl_Language_Node, 1);
655
656                             lang_node->lang_code = eina_stringshare_add(locale_parts->lang);
657
658                             /* Check if the language list exists */
659                             /* Linear Search */
660                             for (next = e_lang_list; next; next = next->next) 
661                               {
662                                  char *e_lang;
663
664                                  e_lang = next->data;
665                                  if (!strncmp(e_lang, locale_parts->lang, 2) || !strcmp("en", locale_parts->lang)) 
666                                    {
667                                       lang_node->lang_available = 1;
668                                       break;
669                                    }
670                               }
671                        
672                             /* Search for translation */
673                             /* Linear Search */
674                             i = 0;
675                             while (language_predefined_pairs[i].locale_key)
676                               {
677                                  if (!strcmp(language_predefined_pairs[i].locale_key, locale_parts->lang))
678                                    {
679                                       lang_node->lang_name = _(language_predefined_pairs[i].locale_translation);
680                                       break;
681                                    }
682                                  i++;
683                               }
684
685                             if (!cfdata->locale_hash)
686                               cfdata->locale_hash = eina_hash_string_superfast_new(NULL);
687                             eina_hash_add(cfdata->locale_hash, locale_parts->lang, lang_node);
688                          }
689
690                        /* We now have the current language hash node, lets see if there is
691                           region data that needs to be added.
692                         */
693
694                        if (locale_parts->region)
695                          {
696                             region_node = eina_hash_find(lang_node->region_hash, locale_parts->region);
697
698                             if (!region_node)
699                               {
700                                  int i;
701
702                                  /* create new node */
703                                  region_node = E_NEW(E_Intl_Region_Node, 1);
704                                  region_node->region_code = eina_stringshare_add(locale_parts->region);
705
706                                  /* Get the region translation */
707                                  /* Linear Search */
708                                  i = 0;
709                                  while (region_predefined_pairs[i].locale_key)
710                                    {
711                                       if (!strcmp(region_predefined_pairs[i].locale_key, locale_parts->region))
712                                         {
713                                            region_node->region_name = _(region_predefined_pairs[i].locale_translation);
714                                            break;
715                                         }
716                                       i++;
717                                    }
718                                  if (!lang_node->region_hash)
719                                    lang_node->region_hash = eina_hash_string_superfast_new(NULL);
720                                  eina_hash_add(lang_node->region_hash, locale_parts->region, region_node);
721                               }
722
723                             /* We now have the current region hash node */
724                             /* Add codeset to the region hash node if it exists */
725                             if (locale_parts->codeset)
726                               {
727                                  const char * cs;
728                                  const char * cs_trans;
729                             
730                                  cs_trans = _intl_charset_upper_get(locale_parts->codeset);
731                                  if (!cs_trans) 
732                                    cs = eina_stringshare_add(locale_parts->codeset);
733                                  else 
734                                    cs = eina_stringshare_add(cs_trans);
735                             
736                                  /* Exclusive */
737                                  /* Linear Search */
738                                  if (!eina_list_data_find(region_node->available_codesets, cs))
739                                    region_node->available_codesets = eina_list_append(region_node->available_codesets, cs);
740                               }
741
742                             /* Add modifier to the region hash node if it exists */
743                             if (locale_parts->modifier)
744                               {
745                                  const char *mod;
746
747                                  mod = eina_stringshare_add(locale_parts->modifier);
748                                  /* Find only works here because we are using stringshare*/
749                             
750                                  /* Exclusive */
751                                  /* Linear Search */
752                                  if (!eina_list_data_find(region_node->available_modifiers, mod))
753                                    region_node->available_modifiers = eina_list_append(region_node->available_modifiers, mod);
754                               }
755                          }
756                     }
757                   e_intl_locale_parts_free(locale_parts);
758                }
759           }
760
761         /* Sort basic languages */
762         cfdata->blang_list = eina_list_sort(cfdata->blang_list,
763               eina_list_count(cfdata->blang_list),
764               _basic_lang_list_sort);
765
766         while (e_lang_list)
767           {
768              free(e_lang_list->data);
769              e_lang_list = eina_list_remove_list(e_lang_list, e_lang_list);
770           }
771         pclose(output);
772      }
773
774    /* Make sure we know the currently configured locale */
775    if (e_config->language)
776      cfdata->cur_language = strdup(e_config->language);
777
778    return;
779 }
780
781 static void *
782 _create_data(E_Config_Dialog *cfd)
783 {
784    E_Config_Dialog_Data *cfdata;
785
786    cfdata = E_NEW(E_Config_Dialog_Data, 1);
787    cfdata->cfd = cfd;
788    _fill_data(cfdata);
789    return cfdata;
790 }
791
792 static void
793 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
794 {
795    E_FREE(cfdata->cur_language);
796
797    eina_stringshare_del(cfdata->cur_blang);
798    eina_stringshare_del(cfdata->cur_lang);
799    eina_stringshare_del(cfdata->cur_reg);
800    eina_stringshare_del(cfdata->cur_cs);
801    eina_stringshare_del(cfdata->cur_mod);
802
803    eina_hash_foreach(cfdata->locale_hash, _language_hash_free_cb, NULL);
804    eina_hash_free(cfdata->locale_hash);
805
806    cfdata->lang_list = eina_list_free(cfdata->lang_list);
807    cfdata->region_list = eina_list_free(cfdata->region_list);
808    cfdata->blang_list = eina_list_free(cfdata->blang_list);
809
810    E_FREE(cfdata);
811 }
812
813 static Eina_Bool
814 _language_hash_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
815 {
816    E_Intl_Language_Node *node;
817
818    node = data;
819    if (node->lang_code) eina_stringshare_del(node->lang_code);
820    eina_hash_foreach(node->region_hash, _region_hash_free_cb, NULL);
821    eina_hash_free(node->region_hash);
822    free(node);
823
824    return 1;
825 }
826
827 static Eina_Bool
828 _region_hash_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
829 {
830    E_Intl_Region_Node *node;
831
832    node = data;
833    if (node->region_code) eina_stringshare_del(node->region_code);
834    while (node->available_codesets)
835      {
836         const char *str;
837
838         str = node->available_codesets->data;
839         if (str) eina_stringshare_del(str);
840         node->available_codesets =
841           eina_list_remove_list(node->available_codesets, node->available_codesets);
842      }
843
844    while (node->available_modifiers)
845      {
846         const char *str;
847
848         str = node->available_modifiers->data;
849         if (str) eina_stringshare_del(str);
850         node->available_modifiers =
851           eina_list_remove_list(node->available_modifiers, node->available_modifiers);
852      }
853
854    free(node);
855    return 1;
856 }
857
858 static int
859 _basic_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
860 {
861    if (cfdata->cur_language)
862      {
863         if (e_config->language) eina_stringshare_del(e_config->language);
864         e_config->language = NULL;
865         if ((cfdata->cur_language) && (cfdata->cur_language[0]))
866            e_config->language = eina_stringshare_add(cfdata->cur_language);
867         e_intl_language_set(e_config->language);
868      }
869
870    e_config_save_queue();
871    return 1;
872 }
873
874 static int
875 _advanced_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
876 {
877    if (cfdata->cur_language)
878      {
879         if (e_config->language) eina_stringshare_del(e_config->language);
880         e_config->language = NULL;
881         if ((cfdata->cur_language) && (cfdata->cur_language[0]))
882            e_config->language = eina_stringshare_add(cfdata->cur_language);
883         e_intl_language_set(e_config->language);
884      }
885
886    e_config_save_queue();
887    return 1;
888 }
889
890 static Evas_Object *
891 _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
892 {
893    Evas_Object *o, *of, *ob;
894    char *cur_sig_loc;
895    Eina_List *next;
896    int i = 0;
897    
898    cfdata->evas = evas;
899    o = e_widget_table_add(evas, 0);
900    of = e_widget_framelist_add(evas, _("Language Selector"), 0);
901    ob = e_widget_ilist_add(evas, 16, 16, &(cfdata->cur_blang));
902    e_widget_size_min_set(ob, 100, 80);
903    e_widget_on_change_hook_set(ob, _ilist_basic_language_cb_change, cfdata);
904    cfdata->gui.blang_list = ob;
905    e_widget_framelist_object_append(of, ob);
906    e_widget_table_object_append(o, of, 0, 0, 1, 1, 1, 1, 1, 1);
907
908    /* Load languages */
909    evas_event_freeze(evas_object_evas_get(ob));
910    edje_freeze();
911    e_widget_ilist_freeze(ob);
912    if (cfdata->cur_language)
913      {
914         E_Locale_Parts *locale_parts;
915         locale_parts = e_intl_locale_parts_get(cfdata->cur_language);
916         if (locale_parts)
917           {
918              cur_sig_loc = e_intl_locale_parts_combine(locale_parts,
919                    E_INTL_LOC_LANG | E_INTL_LOC_REGION);
920
921              e_intl_locale_parts_free(locale_parts);
922           }
923         else
924           cur_sig_loc = NULL;
925      }
926    else
927      cur_sig_loc = NULL;
928
929    e_widget_ilist_append(cfdata->gui.blang_list, NULL, _("System Default"), NULL, NULL, "");
930    if ((!cur_sig_loc) || (!cfdata->cur_language))
931       e_widget_ilist_selected_set(cfdata->gui.blang_list, i);
932    i++;
933    
934    for (next = cfdata->blang_list; next; next = next->next) 
935      {
936         E_Intl_Pair *pair;
937         const char *key;
938         const char *trans;
939
940         pair = next->data;
941         key = pair->locale_key;
942         trans = _(pair->locale_translation);
943         e_widget_ilist_append(cfdata->gui.blang_list, NULL, trans, NULL, NULL, key);
944         if ((cur_sig_loc) && 
945             (!strncmp(key, cur_sig_loc, strlen(cur_sig_loc))))
946           e_widget_ilist_selected_set(cfdata->gui.blang_list, i);
947         
948         i++;
949      }
950    E_FREE(cur_sig_loc);   
951    e_widget_ilist_go(ob);
952    e_widget_ilist_thaw(ob);
953    edje_thaw();
954    evas_event_thaw(evas_object_evas_get(ob));
955
956    of = e_widget_frametable_add(evas, _("Locale Selected"), 0);
957    ob = e_widget_label_add(evas, _("Locale"));
958    e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 0, 1, 0);
959    ob = e_widget_entry_add(evas, &(cfdata->cur_language), NULL, NULL, NULL);
960    cfdata->gui.locale_entry = ob;
961    e_widget_disabled_set(cfdata->gui.locale_entry, 1);
962    e_widget_size_min_set(cfdata->gui.locale_entry, 100, 25);
963    e_widget_frametable_object_append(of, cfdata->gui.locale_entry, 
964                                      1, 0, 1, 1, 1, 1, 1, 0);
965    e_widget_table_object_append(o, of, 0, 1, 1, 1, 1, 0, 1, 0);
966
967    e_dialog_resizable_set(cfd->dia, 1);
968    return o;
969 }
970    
971 static Evas_Object *
972 _advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
973 {
974    Evas_Object *o, *of, *ob;
975    const char *lang, *reg, *cs, *mod;
976    
977    cfdata->evas = evas;
978
979    _intl_current_locale_setup(cfdata);
980
981    o = e_widget_table_add(evas, 0);
982
983    of = e_widget_framelist_add(evas, _("Language Selector"), 1);
984
985    /* Language List */
986    ob = e_widget_ilist_add(evas, 16, 16, &(cfdata->cur_lang));
987    cfdata->gui.lang_list = ob;
988
989    /* If lang_list already loaded just use it */
990    if (!cfdata->lang_list)
991      eina_hash_foreach(cfdata->locale_hash, _lang_hash_cb, cfdata);
992
993    if (cfdata->lang_list)
994      {
995         cfdata->lang_list =
996           eina_list_sort(cfdata->lang_list, eina_list_count(cfdata->lang_list),
997                          _lang_list_sort);
998         _lang_list_load(cfdata);
999      }
1000
1001    e_widget_ilist_go(ob);
1002    e_widget_size_min_set(ob, 140, 200);
1003    e_widget_framelist_object_append(of, ob);
1004    e_widget_ilist_selected_set(ob, e_widget_ilist_selected_get(ob));
1005
1006    /* Region List */
1007    ob = e_widget_ilist_add(evas, 0, 0, &(cfdata->cur_reg));
1008    cfdata->gui.reg_list = ob;
1009
1010    e_widget_ilist_go(ob);
1011    e_widget_size_min_set(ob, 100, 100);
1012    e_widget_framelist_object_append(of, ob);
1013    e_widget_ilist_selected_set(ob, e_widget_ilist_selected_get(ob));
1014
1015    /* Codeset List */
1016    ob = e_widget_ilist_add(evas, 0, 0, &(cfdata->cur_cs));
1017    cfdata->gui.cs_list = ob;
1018
1019    e_widget_ilist_go(ob);
1020    e_widget_size_min_set(ob, 100, 100);
1021    e_widget_framelist_object_append(of, ob);
1022    
1023    /* Modified List */
1024    ob = e_widget_ilist_add(evas, 0, 0, &(cfdata->cur_mod));
1025    cfdata->gui.mod_list = ob;
1026
1027    e_widget_ilist_go(ob);
1028    e_widget_size_min_set(ob, 100, 100);
1029    e_widget_framelist_object_append(of, ob);
1030
1031    e_widget_table_object_append(o, of, 0, 0, 1, 1, 1, 1, 1, 1);
1032    
1033    /* Locale selector */
1034    of = e_widget_frametable_add(evas, _("Locale Selected"), 0);
1035    ob = e_widget_label_add(evas, _("Locale"));
1036    e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 0, 1, 0);
1037    ob = e_widget_entry_add(evas, &(cfdata->cur_language), NULL, NULL, NULL);
1038    cfdata->gui.locale_entry = ob;
1039    e_widget_disabled_set(cfdata->gui.locale_entry, 1);
1040    e_widget_size_min_set(cfdata->gui.locale_entry, 100, 25);
1041    e_widget_frametable_object_append(of, cfdata->gui.locale_entry, 
1042                                      0, 1, 1, 1, 1, 1, 1, 0);
1043    e_widget_table_object_append(o, of, 0, 1, 1, 1, 1, 0, 1, 0);
1044
1045    /* all these cur_* values are not guaranteed to be const so we need to
1046     * copy them. 
1047     */
1048    lang = eina_stringshare_ref(cfdata->cur_lang);
1049    reg = eina_stringshare_ref(cfdata->cur_reg);
1050    cs = eina_stringshare_ref(cfdata->cur_cs);
1051    mod = eina_stringshare_ref(cfdata->cur_mod);
1052    
1053    _cfdata_language_go(lang, reg, cs, mod, cfdata);
1054    
1055    eina_stringshare_del(lang);
1056    eina_stringshare_del(reg);
1057    eina_stringshare_del(cs);
1058    eina_stringshare_del(mod);
1059    
1060    e_widget_on_change_hook_set(cfdata->gui.lang_list, _ilist_language_cb_change, cfdata);
1061    e_widget_on_change_hook_set(cfdata->gui.reg_list, _ilist_region_cb_change, cfdata); 
1062    e_widget_on_change_hook_set(cfdata->gui.cs_list, _ilist_codeset_cb_change, cfdata); 
1063    e_widget_on_change_hook_set(cfdata->gui.mod_list, _ilist_modifier_cb_change, cfdata); 
1064
1065    e_dialog_resizable_set(cfd->dia, 1);
1066    return o;
1067 }
1068
1069 static void
1070 _ilist_basic_language_cb_change(void *data, Evas_Object *obj __UNUSED__)
1071 {
1072    E_Config_Dialog_Data *cfdata;
1073
1074    cfdata = data;
1075    e_widget_entry_text_set(cfdata->gui.locale_entry, cfdata->cur_blang);
1076 }
1077
1078 static void
1079 _ilist_language_cb_change(void *data, Evas_Object *obj __UNUSED__)
1080 {
1081    E_Config_Dialog_Data *cfdata;
1082
1083    cfdata = data;
1084    _cfdata_language_go(cfdata->cur_lang, NULL, NULL, NULL, cfdata);
1085    e_widget_entry_text_set(cfdata->gui.locale_entry, cfdata->cur_lang);
1086    eina_stringshare_del(cfdata->cur_cs);
1087    eina_stringshare_del(cfdata->cur_mod);
1088 }
1089
1090 static void
1091 _ilist_region_cb_change(void *data, Evas_Object *obj __UNUSED__)
1092 {
1093    E_Config_Dialog_Data * cfdata;
1094    char locale[32];
1095     
1096    cfdata = data;
1097     
1098    _cfdata_language_go(cfdata->cur_lang, cfdata->cur_reg, NULL, NULL, cfdata);
1099    
1100    if ((cfdata->cur_lang) && (cfdata->cur_lang[0]))
1101      {
1102         sprintf(locale, "%s_%s", cfdata->cur_lang, cfdata->cur_reg);
1103         e_widget_entry_text_set(cfdata->gui.locale_entry, locale);
1104      }
1105    else
1106       e_widget_entry_text_set(cfdata->gui.locale_entry, "");
1107    eina_stringshare_del(cfdata->cur_cs);
1108    eina_stringshare_del(cfdata->cur_mod);
1109 }
1110
1111 static void 
1112 _ilist_codeset_cb_change(void *data, Evas_Object *obj __UNUSED__)
1113 {
1114    E_Config_Dialog_Data * cfdata;
1115    char locale[32];
1116    
1117    cfdata = data;
1118    
1119    if ((cfdata->cur_lang) && (cfdata->cur_lang[0]))
1120      {
1121         if (cfdata->cur_mod)
1122            sprintf(locale, "%s_%s.%s@%s", cfdata->cur_lang, cfdata->cur_reg, cfdata->cur_cs, cfdata->cur_mod);
1123         else
1124            sprintf(locale, "%s_%s.%s", cfdata->cur_lang, cfdata->cur_reg, cfdata->cur_cs);
1125         e_widget_entry_text_set(cfdata->gui.locale_entry, locale);
1126      }
1127    else
1128       e_widget_entry_text_set(cfdata->gui.locale_entry, "");
1129 }
1130
1131 static void 
1132 _ilist_modifier_cb_change(void *data, Evas_Object *obj __UNUSED__)
1133 {
1134    E_Config_Dialog_Data * cfdata;
1135    char locale[32];
1136    
1137    cfdata = data;
1138    
1139    if ((cfdata->cur_lang) && (cfdata->cur_lang[0]))
1140      {
1141         if (cfdata->cur_cs)
1142            sprintf(locale, "%s_%s.%s@%s", cfdata->cur_lang, cfdata->cur_reg, cfdata->cur_cs, cfdata->cur_mod);
1143         else
1144            sprintf(locale, "%s_%s@%s", cfdata->cur_lang, cfdata->cur_reg, cfdata->cur_mod);
1145         e_widget_entry_text_set(cfdata->gui.locale_entry, locale);
1146      }
1147    else
1148       e_widget_entry_text_set(cfdata->gui.locale_entry, "");
1149 }
1150
1151 static void 
1152 _cfdata_language_go(const char *lang, const char *region, const char *codeset, const char *modifier, E_Config_Dialog_Data *cfdata)
1153 {
1154    E_Intl_Language_Node *lang_node;     
1155    int lang_update;
1156    int region_update;
1157    
1158    /* Check what changed */
1159    lang_update = 0;
1160    region_update = 0;
1161
1162    evas_event_freeze(evas_object_evas_get(cfdata->gui.cs_list));
1163    evas_event_freeze(evas_object_evas_get(cfdata->gui.mod_list));
1164    edje_freeze();
1165    e_widget_ilist_freeze(cfdata->gui.cs_list);
1166    e_widget_ilist_freeze(cfdata->gui.mod_list);
1167
1168    if ((!lang) || (!lang[0]))
1169      {
1170         e_widget_ilist_clear(cfdata->gui.reg_list);
1171         e_widget_ilist_clear(cfdata->gui.cs_list);
1172         e_widget_ilist_clear(cfdata->gui.mod_list);
1173      }
1174    if (cfdata->lang_dirty || (lang && !region))
1175      {
1176         lang_update = 1;
1177         region_update = 1;
1178         e_widget_ilist_clear(cfdata->gui.cs_list);
1179         e_widget_ilist_clear(cfdata->gui.mod_list);
1180      }
1181    if (lang && region)
1182      {
1183         region_update = 1;
1184         e_widget_ilist_clear(cfdata->gui.cs_list);
1185         e_widget_ilist_clear(cfdata->gui.mod_list);
1186      }
1187
1188    cfdata->lang_dirty = 0;
1189
1190    if (lang)
1191      {
1192         lang_node = eina_hash_find(cfdata->locale_hash, lang);
1193
1194         if (lang_node)
1195           {
1196              if (lang_update)
1197                {
1198                   e_widget_ilist_clear(cfdata->gui.reg_list);
1199                   cfdata->region_list = eina_list_free(cfdata->region_list);
1200                   eina_hash_foreach(lang_node->region_hash,
1201                                     _region_hash_cb, cfdata);
1202                   cfdata->region_list =
1203                     eina_list_sort(cfdata->region_list,
1204                                    eina_list_count(cfdata->region_list),
1205                                    _region_list_sort);
1206                   _region_list_load(cfdata);
1207                }
1208
1209              if (region && region_update)
1210                {
1211                   E_Intl_Region_Node *reg_node;
1212
1213                   reg_node = eina_hash_find(lang_node->region_hash, region);
1214                   if (reg_node)
1215                     {
1216                        Eina_List *next;
1217
1218                        for (next = reg_node->available_codesets; next; next = next->next)
1219                          {
1220                             const char * cs;
1221
1222                             cs = next->data;
1223                             e_widget_ilist_append(cfdata->gui.cs_list, NULL, cs, NULL, NULL, cs);
1224                             if (codeset && !strcmp(cs, codeset))
1225                               {
1226                                  int count;
1227
1228                                  count = e_widget_ilist_count(cfdata->gui.cs_list);
1229                                  e_widget_ilist_selected_set(cfdata->gui.cs_list, count - 1);
1230                               }
1231                          }
1232                        
1233                        for (next = reg_node->available_modifiers; next; next = next->next) 
1234                          {
1235                             const char * mod;
1236                             
1237                             mod = next->data;
1238                             e_widget_ilist_append(cfdata->gui.mod_list, NULL, mod, NULL, NULL, mod);
1239                             if (modifier && !strcmp(mod, modifier)) 
1240                               {
1241                                  int count;
1242
1243                                  count = e_widget_ilist_count(cfdata->gui.mod_list);
1244                                  e_widget_ilist_selected_set(cfdata->gui.mod_list, count - 1);
1245                               }
1246
1247                          }
1248                     }
1249                   e_widget_ilist_go(cfdata->gui.cs_list);
1250                   e_widget_ilist_go(cfdata->gui.mod_list);
1251                }
1252           }
1253      }
1254    e_widget_ilist_thaw(cfdata->gui.cs_list);
1255    e_widget_ilist_thaw(cfdata->gui.mod_list);
1256    edje_thaw();
1257    evas_event_thaw(evas_object_evas_get(cfdata->gui.cs_list));
1258    evas_event_thaw(evas_object_evas_get(cfdata->gui.mod_list));
1259
1260    e_widget_ilist_go(cfdata->gui.reg_list);
1261 }
1262
1263 static Eina_Bool
1264 _lang_hash_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
1265 {
1266    E_Config_Dialog_Data *cfdata;
1267    E_Intl_Language_Node *lang_node;
1268
1269    cfdata = fdata;
1270    lang_node = data;
1271
1272    cfdata->lang_list = eina_list_append(cfdata->lang_list, lang_node);
1273    return 1;
1274 }
1275
1276 static Eina_Bool
1277 _region_hash_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
1278 {
1279    E_Config_Dialog_Data *cfdata;
1280    E_Intl_Region_Node *reg_node;
1281
1282    cfdata = fdata;
1283    reg_node = data;
1284
1285    cfdata->region_list = eina_list_append(cfdata->region_list, reg_node);
1286    return 1;
1287 }
1288
1289 void 
1290 _intl_current_locale_setup(E_Config_Dialog_Data *cfdata)
1291 {
1292    eina_stringshare_del(cfdata->cur_lang);
1293    eina_stringshare_del(cfdata->cur_reg);
1294    eina_stringshare_del(cfdata->cur_cs);
1295    eina_stringshare_del(cfdata->cur_mod);
1296
1297    cfdata->cur_lang = NULL;
1298    cfdata->cur_reg = NULL;
1299    cfdata->cur_cs = NULL;
1300    cfdata->cur_mod = NULL;
1301  
1302    if (cfdata->cur_language)
1303      {
1304         E_Locale_Parts *locale_parts;
1305  
1306         locale_parts = e_intl_locale_parts_get(cfdata->cur_language);
1307         if (locale_parts)
1308           {
1309              cfdata->cur_lang = eina_stringshare_add(locale_parts->lang);
1310              cfdata->cur_reg = eina_stringshare_add(locale_parts->region);
1311              if (locale_parts->codeset) 
1312                {
1313                   const char *cs_trans;
1314         
1315                   cs_trans = _intl_charset_upper_get(locale_parts->codeset);
1316                   if (!cs_trans)
1317                     cfdata->cur_cs = eina_stringshare_add(locale_parts->codeset);
1318                   else
1319                     cfdata->cur_cs = eina_stringshare_add(cs_trans);
1320                }
1321              cfdata->cur_mod = eina_stringshare_add(locale_parts->modifier);
1322           }
1323         e_intl_locale_parts_free(locale_parts);
1324      }
1325    cfdata->lang_dirty = 1;
1326 }
1327
1328 static int 
1329 _lang_list_sort(const void *data1, const void *data2) 
1330 {
1331    const E_Intl_Language_Node *ln1, *ln2;
1332    const char *trans1;
1333    const char *trans2;
1334    
1335    if (!data1) return 1;
1336    if (!data2) return -1;
1337    
1338    ln1 = data1;
1339    ln2 = data2;
1340
1341    if (!ln1->lang_name) return 1;
1342    trans1 = ln1->lang_name;
1343
1344    if (!ln2->lang_name) return -1;
1345    trans2 = ln2->lang_name;
1346    
1347    return (strcmp(trans1, trans2));
1348 }
1349
1350 static void 
1351 _lang_list_load(void *data) 
1352 {
1353    E_Config_Dialog_Data *cfdata;
1354    Eina_List *l;
1355    
1356    if (!data) return;
1357
1358    cfdata = data;
1359    if (!cfdata->lang_list) return;
1360
1361    evas_event_freeze(evas_object_evas_get(cfdata->gui.lang_list));
1362    edje_freeze();
1363    e_widget_ilist_freeze(cfdata->gui.lang_list);
1364    
1365    e_widget_ilist_append(cfdata->gui.lang_list, NULL, _("System Default"), NULL, NULL, "");
1366    for (l = cfdata->lang_list; l; l = l->next) 
1367      {
1368         E_Intl_Language_Node *ln;
1369         const char *trans;
1370         
1371         ln = l->data;
1372         if (!ln) continue;
1373         if (ln->lang_name)
1374           trans = ln->lang_name;
1375         else 
1376           trans = ln->lang_code;
1377         
1378         if (ln->lang_available)
1379           {
1380              Evas_Object *ic;
1381         
1382              ic = e_icon_add(cfdata->evas);
1383              e_util_icon_theme_set(ic, "dialog-ok-apply");
1384              e_widget_ilist_append(cfdata->gui.lang_list, ic, trans, NULL, NULL, ln->lang_code);
1385           }
1386         else
1387           e_widget_ilist_append(cfdata->gui.lang_list, NULL, trans, NULL, NULL, ln->lang_code);
1388
1389         if (cfdata->cur_lang && !strcmp(cfdata->cur_lang, ln->lang_code)) 
1390           {
1391              int count;
1392              
1393              count = e_widget_ilist_count(cfdata->gui.lang_list);
1394              e_widget_ilist_selected_set(cfdata->gui.lang_list, count - 1);
1395           }
1396      }
1397    e_widget_ilist_thaw(cfdata->gui.lang_list);
1398    edje_thaw();
1399    evas_event_thaw(evas_object_evas_get(cfdata->gui.lang_list));
1400 }
1401
1402 static int 
1403 _region_list_sort(const void *data1, const void *data2) 
1404 {
1405    const E_Intl_Region_Node *rn1, *rn2;
1406    const char *trans1;
1407    const char *trans2;
1408    
1409    if (!data1) return 1;
1410    if (!data2) return -1;
1411    
1412    rn1 = data1;
1413    rn2 = data2;
1414
1415    if (!rn1->region_name) return 1;
1416    trans1 = rn1->region_name;
1417
1418    if (!rn2->region_name) return -1;
1419    trans2 = rn2->region_name;
1420    
1421    return (strcmp(trans1, trans2));
1422 }
1423
1424 static void 
1425 _region_list_load(void *data) 
1426 {
1427    E_Config_Dialog_Data *cfdata;
1428    Eina_List *l;
1429    
1430    if (!data) return;
1431
1432    cfdata = data;
1433    if (!cfdata->region_list) return;
1434
1435    evas_event_freeze(evas_object_evas_get(cfdata->gui.reg_list));
1436    edje_freeze();
1437    e_widget_ilist_freeze(cfdata->gui.reg_list);
1438    
1439    for (l = cfdata->region_list; l; l = l->next) 
1440      {
1441         E_Intl_Region_Node *rn;
1442         const char *trans;
1443         
1444         rn = l->data;
1445         if (!rn) continue;
1446         if (rn->region_name)
1447           trans = rn->region_name;
1448         else 
1449           trans = rn->region_code;
1450         
1451         e_widget_ilist_append(cfdata->gui.reg_list, NULL, trans, NULL, NULL, rn->region_code);
1452   
1453         if (cfdata->cur_reg && !strcmp(cfdata->cur_reg, rn->region_code)) 
1454           {
1455              int count;
1456              
1457              count = e_widget_ilist_count(cfdata->gui.reg_list);
1458              e_widget_ilist_selected_set(cfdata->gui.reg_list, count - 1);
1459           }
1460      }
1461    e_widget_ilist_thaw(cfdata->gui.reg_list);
1462    edje_thaw();
1463    evas_event_thaw(evas_object_evas_get(cfdata->gui.reg_list));
1464 }
1465
1466 static int 
1467 _basic_lang_list_sort(const void *data1, const void *data2) 
1468 {
1469    const E_Intl_Pair *ln1, *ln2;
1470    const char *trans1;
1471    const char *trans2;
1472    
1473    if (!data1) return 1;
1474    if (!data2) return -1;
1475    
1476    ln1 = data1;
1477    ln2 = data2;
1478
1479    if (!ln1->locale_translation) return 1;
1480    trans1 = ln1->locale_translation;
1481
1482    if (!ln2->locale_translation) return -1;
1483    trans2 = ln2->locale_translation;
1484    
1485    return (strcmp(trans1, trans2));
1486 }
1487
1488 const char *
1489 _intl_charset_upper_get(const char *charset)
1490 {
1491    int i;
1492    
1493    i = 0;
1494    while (charset_predefined_pairs[i].locale_key)
1495      {
1496         if (!strcmp(charset_predefined_pairs[i].locale_key, charset))
1497           {
1498              return charset_predefined_pairs[i].locale_translation;
1499           }                      
1500         i++;                          
1501      }
1502    return NULL;
1503 }