Alexey Zavyalov: Add functionally Numbers, Currency, Time, Date tabs. Fix some bugs.
[reactos.git] / reactos / dll / cpl / intl_new / time.c
1 /*
2 * PROJECT: ReactOS International Control Panel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/intl/time.c
5 * PURPOSE: ReactOS International Control Panel
6 * PROGRAMMERS: Alexey Zavyalov (gen_x@mail.ru)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <windows.h>
12 #include <commctrl.h>
13 #include <cpl.h>
14
15 #include "intl.h"
16 #include "resource.h"
17
18 /* GLOBALS ******************************************************************/
19
20 #define NO_FLAG 0
21 #define MAX_TIME_FMT_SAMPLES 3
22 #define MAX_TIME_SEP_SAMPLES 1
23 #define MAX_TIME_AM_SAMPLES 2
24 #define MAX_TIME_PM_SAMPLES 2
25 #define EOLN_SIZE sizeof(WCHAR)
26 #define STD_TIME_SEP L":"
27
28 /* FUNCTIONS ****************************************************************/
29
30 /* if char is 'h' or 'H' or 'm' or 's' or 't' or ' ' return TRUE, else FALSE */
31 BOOL
32 isTimeComp(WCHAR walpha)
33 {
34
35 if((walpha == L'h') ||
36 (walpha == L'H') ||
37 (walpha == L'm') ||
38 (walpha == L's') ||
39 (walpha == L't') ||
40 (walpha == L' ')) return TRUE;
41 else return FALSE;
42 }
43
44 /* Find first time separator in string */
45 WCHAR*
46 FindTimeSep(const WCHAR *wszSourceStr)
47 {
48 int nDateCompCount=0;
49 int nDateSepCount=0;
50
51 WCHAR* wszFindedSep;
52 wszFindedSep=(WCHAR*) malloc(MAX_SAMPLES_STR_SIZE*sizeof(WCHAR));
53
54 wcscpy(wszFindedSep,STD_TIME_SEP);
55
56 while(nDateCompCount<wcslen(wszSourceStr))
57 {
58 if(!isTimeComp(wszSourceStr[nDateCompCount]) && (wszSourceStr[nDateCompCount]!=L'\''))
59 {
60 while(!isTimeComp(wszSourceStr[nDateCompCount]) && (wszSourceStr[nDateCompCount]!=L'\''))
61 {
62 wszFindedSep[nDateSepCount++]=wszSourceStr[nDateCompCount];
63 nDateCompCount++;
64 }
65 wszFindedSep[nDateSepCount]='\0';
66 return wszFindedSep;
67 }
68 nDateCompCount++;
69 }
70
71 return wszFindedSep;
72 }
73
74 /* Init time PM control box */
75 VOID
76 InitPM(HWND hwndDlg)
77 {
78 WCHAR wszTimePMSamples[MAX_TIME_PM_SAMPLES][MAX_SAMPLES_STR_SIZE]=
79 {
80 L"PM",
81 L""
82 };
83
84 int nCBIndex;
85 int nRetCode;
86
87 DWORD dwValueSize=MAX_SAMPLES_STR_SIZE*sizeof(WCHAR)+EOLN_SIZE;
88 WCHAR wszTimePM[MAX_SAMPLES_STR_SIZE];
89
90 /* Get current time PM */
91 GetLocaleInfoW(LOCALE_USER_DEFAULT,
92 LOCALE_S2359,
93 wszTimePM,
94 dwValueSize);
95
96 /* Clear all box content */
97 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEPM_COMBO),
98 CB_RESETCONTENT,
99 (WPARAM)0,
100 (LPARAM)0);
101
102 /* Create standart list of time PM */
103 for(nCBIndex=0;nCBIndex<MAX_TIME_PM_SAMPLES;nCBIndex++)
104 {
105 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEPM_COMBO),
106 CB_ADDSTRING,
107 nCBIndex,
108 (LPARAM)wszTimePMSamples[nCBIndex]);
109 }
110
111 /* Set current item to value from registry */
112 nRetCode = SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEPM_COMBO),
113 CB_SELECTSTRING,
114 -1,
115 (LPARAM)(LPCSTR)wszTimePM);
116
117 /* if is not success, add new value to list and select them */
118 if(nRetCode == CB_ERR)
119 {
120 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEPM_COMBO),
121 CB_ADDSTRING,
122 MAX_TIME_PM_SAMPLES+1,
123 (LPARAM)wszTimePM);
124 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEPM_COMBO),
125 CB_SELECTSTRING,
126 -1,
127 (LPARAM)(LPCSTR)wszTimePM);
128 }
129
130 }
131
132 /* Init time AM control box */
133 VOID
134 InitAM(HWND hwndDlg)
135 {
136 WCHAR wszTimeAMSamples[MAX_TIME_AM_SAMPLES][MAX_SAMPLES_STR_SIZE]=
137 {
138 L"AM",
139 L""
140 };
141
142 int nCBIndex;
143 int nRetCode;
144
145 DWORD dwValueSize=MAX_SAMPLES_STR_SIZE*sizeof(WCHAR)+EOLN_SIZE;
146 WCHAR wszTimeAM[MAX_SAMPLES_STR_SIZE];
147
148 /* Get current time AM */
149 GetLocaleInfoW(LOCALE_USER_DEFAULT,
150 LOCALE_S1159,
151 wszTimeAM,
152 dwValueSize);
153
154 /* Clear all box content */
155 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEAM_COMBO),
156 CB_RESETCONTENT,
157 (WPARAM)0,
158 (LPARAM)0);
159
160 /* Create standart list of time AM */
161 for(nCBIndex=0;nCBIndex<MAX_TIME_AM_SAMPLES;nCBIndex++)
162 {
163 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEAM_COMBO),
164 CB_ADDSTRING,
165 nCBIndex,
166 (LPARAM)wszTimeAMSamples[nCBIndex]);
167 }
168
169 /* Set current item to value from registry */
170 nRetCode = SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEAM_COMBO),
171 CB_SELECTSTRING,
172 -1,
173 (LPARAM)(LPCSTR)wszTimeAM);
174
175 /* if is not success, add new value to list and select them */
176 if(nRetCode == CB_ERR)
177 {
178 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEAM_COMBO),
179 CB_ADDSTRING,
180 MAX_TIME_AM_SAMPLES+1,
181 (LPARAM)wszTimeAM);
182 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEAM_COMBO),
183 CB_SELECTSTRING,
184 -1,
185 (LPARAM)(LPCSTR)wszTimeAM);
186 }
187
188 }
189
190 /* Init time separator control box */
191 VOID
192 InitTimeSeparatorCB(HWND hwndDlg)
193 {
194 WCHAR wszTimeSepSamples[MAX_TIME_SEP_SAMPLES][MAX_SAMPLES_STR_SIZE]=
195 {
196 L":"
197 };
198
199 int nCBIndex;
200 int nRetCode;
201
202 DWORD dwValueSize=MAX_SAMPLES_STR_SIZE*sizeof(WCHAR)+EOLN_SIZE;
203 WCHAR wszTimeSep[MAX_SAMPLES_STR_SIZE];
204
205 /* Get current time separator*/
206 GetLocaleInfoW(LOCALE_USER_DEFAULT,
207 LOCALE_STIME,
208 wszTimeSep,
209 dwValueSize);
210
211 /* Clear all box content */
212 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
213 CB_RESETCONTENT,
214 (WPARAM)0,
215 (LPARAM)0);
216
217 /* Create standart list of time separators */
218 for(nCBIndex=0;nCBIndex<MAX_TIME_SEP_SAMPLES;nCBIndex++)
219 {
220 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
221 CB_ADDSTRING,
222 nCBIndex,
223 (LPARAM)wszTimeSepSamples[nCBIndex]);
224 }
225
226 /* Set current item to value from registry */
227 nRetCode = SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
228 CB_SELECTSTRING,
229 -1,
230 (LPARAM)(LPCSTR)wszTimeSep);
231
232 /* if is not success, add new value to list and select them */
233 if(nRetCode == CB_ERR)
234 {
235 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
236 CB_ADDSTRING,
237 MAX_TIME_SEP_SAMPLES+1,
238 (LPARAM)wszTimeSep);
239 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
240 CB_SELECTSTRING,
241 -1,
242 (LPARAM)(LPCSTR)wszTimeSep);
243 }
244
245 }
246
247 /* Init time format control box */
248 VOID
249 InitTimeFormatCB(HWND hwndDlg)
250 {
251 WCHAR wszTimeFmtSamples[MAX_TIME_FMT_SAMPLES][MAX_SAMPLES_STR_SIZE]=
252 {
253 L"H:mm:ss",
254 L"HH:mm:ss",
255 L"h:mm:ss tt"
256 };
257
258 int nCBIndex;
259 int nRetCode;
260
261 DWORD dwValueSize=MAX_SAMPLES_STR_SIZE*sizeof(WCHAR)+EOLN_SIZE;
262 WCHAR wszTimeFmt[MAX_SAMPLES_STR_SIZE];
263
264 /* Get current time format */
265 GetLocaleInfoW(LOCALE_USER_DEFAULT,
266 LOCALE_STIMEFORMAT,
267 wszTimeFmt,
268 dwValueSize);
269
270 /* Clear all box content */
271 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEFMT_COMBO),
272 CB_RESETCONTENT,
273 (WPARAM)0,
274 (LPARAM)0);
275
276 /* Create standart list of time formats */
277 for(nCBIndex=0;nCBIndex<MAX_TIME_FMT_SAMPLES;nCBIndex++)
278 {
279 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEFMT_COMBO),
280 CB_ADDSTRING,
281 nCBIndex,
282 (LPARAM)wszTimeFmtSamples[nCBIndex]);
283 }
284
285 /* Set current item to value from registry */
286 nRetCode = SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEFMT_COMBO),
287 CB_SELECTSTRING,
288 -1,
289 (LPARAM)(LPCSTR)wszTimeFmt);
290
291 /* if is not success, add new value to list and select them */
292 if(nRetCode == CB_ERR)
293 {
294 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEFMT_COMBO),
295 CB_ADDSTRING,
296 MAX_TIME_FMT_SAMPLES+1,
297 (LPARAM)wszTimeFmt);
298 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEFMT_COMBO),
299 CB_SELECTSTRING,
300 -1,
301 (LPARAM)(LPCSTR)wszTimeFmt);
302 }
303 }
304
305 /* Set time format to registry */
306 BOOL
307 SetTimeFormat(HWND hwndDlg)
308 {
309 WCHAR wszTimeFmt[MAX_SAMPLES_STR_SIZE];
310 WCHAR wszTimeSep[MAX_SAMPLES_STR_SIZE];
311 WCHAR wszFindedTimeSep[MAX_SAMPLES_STR_SIZE];
312
313 WCHAR* pwszResultStr;
314 BOOL OpenApostFlg = FALSE;
315 int nFmtStrSize;
316 int nTimeCompCount;
317
318 /* Get setted format */
319 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEFMT_COMBO),
320 WM_GETTEXT,
321 (WPARAM)MAX_SAMPLES_STR_SIZE,
322 (LPARAM)(LPCSTR)wszTimeFmt);
323
324 /* Get setted separator */
325 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
326 WM_GETTEXT,
327 (WPARAM)MAX_SAMPLES_STR_SIZE,
328 (LPARAM)(LPCSTR)wszTimeSep);
329
330 /* Get setted format-string size */
331 nFmtStrSize = wcslen(wszTimeFmt);
332
333 /* Check date components */
334 for(nTimeCompCount=0;nTimeCompCount<nFmtStrSize;nTimeCompCount++)
335 {
336 if(wszTimeFmt[nTimeCompCount]==L'\'')
337 {
338 OpenApostFlg=!OpenApostFlg;
339 }
340 if(iswalnum(wszTimeFmt[nTimeCompCount]) &&
341 !isTimeComp(wszTimeFmt[nTimeCompCount]) &&
342 !OpenApostFlg)
343 {
344 MessageBoxW(NULL,
345 L"Entered time format contain incorrect symbol",
346 L"Error", MB_OK | MB_ICONERROR);
347 return FALSE;
348 }
349
350 }
351
352 if(OpenApostFlg)
353 {
354 MessageBoxW(NULL,
355 L"Entered time format contain incorrect symbol",
356 L"Error", MB_OK | MB_ICONERROR);
357 return FALSE;
358 }
359
360 /* substring replacement of separator */
361 wcscpy(wszFindedTimeSep,FindTimeSep(wszTimeFmt));
362 pwszResultStr = ReplaceSubStr(wszTimeFmt,wszTimeSep,wszFindedTimeSep);
363 wcscpy(wszTimeFmt,pwszResultStr);
364 free(pwszResultStr);
365
366 /* Save time format */
367 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, wszTimeFmt);
368
369 return TRUE;
370 }
371
372 /* Setted up time separator to registry */
373 BOOL
374 SetTimeSep(HWND hwndDlg)
375 {
376 WCHAR wszTimeSep[MAX_SAMPLES_STR_SIZE];
377 int nSepStrSize;
378 int nSepCount;
379
380 /* Get setted separator */
381 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMESEP_COMBO),
382 WM_GETTEXT,
383 (WPARAM)MAX_SAMPLES_STR_SIZE,
384 (LPARAM)(LPCSTR)wszTimeSep);
385
386 /* Get setted separator string size */
387 nSepStrSize = wcslen(wszTimeSep);
388
389 /* Check time components */
390 for(nSepCount=0;nSepCount<nSepStrSize;nSepCount++)
391 {
392 if(iswalnum(wszTimeSep[nSepCount]) || (wszTimeSep[nSepCount]=='\''))
393 {
394 MessageBoxW(NULL,
395 L"Entered time separator contain incorrect symbol",
396 L"Error", MB_OK | MB_ICONERROR);
397 return FALSE;
398 }
399
400 }
401
402 /* Save time separator */
403 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STIME, wszTimeSep);
404
405 return TRUE;
406 }
407
408 /* Setted up time AM to registry */
409 BOOL
410 SetTimeAM(HWND hwndDlg)
411 {
412 WCHAR wszTimeAM[MAX_SAMPLES_STR_SIZE];
413
414 /* Get setted separator */
415 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEAM_COMBO),
416 WM_GETTEXT,
417 (WPARAM)MAX_SAMPLES_STR_SIZE,
418 (LPARAM)(LPCSTR)wszTimeAM);
419
420 /* Save time AM */
421 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_S1159, wszTimeAM);
422
423 return TRUE;
424 }
425
426 /* Setted up time PM to registry */
427 BOOL
428 SetTimePM(HWND hwndDlg)
429 {
430 WCHAR wszTimePM[MAX_SAMPLES_STR_SIZE];
431
432 /* Get setted separator */
433 SendMessageW(GetDlgItem(hwndDlg, IDC_TIMEPM_COMBO),
434 WM_GETTEXT,
435 (WPARAM)MAX_SAMPLES_STR_SIZE,
436 (LPARAM)(LPCSTR)wszTimePM);
437
438 /* Save time PM */
439 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_S2359, wszTimePM);
440
441 return TRUE;
442 }
443
444 /* Update all time locale samples */
445 static
446 VOID
447 UpdateTimeLocaleSamples(HWND hwndDlg,
448 LCID lcidLocale)
449 {
450 WCHAR OutBuffer[MAX_FMT_SIZE];
451
452 /* Get time format sample */
453 GetTimeFormatW(lcidLocale,
454 NO_FLAG,
455 NULL,
456 NULL,
457 OutBuffer,
458 MAX_FMT_SIZE);
459 SendMessageW(GetDlgItem(hwndDlg, IDC_TIME_EDIT),
460 WM_SETTEXT,
461 0,
462 (LPARAM)OutBuffer);
463
464 /* TODO: Add unknown control box processing */
465 }
466
467 /* Date options setup page dialog callback */
468 INT_PTR
469 CALLBACK
470 TimeOptsSetProc(HWND hwndDlg,
471 UINT uMsg,
472 WPARAM wParam,
473 LPARAM lParam)
474 {
475 UNREFERENCED_PARAMETER(lParam);
476 UNREFERENCED_PARAMETER(wParam);
477 UNREFERENCED_PARAMETER(hwndDlg);
478 switch(uMsg)
479 {
480 case WM_INITDIALOG:
481 {
482 InitTimeFormatCB(hwndDlg);
483 InitTimeSeparatorCB(hwndDlg);
484 InitAM(hwndDlg);
485 InitPM(hwndDlg);
486 UpdateTimeLocaleSamples(hwndDlg, LOCALE_USER_DEFAULT);
487 }
488 break;
489
490 case WM_COMMAND:
491 {
492 switch (LOWORD(wParam))
493 {
494 case IDC_TIMEFMT_COMBO:
495 case IDC_TIMESEP_COMBO:
496 case IDC_TIMEAM_COMBO:
497 case IDC_TIMEPM_COMBO:
498 {
499 if (HIWORD(wParam) == CBN_SELCHANGE ||
500 HIWORD(wParam) == CBN_EDITCHANGE)
501 {
502 /* Set "Apply" button enabled */
503 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
504 }
505 }
506 break;
507 }
508 }
509 break;
510
511 case WM_NOTIFY:
512 {
513 LPNMHDR lpnm = (LPNMHDR)lParam;
514 /* If push apply button */
515 if (lpnm->code == (UINT)PSN_APPLY)
516 {
517 if(!SetTimeFormat(hwndDlg)) break;
518 if(!SetTimeSep(hwndDlg)) break;
519 if(!SetTimeAM(hwndDlg)) break;
520 if(!SetTimePM(hwndDlg)) break;
521
522 InitTimeFormatCB(hwndDlg);
523
524
525 /* FIXME: */
526 _sleep(15);
527 UpdateTimeLocaleSamples(hwndDlg, LOCALE_USER_DEFAULT);
528 }
529 }
530 break;
531 }
532 return FALSE;
533 }
534
535
536 /* EOF */