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