1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: Dk4WxApplicationHelper.cpt
12 */
13
14 /** @file Dk4WxApplicationHelper.cpp The Dk4WxApplicationHelper module.
15 */
16
17
18 #include "dk4conf.h"
19
20 #include <libdk4wx/Dk4WxApplicationHelper.h>
21
22 #include <libdk4base/dk4mem.h>
23 #include <libdk4c/dk4enc.h>
24 #include <libdk4base/dk4strd.h>
25 #include <libdk4wx/dk4strx.h>
26 #include <libdk4wx/dk4recwx.h>
27 #include <libdk4wx/dk4wxpref.h>
28 #include <libdk4wx/dk4wxstt.h>
29 #include <libdk4c/dk4hnamed.h>
30 #include <libdk4c/dk4loc.h>
31 #include <libdk4c/dk4user.h>
32 #include <libdk4base/dk4mpl.h>
33 #include <libdk4base/dk4vers.h>
34 #include <libdk4c/dk4exepd.h>
35 #include <libdk4c/dk4inst.h>
36 #include <libdk4c/dk4pathd.h>
37 #if DK4_SIZEOF_WXCHAR > 1
38 #include <libdk4base/dk4strw.h>
39 #include <libdk4maiowd/dk4maiwdil.h>
40 #include <libdk4maiowd/dk4maiwdbl.h>
41 #else
42 #include <libdk4base/dk4str8.h>
43 #include <libdk4maio8d/dk4mai8dil.h>
44 #include <libdk4maio8d/dk4mai8dbl.h>
45 #endif
46
47
48
49
50
51
52
53 /* ************************************************************************ */
54 /* * * */
55 /* * Type definitions. * */
56 /* * * */
57 /* ************************************************************************ */
58
59
60
61
62 /** Pointer to constant wxChar.
63 */
64 typedef const wxChar *PCWXCHAR;
65
66
67
68
69
70
71 /* ************************************************************************ */
72 /* * * */
73 /* * Variables. * */
74 /* * * */
75 /* ************************************************************************ */
76
77
78
79
80 /** Empty string, returned for all strings not found.
81 */
82 static const wxChar dk4wxah_empty_string[] = { wxT("") };
83
84
85
86 /** File name separator string
87 */
88 static const dkChar dk4wxah_fnsep_str[] = {
89 #if DK4_ON_WINDOWS
90 dkT("\\")
91 #else
92 dkT("/")
93 #endif
94 } ;
95
96
97
98 /** Texts used in error message boxes in the Initialize() function.
99 */
100 static const wxChar * const dkwxah_msgb_texts[] = {
101 /* 0 */
102 wxT("Initialization failed!"),
103
104 /* 1 */
105 wxT("Not enough memory!"),
106
107 /* 2 */
108 wxT("Failed to find current host name!"),
109
110 /* 3 */
111 wxT("Failed to find language, region, and encoding settings!"),
112
113 /* 4 */
114 wxT("Failed to find users login name!"),
115
116 /* 5 */
117 wxT("Failed to find users home directory!"),
118
119 /* 6 */
120 wxT("Failed to find executable file name!"),
121
122 /* 7 */
123 wxT("Executable file name too long!"),
124
125 /* 8 */
126 wxT("Illegal arguments (NULL pointers) to Initialize() function!"),
127
128 NULL
129
130 };
131
132
133
134 /** Constant text keywords used by module, not localized.
135 */
136 static const dkChar * const dk4wxah_kwnl_dk[] = {
137 /* 0 */
138 dkT("dk4wxbase.str"),
139
140 NULL
141
142 };
143
144
145
146 /** Constant text strings used by the module, not localized.
147 */
148 static const char * const dk4wxah_kwnl_c8[] = {
149 /* 0 */
150 "C",
151
152 NULL
153
154 };
155
156
157
158 /** Final directory names for good installations.
159 */
160 static const dkChar * const dk4wxah_final_directories[] = {
161 /* 0 */
162 dkT("bin"),
163
164 /* 1 */
165 dkT("sbin"),
166
167 /* 2 */
168 dkT("libexec"),
169
170 /* 3 */
171 dkT("lib"),
172
173 NULL
174
175 };
176
177
178
179 /** New final directory names to append.
180 */
181 static const dkChar * const dk4wxah_new_directories[] = {
182 /* 0 */
183 dkT("etc"),
184
185 /* 1 */
186 dkT("share"),
187
188 NULL
189
190 };
191
192
193
194 /** Basic strings, replaced by localized texts later.
195 */
196 static const wxChar * const dk4wxah_basic_strings[] = {
197 /* 0 */
198 wxT("Help file not found"),
199
200 /* 1 */
201 wxT("The file containing online help text was not found on your computer!"),
202
203 /* 2 */
204 wxT("Processing in progress"),
205
206 /* 3 */
207 wxT("Cancel"),
208
209 /* 4 */
210 wxT("Abort current operation"),
211
212 /* 5 */
213 wxT("Abortion scheduled, wait please!"),
214
215 /* 6 */
216 wxT("Error"),
217
218 /* 7 */
219 wxT("Not enough memory (RAM)!"),
220
221 /* 8 */
222 wxT("Illegal arguments in Dk4WxHelpController constructor (bug)!"),
223
224 /* 9 */
225 wxT("File not found"),
226
227 /* 10 */
228 wxT("The file to display was not found!"),
229
230 /* 11 */
231 wxT("Error"),
232
233 /* 12 */
234 wxT("Failed to start browser or application for file\n\""),
235
236 /* 13 */
237 wxT("\"."),
238
239 /* 14 */
240 wxT("Yes"),
241
242 /* 15 */
243 wxT("No"),
244
245 NULL
246
247 };
248
249
250
251 /* ************************************************************************ */
252 /* * * */
253 /* * Internal tool functions, not object-oriented. * */
254 /* * * */
255 /* ************************************************************************ */
256
257
258
259
260 /** Check whether a directory or file name ends in one of
261 the names mentioned in array.
262 @param dirname Directory name to check.
263 @param array String array containing name ends.
264 @return 1 on success with prefix in dirname, 0 on error.
265 */
266 static
267 int
dk4wxapplicationhelper_isinsub(dkChar * dirname,const dkChar * const * array)268 dk4wxapplicationhelper_isinsub(dkChar *dirname, const dkChar * const *array)
269 {
270 dkChar *p1;
271 dkChar *p2;
272 int cc; /* Flag: Can continue */
273 int back = 0; /* Function result */
274
275 do {
276 cc = 0;
277 p1 = dirname; p2 = NULL;
278 while (dkT('\0') != *p1) {
279 if ((dkT('/') == *p1) || (dkT('\\') == *p1)) { p2 = p1; }
280 p1++;
281 }
282 if (NULL != p2) {
283 *(p2++) = dkT('\0');
284 cc = 1;
285 #if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
286 if (0 <= dk4str_array_index(array, p2, 0))
287 #else
288 if (0 <= dk4str_array_index(array, p2, 1))
289 #endif
290 {
291 back = 1;
292 cc = 0;
293 }
294 } else {
295 }
296 } while ((1 == cc) && (0 == back));
297
298 return back;
299 }
300
301
302
303 /* ************************************************************************ */
304 /* * * */
305 /* * Constructor, destructor, initialization and cleanup. * */
306 /* * * */
307 /* ************************************************************************ */
308
309
310
311
Dk4WxApplicationHelper()312 Dk4WxApplicationHelper::Dk4WxApplicationHelper()
313 {
314 /* Set all member variables to "resource not available".
315 Real initialization is in the Initialize() method.
316 */
317
318 ppBasicStrings = NULL;
319 pcwxsArgv0 = NULL;
320 pcwxsVendor = NULL;
321 pcdksGroup = NULL;
322 pwxsApp = NULL;
323 pcdksArgv0 = NULL;
324 pdksHost = NULL;
325 pdksLogname = NULL;
326 pdksHome = NULL;
327 pdksApp = NULL;
328 pdksSysconf = NULL;
329 pdksShare = NULL;
330 pwxsShare = NULL;
331 pdksLanguage = NULL;
332 pdksRegion = NULL;
333 sStt = NULL;
334 iStt = NULL;
335 sPrSys = NULL;
336 iPrSys = NULL;
337 sPrUser = NULL;
338 iPrUser = NULL;
339 nBasicStrings = 0;
340 #if DK4_ON_WINDOWS
341 iDkEncoding = DK4_ENCODING_WIN1252;
342 iWxEncoding = DK4_ENCODING_WIN1252;
343 iFiEncoding = DK4_FILE_ENCODING_WIN1252;
344 #else
345 iDkEncoding = DK4_ENCODING_PLAIN;
346 iWxEncoding = DK4_ENCODING_PLAIN;
347 iFiEncoding = DK4_FILE_ENCODING_PLAIN;
348 #endif
349 bActive = false;
350
351 }
352
353
354 /*
355 We do not need a critical section locker as Initialize()
356 is invoked from the applications OnInit() method. At this
357 time there is no top level window or worker thread yet.
358 */
359 bool
Initialize(const wxChar * argv0,const wxChar * vendorName,const dkChar * groupName,dk4_er_t * erp)360 Dk4WxApplicationHelper::Initialize(
361 const wxChar *argv0,
362 const wxChar *vendorName,
363 const dkChar *groupName,
364 dk4_er_t *erp
365 )
366 {
367 dkChar labuf[DK4_MAX_PATH];
368 dkChar rebuf[DK4_MAX_PATH];
369 wxChar anbuf[DK4_MAX_PATH];
370 const wxChar *msgbtext = NULL;
371 const wxChar *msgbtitle = NULL;
372 dkChar *p1;
373 dkChar *p2;
374 #if DK4_ON_WINDOWS
375 dkChar *p4;
376 #endif
377 size_t szrebuf = DK4_SIZEOF(rebuf,dkChar);
378 size_t szlabuf = DK4_SIZEOF(labuf,dkChar);
379 size_t szanbuf = DK4_SIZEOF(anbuf,wxChar);
380 int errc = ERROR_NONE;
381 int res;
382 int pn;
383 bool back = false;
384
385 /* Keep some of the arguments.
386 */
387 if ((NULL == argv0) || (NULL == vendorName) || (NULL == groupName)) {
388 errc = ERROR_ARGUMENTS;
389 goto finished;
390 }
391 pcwxsArgv0 = argv0;
392 pcwxsVendor = vendorName;
393 pcdksGroup = groupName;
394
395
396 /* Some default values.
397 */
398 ppBasicStrings = dk4wxah_basic_strings;
399 nBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1;
400
401
402 /* Host name.
403 */
404 if (0 != dk4hostname(labuf, szlabuf, NULL)) {
405 p1 = dk4str_chr(labuf, dkT('.'));
406 if (NULL != p1) { *p1 = dkT('\0'); }
407 pdksHost = dk4str_dup(labuf, NULL);
408 if (NULL == pdksHost) {
409 errc = ERROR_MEMORY;
410 goto finished;
411 }
412 } else {
413 errc = ERROR_HOSTNAME;
414 goto finished;
415 }
416
417
418 /* Language and encoding.
419 */
420 res = dk4loc_get_settings(labuf, szlabuf, rebuf, szrebuf, &iDkEncoding, erp);
421 if (0 == res) {
422 errc = ERROR_LANG_REG_ENC;
423 goto finished;
424 }
425 #if DK4_SIZEOF_WXCHAR > 1
426 #if DK4_SIZEOF_WXCHAR > 2
427 iWxEncoding = DK4_ENCODING_32;
428 #else
429 iWxEncoding = DK4_ENCODING_UTF16;
430 #endif
431 #else
432 switch (iDkEncoding) {
433 case DK4_ENCODING_WIN1252 : {
434 iWxEncoding = DK4_ENCODING_WIN1252;
435 } break;
436 case DK4_ENCODING_UTF8 : {
437 iWxEncoding = DK4_ENCODING_UTF8;
438 } break;
439 default : {
440 #if DK4_ON_WINDOWS
441 iWxEncoding = DK4_ENCODING_WIN1252;
442 #else
443 iWxEncoding = DK4_ENCODING_PLAIN;
444 #endif
445 } break;
446 }
447 #endif
448 switch (iDkEncoding) {
449 case DK4_ENCODING_WIN1252 : {
450 iFiEncoding = DK4_ENCODING_WIN1252;
451 } break;
452 case DK4_ENCODING_UTF8 : {
453 iFiEncoding = DK4_ENCODING_UTF8;
454 } break;
455 default : {
456 #if DK4_ON_WINDOWS
457 iFiEncoding = DK4_ENCODING_WIN1252;
458 #else
459 iFiEncoding = DK4_ENCODING_PLAIN;
460 #endif
461 } break;
462 }
463 if (0 < dk4str_len(labuf)) {
464 pdksLanguage = dk4str_dup(labuf, erp);
465 if (NULL == pdksLanguage) {
466 errc = ERROR_MEMORY;
467 goto finished;
468 }
469 }
470 if (0 < dk4str_len(rebuf)) {
471 pdksRegion = dk4str_dup(rebuf, erp);
472 if (NULL == pdksRegion) {
473 errc = ERROR_MEMORY;
474 goto finished;
475 }
476 }
477
478
479 /* Login name and home directory.
480 */
481 res = dk4user_get_logname(labuf, szlabuf, 0, erp);
482 if (0 == res) {
483 errc = ERROR_LOGNAME;
484 goto finished;
485 }
486 pdksLogname = dk4str_dup(labuf, erp);
487 if (NULL == pdksLogname) {
488 errc = ERROR_MEMORY;
489 goto finished;
490 }
491 res = dk4user_get_homedir(labuf, szlabuf, 0, erp);
492 if (0 == res) {
493 errc = ERROR_HOMEDIR;
494 goto finished;
495 }
496 pdksHome = dk4str_dup(labuf, erp);
497 if (NULL == pdksHome) {
498 errc = ERROR_MEMORY;
499 goto finished;
500 }
501
502
503 /* System configuration and data directory.
504 */
505 res = dk4recwx_wxchar_to_dkchar(
506 labuf, szlabuf, iDkEncoding, argv0, iWxEncoding, erp
507 );
508 if (0 == res) {
509 errc = ERROR_EXECUTABLE;
510 goto finished;
511 }
512 pcdksArgv0 = dk4str_dup(labuf, erp);
513 if (NULL == pcdksArgv0) {
514 errc = ERROR_MEMORY;
515 goto finished;
516 }
517 res = dk4execpath(
518 rebuf, szrebuf, ((0 != res) ? labuf : NULL), erp
519 );
520 if (0 == res) {
521 errc = ERROR_EXECUTABLE;
522 goto finished;
523 }
524 p1 = rebuf;
525 p2 = NULL;
526 while (dkT('\0') != *p1) {
527 if (dk4wxah_fnsep_str[0] == *p1) { p2 = p1; }
528 /* We must increase this pointer.
529 */
530 p1++;
531 }
532 if (NULL == p2) {
533 errc = ERROR_EXECUTABLE;
534 goto finished;
535 }
536 *(p2++) = dkT('\0');
537 /* Binary directory in rebuf, p2 is application name */
538 #if DK4_ON_WINDOWS
539 /* On Windows, strip .exe suffix.
540 */
541 p4 = dk4path_get_suffix(p2, NULL);
542 if (NULL != p4) { *p4 = dkT('\0'); }
543 #endif
544 pdksApp = dk4str_dup(p2, NULL);
545 if (NULL == pdksApp) {
546 errc = ERROR_MEMORY;
547 goto finished;
548 }
549 res = dk4recwx_dkchar_to_wxchar(
550 anbuf, szanbuf, iWxEncoding, pdksApp, iDkEncoding, NULL
551 );
552 if (0 == res) {
553 errc = ERROR_EXECUTABLE;
554 goto finished;
555 }
556 pwxsApp = dk4strx_dup(anbuf, NULL);
557 if (NULL == pwxsApp) {
558 errc = ERROR_MEMORY;
559 goto finished;
560 }
561 /* Check whether the binary resides in one of the installation directories */
562 res = 0;
563 if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(4), NULL)) {
564 res = 1;
565 }
566 if (0 == res) {
567 if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(5), NULL)) {
568 res = 1;
569 }
570 }
571 if (0 == res) {
572 if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(6), NULL)) {
573 res = 1;
574 }
575 }
576 if (0 == res) {
577 if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(10), NULL)) {
578 res = 1;
579 }
580 }
581 if (0 != res) {
582 pdksSysconf = dk4str_dup(dk4inst_get_directory(1), NULL);
583 pdksShare = dk4str_dup(dk4inst_get_directory(2), NULL);
584 UpdateWxsShare();
585 if ((NULL == pdksSysconf) || (NULL == pdksShare)) {
586 errc = ERROR_MEMORY;
587 goto finished;
588 }
589 } else {
590 dk4str_cpy_s(labuf, szlabuf, rebuf, NULL);
591 if (0 != dk4wxapplicationhelper_isinsub(labuf, dk4wxah_final_directories)) {
592 res = 0;
593 if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) {
594 if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) {
595 if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[0],NULL))
596 {
597 res = 1;
598 }
599 }
600 }
601 if (0 != res) {
602 pdksSysconf = dk4str_dup(rebuf, NULL);
603 if (NULL == pdksSysconf) {
604 errc = ERROR_MEMORY;
605 goto finished;
606 }
607 } else {
608 errc = ERROR_EXEC_TOO_LONG;
609 goto finished;
610 }
611 res = 0;
612 if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) {
613 if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) {
614 if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[1],NULL))
615 {
616 res = 1;
617 }
618 }
619 }
620 if (0 != res) {
621 pdksShare = dk4str_dup(rebuf, NULL);
622 UpdateWxsShare();
623 if (NULL == pdksShare) {
624 errc = ERROR_MEMORY;
625 goto finished;
626 }
627 } else {
628 errc = ERROR_EXEC_TOO_LONG;
629 goto finished;
630 }
631 } else {
632 pdksSysconf = dk4str_dup(rebuf, NULL);
633 pdksShare = dk4str_dup(rebuf, NULL);
634 UpdateWxsShare();
635 if ((NULL == pdksSysconf) || (NULL == pdksShare)) {
636 errc = ERROR_MEMORY;
637 goto finished;
638 }
639 }
640 }
641
642
643 /* Containers and iterators for string tables and preferences.
644 */
645 sStt = dk4sto_open(NULL);
646 if (NULL == sStt) {
647 errc = ERROR_MEMORY;
648 goto finished;
649 }
650 dk4sto_set_comp(sStt, dk4wxstt_compare, 0);
651 iStt = dk4sto_it_open(sStt, NULL);
652 if (NULL == iStt) {
653 errc = ERROR_MEMORY;
654 goto finished;
655 }
656 sPrSys = dk4sto_open(NULL);
657 if (NULL == sPrSys) {
658 errc = ERROR_MEMORY;
659 goto finished;
660 }
661 dk4sto_set_comp(sPrSys, dk4wxpref_compare, 0);
662 iPrSys = dk4sto_it_open(sPrSys, NULL);
663 if (NULL == iPrSys) {
664 errc = ERROR_MEMORY;
665 goto finished;
666 }
667 sPrUser = dk4sto_open(NULL);
668 if (NULL == sPrUser) {
669 errc = ERROR_MEMORY;
670 goto finished;
671 }
672 dk4sto_set_comp(sPrUser, dk4wxpref_compare, 0);
673 iPrUser = dk4sto_it_open(sPrUser, NULL);
674 if (NULL == iPrUser) {
675 errc = ERROR_MEMORY;
676 goto finished;
677 }
678
679
680 /* Read preference files.
681 */
682 for (pn = 0; pn <= DK4_FS_CONF_MAX; pn++) {
683 dk4wxpref_one_pass(
684 ((DK4_FS_CONF_SYS_MAX < pn) ? sPrUser : sPrSys),
685 ((DK4_FS_CONF_SYS_MAX < pn) ? iPrUser : iPrSys),
686 pdksApp,
687 pcdksGroup,
688 pdksLogname,
689 pdksHost,
690 pdksLanguage,
691 pdksRegion,
692 pdksHome,
693 pdksSysconf,
694 pdksShare,
695 iWxEncoding,
696 iDkEncoding,
697 (
698 (DK4_ENCODING_UTF8 == iDkEncoding)
699 ? DK4_FILE_ENCODING_UTF8 :
700 #if DK4_ON_WINDOWS
701 DK4_FILE_ENCODING_WIN1252
702 #else
703 DK4_FILE_ENCODING_PLAIN
704 #endif
705 ),
706 pn
707 );
708 }
709
710
711 /* Localized basic strings.
712 */
713 ppBasicStrings = InternalGetStringTable(
714 dk4wxah_kwnl_dk[0], (DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1)
715 );
716 if (NULL == ppBasicStrings) { ppBasicStrings = dk4wxah_basic_strings; }
717 nBasicStrings = Dk4WxApplicationHelper::StringTableSize(ppBasicStrings);
718
719
720 /* Finally mark success.
721 */
722 bActive = back = true;
723
724 /* Clean up if not successfully.
725 */
726 finished:
727 if (!(back)) {
728 switch (errc) {
729 case ERROR_MEMORY : {
730 msgbtext = dkwxah_msgb_texts[1];
731 msgbtitle = dkwxah_msgb_texts[0];
732 } break;
733 case ERROR_HOSTNAME : {
734 msgbtext = dkwxah_msgb_texts[2];
735 msgbtitle = dkwxah_msgb_texts[0];
736 } break;
737 case ERROR_LANG_REG_ENC : {
738 msgbtext = dkwxah_msgb_texts[3];
739 msgbtitle = dkwxah_msgb_texts[0];
740 } break;
741 case ERROR_LOGNAME : {
742 msgbtext = dkwxah_msgb_texts[4];
743 msgbtitle = dkwxah_msgb_texts[0];
744 } break;
745 case ERROR_HOMEDIR : {
746 msgbtext = dkwxah_msgb_texts[5];
747 msgbtitle = dkwxah_msgb_texts[0];
748 } break;
749 case ERROR_EXECUTABLE : {
750 msgbtext = dkwxah_msgb_texts[6];
751 msgbtitle = dkwxah_msgb_texts[0];
752 } break;
753 case ERROR_EXEC_TOO_LONG : {
754 msgbtext = dkwxah_msgb_texts[7];
755 msgbtitle = dkwxah_msgb_texts[0];
756 } break;
757 case ERROR_ARGUMENTS : {
758 msgbtext = dkwxah_msgb_texts[8];
759 msgbtitle = dkwxah_msgb_texts[0];
760 } break;
761 }
762 if ((NULL != msgbtext) && (NULL != msgbtitle)) {
763 wxMessageBox(
764 msgbtext, msgbtitle, (wxOK | wxCENTRE | wxICON_ERROR)
765 );
766 }
767 InternalCleanup();
768 }
769
770 return back;
771 }
772
773
774
775 void
InternalCleanup(void)776 Dk4WxApplicationHelper::InternalCleanup(void)
777 {
778 dk4_wx_string_table_t *wxsttptr;
779 dk4_wx_pref_t *pptr;
780
781 bActive = false; // Object can not longer be used.
782 ppBasicStrings = NULL;
783 pcwxsArgv0 = NULL;
784 pcwxsVendor = NULL;
785 pcdksGroup = NULL;
786 if (NULL != sPrUser) {
787 if (NULL != iPrUser) {
788 dk4sto_it_reset(iPrUser);
789 do {
790 pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrUser);
791 if (NULL != pptr) { dk4wxpref_close(pptr); }
792 } while (NULL != pptr);
793 dk4sto_it_close(iPrUser);
794 iPrUser = NULL;
795 }
796 dk4sto_close(sPrUser);
797 sPrUser = NULL;
798 }
799 if (NULL != sPrSys) {
800 if (NULL != iPrSys) {
801 dk4sto_it_reset(iPrSys);
802 do {
803 pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrSys);
804 if (NULL != pptr) { dk4wxpref_close(pptr); }
805 } while (NULL != pptr);
806 dk4sto_it_close(iPrSys);
807 iPrSys = NULL;
808 }
809 dk4sto_close(sPrSys);
810 sPrSys = NULL;
811 }
812 if (NULL != sStt) {
813 if (NULL != iStt) {
814 dk4sto_it_reset(iStt);
815 do {
816 wxsttptr = (dk4_wx_string_table_t *)dk4sto_it_next(iStt);
817 if (NULL != wxsttptr) { dk4wxstt_close(wxsttptr); }
818 } while (NULL != wxsttptr);
819 dk4sto_it_close(iStt);
820 iStt = NULL;
821 }
822 dk4sto_close(sStt);
823 sStt = NULL;
824 }
825 nBasicStrings = 0;
826 #if 0
827 /* Leave these integer variables as is.
828 */
829 iDkEncoding = DK4_ENCODING_PLAIN;
830 iWxEncoding = DK4_ENCODING_PLAIN;
831 iFiEncoding = DK4_FILE_ENCODING_PLAIN;
832 #endif
833 dk4mem_release(pdksRegion);
834 dk4mem_release(pdksLanguage);
835 dk4mem_release(pdksShare);
836 dk4mem_release(pwxsShare);
837 dk4mem_release(pdksSysconf);
838 dk4mem_release(pdksApp);
839 dk4mem_release(pdksHost);
840 dk4mem_release(pcdksArgv0);
841 dk4mem_release(pwxsApp);
842 dk4mem_release(pdksLogname);
843 dk4mem_release(pdksHome);
844
845 }
846
847
848
849 void
Cleanup(void)850 Dk4WxApplicationHelper::Cleanup(void)
851 {
852
853 {
854 wxCriticalSectionLocker lock(csProtect);
855 InternalCleanup();
856 }
857
858 }
859
860
861
862 /*
863 We do not need a critical section locker as the destructor
864 is invoked from the applications destructor. At this
865 we have no more top level windows or worker threads.
866 */
~Dk4WxApplicationHelper()867 Dk4WxApplicationHelper::~Dk4WxApplicationHelper()
868 {
869
870 InternalCleanup();
871
872 }
873
874
875
876 /* ************************************************************************ */
877 /* * * */
878 /* * Internal functions. * */
879 /* * These functions do not attempt synchronization. * */
880 /* * * */
881 /* ************************************************************************ */
882
883
884
885 bool
InternalStringToWx(wxChar * dptr,size_t dsz,const dkChar * sptr,dk4_er_t * erp)886 Dk4WxApplicationHelper::InternalStringToWx(
887 wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
888 )
889 {
890 int res = 0;
891 bool back = false;
892
893 res = dk4recwx_dkchar_to_wxchar(dptr,dsz,iWxEncoding,sptr,iDkEncoding,erp);
894 if (0 != res) { back = true; }
895
896 return back;
897 }
898
899
900
901 bool
InternalStringToDk(dkChar * dptr,size_t dsz,const wxChar * sptr,dk4_er_t * erp)902 Dk4WxApplicationHelper::InternalStringToDk(
903 dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
904 )
905 {
906 int res = 0;
907 bool back = false;
908
909 res = dk4recwx_wxchar_to_dkchar(dptr,dsz,iDkEncoding,sptr,iWxEncoding,erp);
910 if (0 != res) { back = true; }
911
912 return back;
913 }
914
915
916
917 bool
InternalFindDataFile(dkChar * fnb,size_t szfnb,dkChar const * sfn,int maxpass,bool aco)918 Dk4WxApplicationHelper::InternalFindDataFile(
919 dkChar *fnb,
920 size_t szfnb,
921 dkChar const *sfn,
922 int maxpass,
923 bool aco
924 )
925 {
926 int passno = 0;
927 int res = 0;
928 bool back = false;
929
930 for (passno = 0; ((passno <= maxpass) && (!(back))); passno++) {
931 res = dk4fs_data_one(
932 fnb, szfnb, sfn,
933 pdksShare, pdksHome, pdksApp, pcdksGroup,
934 pdksLanguage, pdksRegion,
935 passno, ((aco) ? 1 : 0), NULL
936 );
937 if (0 != res) { back = true; }
938 }
939 return back;
940 }
941
942
943
944
945 #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
946
947 bool
InternalFindDataFile(wxChar * fnb,size_t szfnb,dkChar const * sfn,int maxpass,bool aco)948 Dk4WxApplicationHelper::InternalFindDataFile(
949 wxChar *fnb,
950 size_t szfnb,
951 dkChar const *sfn,
952 int maxpass,
953 bool aco
954 )
955 {
956 dkChar buf[DK4_MAX_PATH];
957 size_t szbuf = DK4_SIZEOF(buf,dkChar);
958 bool back = false;
959
960 back = InternalFindDataFile(buf, szbuf, sfn, maxpass, aco);
961 if (back) {
962 back = InternalStringToWx(fnb, szfnb, buf, NULL);
963 }
964 return back;
965 }
966
967 #endif
968
969
970
971 const wxChar * const *
InternalGetStringTable(const dkChar * tableName,size_t tableSize)972 Dk4WxApplicationHelper::InternalGetStringTable(
973 const dkChar *tableName,
974 size_t tableSize
975 )
976 {
977 dkChar fnb[DK4_MAX_PATH];
978 dk4_er_t e1;
979 dk4_er_t e2;
980 const wxChar * const *back = NULL;
981 dk4_wx_string_table_t *tabptr = NULL;
982 dk4_stream_t *strm = NULL;
983 size_t szfnb = DK4_SIZEOF(fnb,dkChar);
984
985 tabptr = (dk4_wx_string_table_t *)dk4sto_it_find_like(iStt, tableName, 1);
986 if (NULL == tabptr) {
987 if (InternalFindDataFile(fnb, szfnb, tableName, DK4_FS_DATA_MAX_SYS, 1)) {
988 strm = dk4stream_open_file_reader(fnb, NULL);
989 if (NULL != strm) {
990 tabptr = dk4wxstt_open(tableName, tableSize, NULL);
991 if (NULL != tabptr) {
992 if (0 != dk4sto_add(sStt, tabptr, NULL)) {
993 dk4error_init(&e1);
994 dk4error_init(&e2);
995 if (!dk4wxstt_apply_stream(tabptr, strm, iWxEncoding, &e1, &e2)) {
996 dk4wxstt_shutdown(tabptr);
997 }
998 } else {
999 dk4wxstt_close(tabptr);
1000 tabptr = NULL;
1001 }
1002 }
1003 dk4stream_close(strm, NULL);
1004 }
1005 }
1006 }
1007 if (NULL != tabptr) {
1008 if (tabptr->nstrings >= tableSize) {
1009 back = (const wxChar * const *)(tabptr->strings);
1010 }
1011 }
1012 return back;
1013 }
1014
1015
1016
1017 bool
InternalSetMultiple(const wxChar * const * names,long * array,size_t sz)1018 Dk4WxApplicationHelper::InternalSetMultiple(
1019 const wxChar * const *names, long *array, size_t sz
1020 )
1021 {
1022 wxConfig conf(pwxsApp, pcwxsVendor);
1023 size_t i = 0;
1024 bool back = false;
1025
1026 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1027 back = true;
1028 for (i = 0; i < sz; i++) {
1029 if (!(conf.Write(names[i], array[i]))) {
1030 back = false;
1031 }
1032 }
1033 }
1034 return back;
1035 }
1036
1037
1038
1039 bool
InternalSetMultiple(const wxChar * const * names,int * array,size_t sz)1040 Dk4WxApplicationHelper::InternalSetMultiple(
1041 const wxChar * const *names, int *array, size_t sz
1042 )
1043 {
1044 wxConfig conf(pwxsApp, pcwxsVendor);
1045 size_t i = 0;
1046 bool back = false;
1047
1048 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1049 back = true;
1050 for (i = 0; i < sz; i++) {
1051 if (!(conf.Write(names[i], array[i]))) {
1052 back = false;
1053 }
1054 }
1055 }
1056 return back;
1057 }
1058
1059
1060
1061 bool
InternalSetMultiple(const wxChar * const * names,bool * array,size_t sz)1062 Dk4WxApplicationHelper::InternalSetMultiple(
1063 const wxChar * const *names, bool *array, size_t sz
1064 )
1065 {
1066 wxConfig conf(pwxsApp, pcwxsVendor);
1067 size_t i = 0;
1068 bool back = false;
1069
1070 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1071 back = true;
1072 for (i = 0; i < sz; i++) {
1073 if (!(conf.Write(names[i], array[i]))) {
1074 back = false;
1075 }
1076 }
1077 }
1078 return back;
1079 }
1080
1081
1082
1083 bool
InternalSetMultiple(const wxChar * const * names,double * array,size_t sz)1084 Dk4WxApplicationHelper::InternalSetMultiple(
1085 const wxChar * const *names, double *array, size_t sz
1086 )
1087 {
1088 wxConfig conf(pwxsApp, pcwxsVendor);
1089 size_t i = 0;
1090 bool back = false;
1091
1092 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1093 back = true;
1094 for (i = 0; i < sz; i++) {
1095 if (!(conf.Write(names[i], array[i]))) {
1096 back = false;
1097 }
1098 }
1099 }
1100 return back;
1101 }
1102
1103
1104
1105 bool
InternalSetMultiple(const wxChar * const * names,const wxChar * const * array,size_t sz)1106 Dk4WxApplicationHelper::InternalSetMultiple(
1107 const wxChar * const *names, const wxChar * const *array, size_t sz
1108 )
1109 {
1110 wxConfig conf(pwxsApp, pcwxsVendor);
1111 size_t i = 0;
1112 bool back = false;
1113
1114 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1115 back = true;
1116 for (i = 0; i < sz; i++) {
1117 if (!(conf.Write(names[i], array[i]))) {
1118 back = false;
1119 }
1120 }
1121 }
1122 return back;
1123 }
1124
1125
1126
1127 bool
InternalGetMultiple(const wxChar * const * names,long * array,size_t sz)1128 Dk4WxApplicationHelper::InternalGetMultiple(
1129 const wxChar * const *names, long *array, size_t sz
1130 )
1131 {
1132 wxConfig conf(pwxsApp, pcwxsVendor);
1133 dk4_wx_pref_t *pptr = NULL;
1134 #if DK4_SIZEOF_WXCHAR > 1
1135 const wchar_t *ep = NULL;
1136 #else
1137 const char *ep = NULL;
1138 #endif
1139 size_t i;
1140 long l;
1141 int res;
1142 bool back = false;
1143
1144 back = true;
1145 for (i = 0; i < sz; i++) {
1146 l = 0L;
1147 if (conf.Read(names[i], &l)) {
1148 array[i] = l;
1149 } else {
1150 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
1151 if (NULL == pptr) {
1152 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
1153 }
1154 if (NULL != pptr) {
1155 #if DK4_SIZEOF_WXCHAR > 1
1156 res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL);
1157 #else
1158 res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL);
1159 #endif
1160 if (0 != res) {
1161 array[i] = l;
1162 } else {
1163 back = false;
1164 }
1165 }
1166 }
1167 }
1168
1169 return back;
1170 }
1171
1172
1173
1174 bool
InternalGetMultiple(const wxChar * const * names,int * array,size_t sz)1175 Dk4WxApplicationHelper::InternalGetMultiple(
1176 const wxChar * const *names, int *array, size_t sz
1177 )
1178 {
1179 wxConfig conf(pwxsApp, pcwxsVendor);
1180 dk4_wx_pref_t *pptr = NULL;
1181 #if DK4_SIZEOF_WXCHAR > 1
1182 const wchar_t *ep = NULL;
1183 #else
1184 const char *ep = NULL;
1185 #endif
1186 size_t i;
1187 long l;
1188 int res;
1189 bool back = false;
1190
1191 back = true;
1192 for (i = 0; i < sz; i++) {
1193 l = 0L;
1194 if (conf.Read(names[i], &l)) {
1195 if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) {
1196 array[i] = (int)l;
1197 } else {
1198 back = false;
1199 }
1200 } else {
1201 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
1202 if (NULL == pptr) {
1203 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
1204 }
1205 if (NULL != pptr) {
1206 #if DK4_SIZEOF_WXCHAR > 1
1207 res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL);
1208 #else
1209 res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL);
1210 #endif
1211 if (0 != res) {
1212 if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) {
1213 array[i] = (int)l;
1214 } else {
1215 back = false;
1216 }
1217 } else {
1218 back = false;
1219 }
1220 }
1221 }
1222 }
1223
1224 return back;
1225 }
1226
1227
1228
1229 bool
InternalGetMultiple(const wxChar * const * names,bool * array,size_t sz)1230 Dk4WxApplicationHelper::InternalGetMultiple(
1231 const wxChar * const *names, bool *array, size_t sz
1232 )
1233 {
1234 wxConfig conf(pwxsApp, pcwxsVendor);
1235 dk4_wx_pref_t *pptr = NULL;
1236 size_t i;
1237 bool l;
1238 bool back = false;
1239
1240 back = true;
1241 for (i = 0; i < sz; i++) {
1242 l = 0L;
1243
1244 if (conf.Read(names[i], &l)) {
1245 array[i] = l;
1246 } else {
1247 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
1248 if (NULL == pptr) {
1249 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
1250 }
1251 if (NULL != pptr) {
1252
1253
1254 #if DK4_SIZEOF_WXCHAR > 1
1255
1256 if (0 != dk4strw_is_bool(pptr->value)) {
1257 if (0 != dk4strw_is_on(pptr->value)) {
1258 array[i] = true;
1259 } else {
1260 array[i] = false;
1261 }
1262 } else {
1263 back = false;
1264 }
1265 #else
1266
1267 if (0 != dk4str8_is_bool(pptr->value)) {
1268 if (0 != dk4str8_is_on(pptr->value)) {
1269 array[i] = true;
1270 } else {
1271 array[i] = false;
1272 }
1273 } else {
1274 back = false;
1275 }
1276 #endif
1277 } else {
1278 }
1279 }
1280 }
1281
1282 return back;
1283 }
1284
1285
1286
1287 bool
InternalGetMultiple(const wxChar * const * names,double * array,size_t sz)1288 Dk4WxApplicationHelper::InternalGetMultiple(
1289 const wxChar * const *names, double *array, size_t sz
1290 )
1291 {
1292 wxConfig conf(pwxsApp, pcwxsVendor);
1293 dk4_wx_pref_t *pptr = NULL;
1294 #if DK4_SIZEOF_WXCHAR > 1
1295 const wchar_t *ep = NULL;
1296 #else
1297 const char *ep = NULL;
1298 #endif
1299 #if DK4_HAVE_SETLOCALE
1300 char *oldloc = NULL;
1301 #endif
1302 double l;
1303 size_t i;
1304 int res;
1305 bool back = false;
1306
1307 back = true;
1308 for (i = 0; i < sz; i++) {
1309 l = 0.0;
1310 if (conf.Read(names[i], &l)) {
1311 array[i] = l;
1312 } else {
1313 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
1314 if (NULL == pptr) {
1315 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
1316 }
1317 if (NULL != pptr) {
1318 #if DK4_HAVE_SETLOCALE
1319 oldloc = setlocale(LC_NUMERIC, dk4wxah_kwnl_c8[0]);
1320 #endif
1321 #if DK4_SIZEOF_WXCHAR > 1
1322 res = dk4ma_input_wc_double(&l, pptr->value, &ep, 1, NULL);
1323 #else
1324 res = dk4ma_input_c8_double(&l, pptr->value, &ep, 1, NULL);
1325 #endif
1326 #if DK4_HAVE_SETLOCALE
1327 if (NULL != oldloc) { setlocale(LC_NUMERIC, oldloc); }
1328 #endif
1329 if (0 != res) {
1330 array[i] = l;
1331 } else {
1332 back = false;
1333 }
1334 }
1335 }
1336 }
1337
1338 return back;
1339 }
1340
1341
1342
1343 bool
InternalGetMultiple(const wxChar * const * names,wxChar ** array,size_t sz,bool ov)1344 Dk4WxApplicationHelper::InternalGetMultiple(
1345 const wxChar * const *names, wxChar **array, size_t sz, bool ov
1346 )
1347 {
1348 wxConfig conf(pwxsApp, pcwxsVendor);
1349 dk4_wx_pref_t *pptr = NULL;
1350 const wxChar *vptr = NULL;
1351 wxChar *nptr = NULL;
1352 size_t i;
1353 bool back = false;
1354
1355 back = true;
1356 for (i = 0; i < sz; i++) {
1357 if ((NULL == array[i]) || (ov)) {
1358 wxString value = wxEmptyString;
1359 if (conf.Read(names[i], &value)) {
1360 wxCStrData valuestrdata = value.c_str();
1361 vptr = (wxChar const *)valuestrdata;
1362 if (NULL != vptr) {
1363 nptr = dk4strx_dup(vptr, NULL);
1364 if (NULL != nptr) {
1365 if (NULL != array[i]) { dk4mem_free(array[i]); }
1366 array[i] = nptr;
1367 } else {
1368 back = false;
1369 }
1370 } else {
1371 back = false;
1372 }
1373 } else {
1374 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
1375 if (NULL == pptr) {
1376 pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
1377 }
1378 if (NULL != pptr) {
1379 nptr = dk4strx_dup(pptr->value, NULL);
1380 if (nptr) {
1381 if (NULL != array[i]) { dk4mem_free(array[i]); }
1382 array[i] = nptr;
1383 } else {
1384 back = false;
1385 }
1386 }
1387 }
1388 }
1389 }
1390
1391 return back;
1392 }
1393
1394
1395
1396 /* ************************************************************************ */
1397 /* * * */
1398 /* * Public interface. * */
1399 /* * The methods must * */
1400 /* * (a) synchronize access attempts from multiple threads and * */
1401 /* * (b) ensure the object is in a usable state. * */
1402 /* * * */
1403 /* ************************************************************************ */
1404
1405
1406
1407 bool
FindDataFile(dkChar * fnb,size_t szfnb,dkChar const * sfn,int maxpass,bool aco)1408 Dk4WxApplicationHelper::FindDataFile(
1409 dkChar *fnb,
1410 size_t szfnb,
1411 dkChar const *sfn,
1412 int maxpass,
1413 bool aco
1414 )
1415 {
1416 bool back = false;
1417
1418 if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
1419 wxCriticalSectionLocker lock(csProtect);
1420 if (bActive) {
1421 back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco);
1422 }
1423 }
1424 return back;
1425 }
1426
1427
1428
1429
1430 #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
1431
1432 bool
FindDataFile(wxChar * fnb,size_t szfnb,dkChar const * sfn,int maxpass,bool aco)1433 Dk4WxApplicationHelper::FindDataFile(
1434 wxChar *fnb,
1435 size_t szfnb,
1436 dkChar const *sfn,
1437 int maxpass,
1438 bool aco
1439 )
1440 {
1441 bool back = false;
1442
1443 if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
1444 wxCriticalSectionLocker lock(csProtect);
1445 if (bActive) {
1446 back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco);
1447 }
1448 }
1449 return back;
1450 }
1451
1452 #endif
1453
1454
1455
1456 int
GetDkEncoding(void)1457 Dk4WxApplicationHelper::GetDkEncoding(void)
1458 {
1459 int back = DK4_ENCODING_PLAIN;
1460
1461 #if DK4_ON_WINDOWS
1462 back = DK4_ENCODING_WIN1252;
1463 #endif
1464 {
1465 wxCriticalSectionLocker lock(csProtect);
1466 back = iDkEncoding;
1467 }
1468 return back;
1469 }
1470
1471
1472
1473 int
GetWxEncoding(void)1474 Dk4WxApplicationHelper::GetWxEncoding(void)
1475 {
1476 int back = DK4_ENCODING_PLAIN;
1477
1478 #if DK4_ON_WINDOWS
1479 back = DK4_ENCODING_WIN1252;
1480 #endif
1481 {
1482 wxCriticalSectionLocker lock(csProtect);
1483 back = iWxEncoding;
1484 }
1485 return back;
1486 }
1487
1488
1489
1490 int
GetFiEncoding(void)1491 Dk4WxApplicationHelper::GetFiEncoding(void)
1492 {
1493 int back = DK4_FILE_ENCODING_PLAIN;
1494
1495 #if DK4_ON_WINDOWS
1496 back = DK4_FILE_ENCODING_WIN1252;
1497 #endif
1498 {
1499 wxCriticalSectionLocker lock(csProtect);
1500 back = iFiEncoding;
1501 }
1502 return back;
1503 }
1504
1505
1506
1507 const wxChar * const *
GetStringTable(const dkChar * tableName,const wxChar * const * defaultTable)1508 Dk4WxApplicationHelper::GetStringTable(
1509 const dkChar *tableName,
1510 const wxChar * const *defaultTable
1511 )
1512 {
1513 const wxChar * const *back = NULL;
1514 size_t sz = 0;
1515
1516 if ((NULL != tableName) && (NULL != defaultTable)) {
1517 sz = Dk4WxApplicationHelper::StringTableSize(defaultTable);
1518 if (0 < sz) {
1519 wxCriticalSectionLocker lock(csProtect);
1520 if (bActive) {
1521 back = InternalGetStringTable(tableName, sz);
1522 }
1523 }
1524 }
1525 if (NULL == back) { back = defaultTable; }
1526
1527 return back;
1528 }
1529
1530
1531
1532 const wxChar *
GetBasicString(size_t numstr)1533 Dk4WxApplicationHelper::GetBasicString(
1534 size_t numstr
1535 )
1536 {
1537 const wxChar *back = NULL;
1538
1539 {
1540 wxCriticalSectionLocker lock(csProtect);
1541 if (bActive) {
1542 if ((NULL != ppBasicStrings) && (0 < nBasicStrings)) {
1543 if (numstr < nBasicStrings) {
1544 back = ppBasicStrings[numstr];
1545 }
1546 }
1547 }
1548 }
1549 if (NULL == back) {
1550 if (numstr < (DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1)) {
1551 back = dk4wxah_basic_strings[numstr];
1552 } else {
1553 back = dk4wxah_empty_string;
1554 }
1555 }
1556 return back;
1557 }
1558
1559
1560
1561 const wxChar * const *
GetBasicStrings(size_t * pNumBasicStrings)1562 Dk4WxApplicationHelper::GetBasicStrings(
1563 size_t *pNumBasicStrings
1564 )
1565 {
1566 const wxChar * const *back = NULL;
1567
1568 {
1569 wxCriticalSectionLocker lock(csProtect);
1570 if (bActive) {
1571 back = ppBasicStrings;
1572 if (NULL != pNumBasicStrings) { *pNumBasicStrings = nBasicStrings; }
1573 }
1574 }
1575 if (NULL == back) {
1576 back = dk4wxah_basic_strings;
1577 if (NULL != pNumBasicStrings) {
1578 *pNumBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1;
1579 }
1580 }
1581 return back;
1582 }
1583
1584
1585
1586 bool
StringToWx(wxChar * dptr,size_t dsz,const dkChar * sptr,dk4_er_t * erp)1587 Dk4WxApplicationHelper::StringToWx(
1588 wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
1589 )
1590 {
1591 int res = 0;
1592 int wxe = DK4_ENCODING_PLAIN;
1593 int dke = DK4_ENCODING_PLAIN;
1594 bool back = false;
1595
1596 #if DK4_ON_WINDOWS
1597 wxe = dke = DK4_ENCODING_WIN1252;
1598 #endif
1599 if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
1600 {
1601 wxCriticalSectionLocker lock(csProtect);
1602 wxe = iWxEncoding;
1603 dke = iDkEncoding;
1604 }
1605 res = dk4recwx_dkchar_to_wxchar(dptr, dsz, wxe, sptr, dke, erp);
1606 if (0 != res) { back = true; }
1607 }
1608 return back;
1609 }
1610
1611
1612
1613 bool
StringToDk(dkChar * dptr,size_t dsz,const wxChar * sptr,dk4_er_t * erp)1614 Dk4WxApplicationHelper::StringToDk(
1615 dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
1616 )
1617 {
1618 int res = 0;
1619 int wxe = DK4_ENCODING_PLAIN;
1620 int dke = DK4_ENCODING_PLAIN;
1621 bool back = false;
1622
1623 #if DK4_ON_WINDOWS
1624 wxe = dke = DK4_ENCODING_WIN1252;
1625 #endif
1626 if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
1627 {
1628 wxCriticalSectionLocker lock(csProtect);
1629 wxe = iWxEncoding;
1630 dke = iDkEncoding;
1631 }
1632 res = dk4recwx_wxchar_to_dkchar(dptr, dsz, dke, sptr, wxe, erp);
1633 if (0 != res) { back = true; }
1634 }
1635 return back;
1636 }
1637
1638
1639
1640 bool
StringToChar(char * dptr,size_t dsz,const wxChar * sptr,dk4_er_t * erp)1641 Dk4WxApplicationHelper::StringToChar(
1642 char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
1643 )
1644 {
1645 int res = 0;
1646 int wxe = DK4_ENCODING_PLAIN;
1647 int dke = DK4_ENCODING_PLAIN;
1648 bool back = false;
1649 #if DK4_ON_WINDOWS
1650 wxe = dke = DK4_ENCODING_WIN1252;
1651 #endif
1652 if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
1653 {
1654 wxCriticalSectionLocker lock(csProtect);
1655 wxe = iWxEncoding;
1656 dke = iDkEncoding;
1657 }
1658 if (DK4_ENCODING_UTF8 != dke) {
1659 if (DK4_ENCODING_WIN1252 != dke) {
1660 dke = DK4_ENCODING_PLAIN;
1661 }
1662 }
1663 res = dk4recwx_wxchar_to_char(dptr, dsz, dke, sptr, wxe, erp);
1664 if (0 != res) { back = true; }
1665 }
1666 return back;
1667 }
1668
1669
1670
1671 bool
SetMultiple(const wxChar * const * names,long * array,size_t sz)1672 Dk4WxApplicationHelper::SetMultiple(
1673 const wxChar * const *names, long *array, size_t sz
1674 )
1675 {
1676 bool back = false;
1677
1678 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1679 wxCriticalSectionLocker lock(csProtect);
1680 if (bActive) {
1681 back = InternalSetMultiple(names, array, sz);
1682 } else {
1683 /* Object not active */
1684 }
1685 }
1686 return back;
1687 }
1688
1689
1690
1691 bool
SetMultiple(const wxChar * const * names,int * array,size_t sz)1692 Dk4WxApplicationHelper::SetMultiple(
1693 const wxChar * const *names, int *array, size_t sz
1694 )
1695 {
1696 bool back = false;
1697
1698 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1699 wxCriticalSectionLocker lock(csProtect);
1700 if (bActive) {
1701 back = InternalSetMultiple(names, array, sz);
1702 } else {
1703 /* Object not active */
1704 }
1705 }
1706 return back;
1707 }
1708
1709
1710
1711 bool
SetMultiple(const wxChar * const * names,bool * array,size_t sz)1712 Dk4WxApplicationHelper::SetMultiple(
1713 const wxChar * const *names, bool *array, size_t sz
1714 )
1715 {
1716 bool back = false;
1717
1718 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1719 wxCriticalSectionLocker lock(csProtect);
1720 if (bActive) {
1721 back = InternalSetMultiple(names, array, sz);
1722 } else {
1723 /* Object not active */
1724 }
1725 }
1726 return back;
1727 }
1728
1729
1730
1731 bool
SetMultiple(const wxChar * const * names,double * array,size_t sz)1732 Dk4WxApplicationHelper::SetMultiple(
1733 const wxChar * const *names, double *array, size_t sz
1734 )
1735 {
1736 bool back = false;
1737
1738 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1739 wxCriticalSectionLocker lock(csProtect);
1740 if (bActive) {
1741 back = InternalSetMultiple(names, array, sz);
1742 } else {
1743 /* Object not active */
1744 }
1745 }
1746 return back;
1747 }
1748
1749
1750
1751 bool
SetMultiple(const wxChar * const * names,const wxChar * const * array,size_t sz)1752 Dk4WxApplicationHelper::SetMultiple(
1753 const wxChar * const *names, const wxChar * const *array, size_t sz
1754 )
1755 {
1756 bool back = false;
1757
1758 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1759 wxCriticalSectionLocker lock(csProtect);
1760 if (bActive) {
1761 back = InternalSetMultiple(names, array, sz);
1762 } else {
1763 /* Object not active */
1764 }
1765 }
1766 return back;
1767 }
1768
1769
1770
1771 bool
GetMultiple(const wxChar * const * names,long * array,size_t sz)1772 Dk4WxApplicationHelper::GetMultiple(
1773 const wxChar * const *names, long *array, size_t sz
1774 )
1775 {
1776 bool back = false;
1777
1778 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1779 wxCriticalSectionLocker lock(csProtect);
1780 if (bActive) {
1781 back = InternalGetMultiple(names, array, sz);
1782 } else {
1783 /* Object not active */
1784 }
1785 }
1786 return back;
1787 }
1788
1789
1790
1791 bool
GetMultiple(const wxChar * const * names,int * array,size_t sz)1792 Dk4WxApplicationHelper::GetMultiple(
1793 const wxChar * const *names, int *array, size_t sz
1794 )
1795 {
1796 bool back = false;
1797
1798 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1799 wxCriticalSectionLocker lock(csProtect);
1800 if (bActive) {
1801 back = InternalGetMultiple(names, array, sz);
1802 } else {
1803 /* Object not active */
1804 }
1805 }
1806 return back;
1807 }
1808
1809
1810
1811 bool
GetMultiple(const wxChar * const * names,bool * array,size_t sz)1812 Dk4WxApplicationHelper::GetMultiple(
1813 const wxChar * const *names, bool *array, size_t sz
1814 )
1815 {
1816 bool back = false;
1817
1818 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1819 wxCriticalSectionLocker lock(csProtect);
1820 if (bActive) {
1821 back = InternalGetMultiple(names, array, sz);
1822 } else {
1823 /* Object not active */
1824 }
1825 }
1826 return back;
1827 }
1828
1829
1830
1831 bool
GetMultiple(const wxChar * const * names,double * array,size_t sz)1832 Dk4WxApplicationHelper::GetMultiple(
1833 const wxChar * const *names, double *array, size_t sz
1834 )
1835 {
1836 bool back = false;
1837
1838 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1839 wxCriticalSectionLocker lock(csProtect);
1840 if (bActive) {
1841 back = InternalGetMultiple(names, array, sz);
1842 } else {
1843 /* Object not active */
1844 }
1845 }
1846 return back;
1847 }
1848
1849
1850
1851 bool
GetMultiple(const wxChar * const * names,wxChar ** array,size_t sz,bool ov)1852 Dk4WxApplicationHelper::GetMultiple(
1853 const wxChar * const *names, wxChar **array, size_t sz, bool ov
1854 )
1855 {
1856 bool back = false;
1857
1858 if ((NULL != names) && (NULL != array) && (0 < sz)) {
1859 wxCriticalSectionLocker lock(csProtect);
1860 if (bActive) {
1861 back = InternalGetMultiple(names, array, sz, ov);
1862 } else {
1863 /* Object not active */
1864 }
1865 }
1866 return back;
1867 }
1868
1869
1870
1871 bool
SetString(const wxString & key,const wxString & value)1872 Dk4WxApplicationHelper::SetString(const wxString & key, const wxString & value)
1873 {
1874 bool back = false;
1875
1876 {
1877 wxCriticalSectionLocker lock(csProtect);
1878 if (bActive) {
1879 wxConfig conf(pwxsApp, pcwxsVendor);
1880 back = conf.Write(key, value);
1881 }
1882 }
1883
1884 return back;
1885 }
1886
1887
1888
1889 bool
GetString(const wxString & key,wxString * pvalue)1890 Dk4WxApplicationHelper::GetString(const wxString & key, wxString *pvalue)
1891 {
1892 bool back = false;
1893
1894 if (NULL != pvalue) {
1895 wxCriticalSectionLocker lock(csProtect);
1896 if (bActive) {
1897 wxConfig conf(pwxsApp, pcwxsVendor);
1898 back = conf.Read(key, pvalue);
1899 }
1900 }
1901
1902 return back;
1903 }
1904
1905
1906
1907 /* ************************************************************************ */
1908 /* * * */
1909 /* * Static class functions. * */
1910 /* * * */
1911 /* ************************************************************************ */
1912
1913
1914
1915 void
CorrectPosition(int & x,int & y,int & w,int & h,bool cn)1916 Dk4WxApplicationHelper::CorrectPosition(
1917 int & x, int & y, int & w, int & h, bool cn
1918 )
1919 {
1920 wxSize scsz;
1921
1922 scsz = wxGetDisplaySize();
1923 if (cn) {
1924 /*
1925 Negative coordinates mean x and y not defined, center window.
1926 */
1927 if (0 > x) { x = (scsz.x - w) / 2; }
1928 if (0 > y) { y = (scsz.y - h) / 2; }
1929 }
1930 if (scsz.x < (x + w)) { x = scsz.x - w; }
1931 if (scsz.y < (y + h)) { y = scsz.y - h; }
1932 if (0 > x) { x = 0; }
1933 if (0 > y) { y = 0; }
1934
1935 }
1936
1937
1938
1939 void
CorrectPosition(wxWindow & wnd,bool cn)1940 Dk4WxApplicationHelper::CorrectPosition(
1941 wxWindow & wnd, bool cn
1942 )
1943 {
1944 int x, y, w, h;
1945
1946 wnd.GetPosition(&x, &y);
1947 wnd.GetSize(&w, &h);
1948 Dk4WxApplicationHelper::CorrectPosition(x, y, w, h, cn);
1949 wnd.SetSize(x, y, w, h);
1950
1951 }
1952
1953
1954
1955 void
ChooseChildPosition(const wxWindow & p,wxWindow & c,bool beside)1956 Dk4WxApplicationHelper::ChooseChildPosition(
1957 const wxWindow & p, wxWindow & c, bool beside
1958 )
1959 {
1960 wxSize scsz = wxGetDisplaySize();
1961 int px = 0;
1962 int py = 0;
1963 int pw = 0;
1964 int ph = 0;
1965 int cx = 0;
1966 int cy = 0;
1967 int cw = 0;
1968 int ch = 0;
1969 bool done = false;
1970 bool findy = false;
1971
1972 #if 0
1973 p.GetPosition(&px, &py);
1974 p.GetSize(&pw, &ph);
1975 #else
1976 wxRect re = p.GetScreenRect();
1977 px = re.GetX();
1978 py = re.GetY();
1979 pw = re.GetWidth();
1980 ph = re.GetHeight();
1981
1982 #endif
1983 c.GetSize(&cw, &ch);
1984
1985 if (beside) {
1986 /* Attempt right side */
1987 if (scsz.x > px + pw + cw) {
1988 cx = px + pw;
1989 done = true;
1990 findy = true;
1991 }
1992 /* Attempt bottom side */
1993 if (!done) {
1994 if (scsz.y > py + ph + ch) {
1995 cy = py + ph;
1996 done = true;
1997 }
1998 }
1999 /* Attempt left side */
2000 if (!done) {
2001 if (px > cw) {
2002 cx = px - cw;
2003 done = true;
2004 findy = true;
2005 }
2006 }
2007 /* Attempt top side */
2008 if (!done) {
2009 if (py < ch) {
2010 cy = py - ch;
2011 done = true;
2012 }
2013 }
2014 if (done) {
2015 if (findy) {
2016 if (scsz.y > (py + ch)) {
2017 cy = py;
2018 } else {
2019 if (0 <= (py + ph - ch)) {
2020 cy = py + ph - ch;
2021 } else {
2022 cy = py + (ph - ch) / 2;
2023 if (scsz.y <= (cy + ch)) {
2024 cy = scsz.y - ch - 1;
2025 }
2026 if (0 > cy) {
2027 cy = 0;
2028 }
2029 }
2030 }
2031 } else {
2032 if (scsz.x > (px + cw)) {
2033 cx = px;
2034 } else {
2035 if (0 <= (px + pw - cw)) {
2036 cx = px + pw - cw;
2037 } else {
2038 cx = px + (pw - cw) / 2;
2039 if (scsz.x <= (cx + cw)) {
2040 cx = scsz.x - cw - 1;
2041 }
2042 if (0 > cx) {
2043 cx = 0;
2044 }
2045 }
2046 }
2047 }
2048 c.SetSize(cx, cy, cw, ch);
2049 }
2050 }
2051 if (!done) {
2052 cx = px + (pw - cw) / 2;
2053 cy = py + (ph - ch) / 2;
2054
2055 Dk4WxApplicationHelper::CorrectPosition(cx, cy, cw, ch, false);
2056
2057 c.SetSize(cx, cy, cw, ch);
2058 }
2059
2060 }
2061
2062
2063
2064 size_t
StringTableSize(const wxChar * const * sttptr)2065 Dk4WxApplicationHelper::StringTableSize(const wxChar * const *sttptr)
2066 {
2067 size_t back = 0;
2068
2069 if (NULL != sttptr) {
2070 while (NULL != *(sttptr++)) { back++; }
2071 }
2072 return back;
2073 }
2074
2075
2076
2077 void
ReleaseWxcharStringArray(wxChar ** array,size_t sz,bool ea)2078 Dk4WxApplicationHelper::ReleaseWxcharStringArray(
2079 wxChar **array, size_t sz, bool ea
2080 )
2081 {
2082 wxChar **ap;
2083
2084 if ((NULL != array) && (0 < sz)) {
2085 ap = array;
2086 while (0 < sz--) {
2087 dk4mem_release(*array);
2088 array++;
2089 }
2090 if (ea) { dk4mem_free(ap); }
2091 }
2092
2093 }
2094
2095
2096
2097 const
2098 dkChar *
GetDkArgv0(void)2099 Dk4WxApplicationHelper::GetDkArgv0(void)
2100 {
2101 return ((const dkChar *)pcdksArgv0);
2102 }
2103
2104
2105
2106 const
2107 dkChar *
GetDkGroupName(void)2108 Dk4WxApplicationHelper::GetDkGroupName(void)
2109 {
2110 return(pcdksGroup);
2111 }
2112
2113
2114
2115 void
UpdateWxsShare(void)2116 Dk4WxApplicationHelper::UpdateWxsShare(void)
2117 {
2118 wxChar buf[DK4_MAX_PATH];
2119 wxChar *np;
2120 bool res;
2121 if (NULL != pdksShare) {
2122 res = InternalStringToWx(buf, DK4_SIZEOF(buf,wxChar), pdksShare, NULL);
2123 if (res) {
2124 np = dk4strx_dup(buf, NULL);
2125 if (NULL != np) {
2126 dk4mem_release(pwxsShare);
2127 pwxsShare = np;
2128 }
2129 }
2130 }
2131 }
2132
2133
2134
2135 const
2136 wxChar *
GetWxsShare(void) const2137 Dk4WxApplicationHelper::GetWxsShare(void) const
2138 {
2139 return ((wxChar const *)pwxsShare);
2140 }
2141
2142
2143
2144 bool
InternalFindHelpFile(dkChar * fnb,size_t szfnb,dkChar const * sfn)2145 Dk4WxApplicationHelper::InternalFindHelpFile(
2146 dkChar *fnb,
2147 size_t szfnb,
2148 dkChar const *sfn
2149 )
2150 {
2151 int passno = 0;
2152 int res = 0;
2153 bool back = false;
2154
2155 for (passno = 0; ((passno <= DK4_FS_DOC_MAX) && (!(back))); passno++) {
2156 res = dk4fs_doc_one(
2157 fnb, szfnb, sfn, pdksShare, pdksApp, pcdksGroup,
2158 pdksLanguage, pdksRegion, passno, NULL
2159 );
2160 if (0 != res) {
2161 back = true;
2162 }
2163 }
2164
2165 return back;
2166 }
2167
2168
2169 #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
2170
2171 bool
InternalFindHelpFile(wxChar * fnb,size_t szfnb,dkChar const * sfn)2172 Dk4WxApplicationHelper::InternalFindHelpFile(
2173 wxChar *fnb,
2174 size_t szfnb,
2175 dkChar const *sfn
2176 )
2177 {
2178 dkChar buf[DK4_MAX_PATH];
2179 size_t szbuf = DK4_SIZEOF(buf,dkChar);
2180 bool back = false;
2181
2182 back = InternalFindHelpFile(buf, szbuf, sfn);
2183 if (back) {
2184 back = InternalStringToWx(fnb, szfnb, buf, NULL);
2185 }
2186
2187 return back;
2188 }
2189
2190 #endif
2191
2192 bool
FindHelpFile(dkChar * fnb,size_t szfnb,dkChar const * sfn)2193 Dk4WxApplicationHelper::FindHelpFile(
2194 dkChar *fnb,
2195 size_t szfnb,
2196 dkChar const *sfn
2197 )
2198 {
2199 bool back = false;
2200 if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
2201 wxCriticalSectionLocker lock(csProtect);
2202 if (bActive) {
2203 back = InternalFindHelpFile(fnb, szfnb, sfn);
2204 }
2205 }
2206 return back;
2207 }
2208
2209 #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
2210
2211 bool
FindHelpFile(wxChar * fnb,size_t szfnb,dkChar const * sfn)2212 Dk4WxApplicationHelper::FindHelpFile(
2213 wxChar *fnb,
2214 size_t szfnb,
2215 dkChar const *sfn
2216 )
2217 {
2218 bool back = false;
2219 if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
2220 wxCriticalSectionLocker lock(csProtect);
2221 if (bActive) {
2222 back = InternalFindHelpFile(fnb, szfnb, sfn);
2223 }
2224 }
2225 return back;
2226 }
2227
2228 #endif
2229
2230
2231 /* vim: set ai sw=4 ts=4 : */
2232