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