* Sync up to trunk head (r65147).
[reactos.git] / dll / cpl / intl / generalp.c
1 /*
2 * ReactOS
3 * Copyright (C) 2004, 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * PROJECT: ReactOS International Control Panel
21 * FILE: dll/cpl/intl/generalp.c
22 * PURPOSE: General property page
23 * PROGRAMMER: Eric Kohl
24 * Klemens Friedl
25 * Aleksey Bragin
26 */
27
28 #include "intl.h"
29
30 #include <debug.h>
31
32 #define SAMPLE_NUMBER _T("123456789")
33 #define NO_FLAG 0
34
35 HWND hList;
36 HWND hLocaleList, hGeoList;
37 BOOL bSpain = FALSE;
38
39 static BOOL CALLBACK
40 LocalesEnumProc(LPTSTR lpLocale)
41 {
42 LCID lcid;
43 TCHAR lang[255];
44 INT index;
45 BOOL bNoShow = FALSE;
46
47 lcid = _tcstoul(lpLocale, NULL, 16);
48
49 /* Display only languages with installed support */
50 if (!IsValidLocale(lcid, LCID_INSTALLED))
51 return TRUE;
52
53 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) ||
54 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT))
55 {
56 if (bSpain == FALSE)
57 {
58 LoadString(hApplet, IDS_SPAIN, lang, 255);
59 bSpain = TRUE;
60 }
61 else
62 {
63 bNoShow = TRUE;
64 }
65 }
66 else
67 {
68 GetLocaleInfo(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(TCHAR));
69 }
70
71 if (bNoShow == FALSE)
72 {
73 index = SendMessage(hList,
74 CB_ADDSTRING,
75 0,
76 (LPARAM)lang);
77
78 SendMessage(hList,
79 CB_SETITEMDATA,
80 index,
81 (LPARAM)lcid);
82 }
83
84 return TRUE;
85 }
86
87 /* Update all locale samples */
88 static VOID
89 UpdateLocaleSample(HWND hwndDlg, LCID lcidLocale)
90 {
91 TCHAR OutBuffer[MAX_SAMPLES_STR_SIZE];
92
93 /* Get number format sample */
94 GetNumberFormat(lcidLocale, NO_FLAG, SAMPLE_NUMBER, NULL, OutBuffer,
95 MAX_SAMPLES_STR_SIZE);
96 SendMessage(GetDlgItem(hwndDlg, IDC_NUMSAMPLE_EDIT),
97 WM_SETTEXT, 0, (LPARAM)OutBuffer);
98
99 /* Get monetary format sample */
100 GetCurrencyFormat(lcidLocale, LOCALE_USE_CP_ACP, SAMPLE_NUMBER, NULL,
101 OutBuffer, MAX_SAMPLES_STR_SIZE);
102 SendMessage(GetDlgItem(hwndDlg, IDC_MONEYSAMPLE_EDIT),
103 WM_SETTEXT, 0, (LPARAM)OutBuffer);
104
105 /* Get time format sample */
106 GetTimeFormat(lcidLocale, NO_FLAG, NULL, NULL, OutBuffer, MAX_SAMPLES_STR_SIZE);
107 SendMessage(GetDlgItem(hwndDlg, IDC_TIMESAMPLE_EDIT),
108 WM_SETTEXT,
109 0,
110 (LPARAM)OutBuffer);
111
112 /* Get short date format sample */
113 GetDateFormat(lcidLocale, DATE_SHORTDATE, NULL, NULL, OutBuffer,
114 MAX_SAMPLES_STR_SIZE);
115 SendMessage(GetDlgItem(hwndDlg, IDC_SHORTTIMESAMPLE_EDIT), WM_SETTEXT,
116 0, (LPARAM)OutBuffer);
117
118 /* Get long date sample */
119 GetDateFormat(lcidLocale, DATE_LONGDATE, NULL, NULL, OutBuffer,
120 MAX_SAMPLES_STR_SIZE);
121 SendMessage(GetDlgItem(hwndDlg, IDC_FULLTIMESAMPLE_EDIT),
122 WM_SETTEXT, 0, (LPARAM)OutBuffer);
123 }
124
125 static VOID
126 CreateLanguagesList(HWND hwnd)
127 {
128 TCHAR langSel[255];
129
130 hList = hwnd;
131 bSpain = FALSE;
132 EnumSystemLocales(LocalesEnumProc, LCID_SUPPORTED);
133
134 /* Select current locale */
135 /* or should it be System and not user? */
136 GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(TCHAR));
137
138 SendMessage(hList,
139 CB_SELECTSTRING,
140 -1,
141 (LPARAM)langSel);
142 }
143
144 /* Sets new locale */
145 VOID
146 SetNewLocale(LCID lcid)
147 {
148 // HKCU\\Control Panel\\International\\Locale = 0409 (type=0)
149 // HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","Default",0x00000000,"0409" (type=0)
150 // HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","InstallLanguage",0x00000000,"0409" (type=0)
151
152 // Set locale
153 HKEY localeKey;
154 HKEY langKey;
155 DWORD ret;
156 TCHAR value[9];
157 DWORD valuesize;
158 TCHAR ACPPage[9];
159 TCHAR OEMPage[9];
160
161 ret = GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, OEMPage, sizeof(OEMPage)/sizeof(TCHAR));
162 if (ret == 0)
163 {
164 PrintErrorMsgBox(IDS_ERROR_OEM_CODE_PAGE);
165 return;
166 }
167
168 ret = GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, ACPPage, sizeof(ACPPage)/sizeof(TCHAR));
169 if (ret == 0)
170 {
171 PrintErrorMsgBox(IDS_ERROR_ANSI_CODE_PAGE);
172 return;
173 }
174
175 ret = RegOpenKey(HKEY_CURRENT_USER, _T("Control Panel\\International"), &localeKey);
176 if (ret != ERROR_SUCCESS)
177 {
178 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG);
179 return;
180 }
181
182 wsprintf(value, _T("%04X"), (DWORD)lcid);
183 valuesize = (_tcslen(value) + 1) * sizeof(TCHAR);
184
185 RegSetValueEx(localeKey, _T("Locale"), 0, REG_SZ, (LPBYTE)value, valuesize);
186 RegCloseKey(localeKey);
187
188 ret = RegOpenKey(HKEY_USERS, _T(".DEFAULT\\Control Panel\\International"), &localeKey);
189 if (ret != ERROR_SUCCESS)
190 {
191 PrintErrorMsgBox(IDS_ERROR_DEF_INT_KEY_REG);
192 return;
193 }
194
195 wsprintf(value, _T("%04X"), (DWORD)lcid);
196 valuesize = (_tcslen(value) + 1) * sizeof(TCHAR);
197
198 RegSetValueEx(localeKey, _T("Locale"), 0, REG_SZ, (BYTE *)value, valuesize);
199 RegCloseKey(localeKey);
200
201 // Set language
202 ret = RegOpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Language"), &langKey);
203 if (ret != ERROR_SUCCESS)
204 {
205 PrintErrorMsgBox(IDS_ERROR_NLS_KEY_REG);
206 return;
207 }
208
209 RegSetValueEx(langKey, _T("Default"), 0, REG_SZ, (BYTE *)value, valuesize );
210 RegSetValueEx(langKey, _T("InstallLanguage"), 0, REG_SZ, (BYTE *)value, valuesize );
211
212 RegCloseKey(langKey);
213
214
215 /* Set language */
216 ret = RegOpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage"), &langKey);
217 if (ret != ERROR_SUCCESS)
218 {
219 PrintErrorMsgBox(IDS_ERROR_NLS_CODE_REG);
220 return;
221 }
222
223 RegSetValueExW(langKey, _T("OEMCP"), 0, REG_SZ, (BYTE *)OEMPage, (_tcslen(OEMPage) +1 ) * sizeof(TCHAR));
224 RegSetValueExW(langKey, _T("ACP"), 0, REG_SZ, (BYTE *)ACPPage, (_tcslen(ACPPage) +1 ) * sizeof(TCHAR));
225
226 RegCloseKey(langKey);
227 }
228
229 /* Location enumerate procedure */
230 BOOL
231 CALLBACK
232 LocationsEnumProc(GEOID gId)
233 {
234 TCHAR loc[MAX_STR_SIZE];
235 INT index;
236
237 if(GetGeoInfo(gId, GEO_FRIENDLYNAME, loc, MAX_STR_SIZE, LANG_SYSTEM_DEFAULT) == 0)
238 return TRUE;
239
240 index = (INT)SendMessage(hGeoList,
241 CB_ADDSTRING,
242 0,
243 (LPARAM)loc);
244
245 SendMessage(hGeoList,
246 CB_SETITEMDATA,
247 index,
248 (LPARAM)gId);
249
250 return TRUE;
251 }
252
253 /* Enumerate all system locations identifiers */
254 static
255 VOID
256 CreateLocationsList(HWND hWnd)
257 {
258 GEOID userGeoID;
259 TCHAR loc[MAX_STR_SIZE];
260
261 hGeoList = hWnd;
262
263 EnumSystemGeoID(GEOCLASS_NATION, 0, LocationsEnumProc);
264
265 /* Select current location */
266 userGeoID = GetUserGeoID(GEOCLASS_NATION);
267 GetGeoInfo(userGeoID,
268 GEO_FRIENDLYNAME,
269 loc,
270 MAX_STR_SIZE,
271 LANG_SYSTEM_DEFAULT);
272
273 SendMessage(hGeoList,
274 CB_SELECTSTRING,
275 (WPARAM) -1,
276 (LPARAM)loc);
277 }
278
279 DWORD
280 VerifyUnattendLCID(HWND hwndDlg)
281 {
282 LRESULT lCount, lIndex, lResult;
283
284 lCount = SendMessage(hList, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
285 if (lCount == CB_ERR)
286 {
287 return 0;
288 }
289
290 for (lIndex = 0; lIndex < lCount; lIndex++)
291 {
292 lResult = SendMessage(hList, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
293 if (lResult == CB_ERR)
294 {
295 continue;
296 }
297
298 if (lResult == (LRESULT)UnattendLCID)
299 {
300 SendMessage(hList, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
301 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
302 return 1;
303 }
304 }
305
306 return 0;
307 }
308
309
310 /* Property page dialog callback */
311 INT_PTR CALLBACK
312 GeneralPageProc(HWND hwndDlg,
313 UINT uMsg,
314 WPARAM wParam,
315 LPARAM lParam)
316 {
317 switch(uMsg)
318 {
319 case WM_INITDIALOG:
320 CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST));
321 UpdateLocaleSample(hwndDlg, LOCALE_USER_DEFAULT);
322 CreateLocationsList(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO));
323 if (IsUnattendedSetupEnabled)
324 {
325 if (VerifyUnattendLCID(hwndDlg))
326 {
327 SetNewLocale(UnattendLCID);
328 PostQuitMessage(0);
329 } else
330 DPRINT1("VerifyUnattendLCID failed\n");
331 return TRUE;
332 }
333 break;
334
335 case WM_COMMAND:
336 switch (LOWORD(wParam))
337 {
338 case IDC_LANGUAGELIST:
339 if (HIWORD(wParam) == CBN_SELCHANGE)
340 {
341 LCID NewLcid;
342 INT iCurSel;
343
344 iCurSel = SendMessage(hList,
345 CB_GETCURSEL,
346 0,
347 0);
348 if (iCurSel == CB_ERR)
349 break;
350
351 NewLcid = SendMessage(hList,
352 CB_GETITEMDATA,
353 iCurSel,
354 0);
355 if (NewLcid == (LCID)CB_ERR)
356 break;
357
358 UpdateLocaleSample(hwndDlg, NewLcid);
359
360 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
361 }
362 break;
363
364 case IDC_LOCATION_COMBO:
365 if (HIWORD(wParam) == CBN_SELCHANGE)
366 {
367 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
368 }
369 break;
370 case IDC_SETUP_BUTTON:
371 {
372 LCID NewLcid;
373 INT iCurSel;
374
375 iCurSel = SendMessage(hList,
376 CB_GETCURSEL,
377 0,
378 0);
379 if (iCurSel == CB_ERR)
380 break;
381
382 NewLcid = SendMessage(hList,
383 CB_GETITEMDATA,
384 iCurSel,
385 0);
386 if (NewLcid == (LCID)CB_ERR)
387 break;
388
389 SetupApplet(GetParent(hwndDlg), NewLcid);
390 }
391 break;
392 }
393 break;
394
395 case WM_NOTIFY:
396 {
397 LPNMHDR lpnm = (LPNMHDR)lParam;
398
399 if (lpnm->code == (UINT)PSN_APPLY)
400 {
401 /* Apply changes */
402 LCID NewLcid;
403 GEOID NewGeoID;
404 INT iCurSel;
405
406 PropSheet_UnChanged(GetParent(hwndDlg), hwndDlg);
407
408 /* Acquire new value */
409 iCurSel = SendMessage(hList,
410 CB_GETCURSEL,
411 0,
412 0);
413 if (iCurSel == CB_ERR)
414 break;
415
416 NewLcid = SendMessage(hList,
417 CB_GETITEMDATA,
418 iCurSel,
419 0);
420 if (NewLcid == (LCID)CB_ERR)
421 break;
422
423 iCurSel = SendMessage(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO),
424 CB_GETCURSEL,
425 0,
426 0);
427 if (iCurSel == CB_ERR)
428 break;
429
430 NewGeoID = SendMessage(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO),
431 CB_GETITEMDATA,
432 iCurSel,
433 0);
434 if (NewGeoID == (GEOID)CB_ERR)
435 break;
436
437 /* Set new locale */
438 SetNewLocale(NewLcid);
439 AddNewKbLayoutsByLcid(NewLcid);
440 SetUserGeoID(NewGeoID);
441 SetNonUnicodeLang(hwndDlg, NewLcid);
442 }
443 }
444 break;
445 }
446
447 return FALSE;
448 }
449
450 /* EOF */