%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% header /** @file Dk4WxApplicationHelper.h The Dk4WxApplicationHelper class. */ #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4TYPES_H_INCLUDED #include "dk4types.h" #endif #ifndef DK4CONST_H_INCLUDED #include "dk4const.h" #endif #ifndef DK4ERROR_H_INCLUDED #include "dk4error.h" #endif #ifndef DK4STO_H_INCLUDED #include "dk4sto.h" #endif #ifndef DK4WXCS_H_INCLUDED #include "dk4wxcs.h" #endif #ifndef DK4FSH_H_INCLUDED #include "dk4fs.h" #endif #ifndef WX_WXPREC_H_INCLUDED #include "wx/wxprec.h" #define WX_WXPREC_H_INCLUDED 1 #endif #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #ifndef WX_WX_H_INCLUDED #include "wx/wx.h" #define WX_WX_H_INCLUDED 1 #endif #endif #ifndef WX_CONFIG_H_INCLUDED #include #define WX_CONFIG_H_INCLUDED 1 #endif #ifndef WX_FILENAME_H_INCLUDED #include #define WX_FILENAME_H_INCLUDED 1 #endif #ifndef WX_THREAD_H_INCLUDED #include #define WX_THREAD_H_INCLUDED 1 #endif #ifndef DK4WXSTT_H_INCLUDED #include "dk4wxstt.h" #endif /** Application helper. Each application should have one application helper object as the member of the wxApp-derived application class. In the applications OnInit() method call the Initialize() method. */ class Dk4WxApplicationHelper { protected: /** Synchronization for access from multiple threads. */ wxCriticalSection csProtect; /** The basic strings for GUIs. */ const wxChar * const *ppBasicStrings; /** Software vendor name. */ const wxChar *pcwxsVendor; /** First command line argument. */ const wxChar *pcwxsArgv0; /** Application group name. */ const dkChar *pcdksGroup; /** Application name. */ wxChar *pwxsApp; /** Host name. */ dkChar *pdksHost; /** Users login name. */ dkChar *pdksLogname; /** Home directory. */ dkChar *pdksHome; /** Application name. */ dkChar *pdksApp; /** System configuration directory. */ dkChar *pdksSysconf; /** Data directory. */ dkChar *pdksShare; /** Users language. */ dkChar *pdksLanguage; /** Users region. */ dkChar *pdksRegion; /** String tables storage. */ dk4_sto_t *sStt; /** String tables storage iterator. */ dk4_sto_it_t *iStt; /** System preferences storage. */ dk4_sto_t *sPrSys; /** System preferences storage iterator. */ dk4_sto_it_t *iPrSys; /** User preferences storage. */ dk4_sto_t *sPrUser; /** User preferences storage iterator. */ dk4_sto_it_t *iPrUser; /** Number of strings in the ppBasicStrings array. */ size_t nBasicStrings; /** Encoding for dkChar strings. */ int iDkEncoding; /** Encoding for wxChar strings. */ int iWxEncoding; /** Expected encoding for file input. */ int iFiEncoding; /** Flag: Controller is set up and can be used. */ bool bActive; protected: /** Clean up internal data structures. */ void InternalCleanup(void); /** Search for data file. @param fnb File name buffer. @param szfnb Buffer size (number of dkChar). @param sfn Short file name. @param maxpass Maximum pass number for search. @param aco Flag: Allow compressed versions. @return True if the file was found (name in fnb), false otherwise. */ bool InternalFindDataFile( dkChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass, bool aco ); #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE /** Search for data file. @param fnb File name buffer. @param szfnb Buffer size (number of wxChar). @param sfn Short file name. @param maxpass Maximum pass number for search. @param aco Flag: Allow compressed versions. @return True if the file was found (name in fnb), false otherwise. */ bool InternalFindDataFile( wxChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass, bool aco ); #endif /** Convert dkChar string to wxChar string. @param dptr Result buffer. @param dsz Buffer size (number of wxChar). @param sptr Source string. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if dptr or sptr is NULL or dsz is 0, - DK4_E_BUFFER_TOO_SMALL
if dptr is too small, - DK4_E_SYNTAX
if a non-recodable character was found. */ bool InternalStringToWx( wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp ); /** Convert wxChar string to dkChar string. @param dptr Result buffer. @param dsz Result buffer size (number of dkChar). @param sptr Source string. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if dptr or sptr is NULL or dsz is 0, - DK4_E_BUFFER_TOO_SMALL
if dptr is too small, - DK4_E_SYNTAX
if a non-recodable character was found. */ bool InternalStringToDk( dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp ); /** Retrieve a string table. @param tableName Short string table file name. @param tableSize Minimum number of elements required in table. @return Pointer to string table found or NULL. */ const wxChar * const * InternalGetStringTable( const dkChar *tableName, size_t tableSize ); /** Save multiple long values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalSetMultiple(const wxChar * const *names, long *array, size_t sz); /** Save multiple int values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalSetMultiple(const wxChar * const *names, int *array, size_t sz); /** Save multiple bool values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalSetMultiple(const wxChar * const *names, bool *array, size_t sz); /** Save multiple double values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalSetMultiple(const wxChar * const *names, double *array, size_t sz); /** Save multiple string values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalSetMultiple( const wxChar * const *names, const wxChar * const *array, size_t sz ); /** Retrieve multiple long values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalGetMultiple(const wxChar * const *names, long *array, size_t sz); /** Retrieve multiple int values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalGetMultiple(const wxChar * const *names, int *array, size_t sz); /** Retrieve multiple bool values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalGetMultiple(const wxChar * const *names, bool *array, size_t sz); /** Retrieve multiple double values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool InternalGetMultiple(const wxChar * const *names, double *array, size_t sz); /** Retrieve multiple string values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @param ov Flag: Overwrite existing strings. Memory for already existing strings is freed, memory for the new found string is allocated if the flag is set. Existing strings are left untouched if the flag is not set. @return True on success, false on error. */ bool InternalGetMultiple( const wxChar * const *names, wxChar **array, size_t sz, bool ov = true ); public: /** Default constructor. */ Dk4WxApplicationHelper(); /** Destructor. */ ~Dk4WxApplicationHelper(); /** Initialize before used, called from the applications OnInit() method. If this method returns false, the OnInit() method should return false too. @param argv0 First command line argument. @param vendorName Software vendor name. @param groupName Application group name. @param erp Error report, may be NULL. @return True if initialized successfully, false otherwise. Error codes: - DK4_E_NOT_FOUND
if the system function(s) failed to find the name of the file currently executed or the users home directory or the users home directory or login name, - DK4_E_SYSTEM
if the function failed to find the current working directory, - DK4_E_SYNTAX
if there are string conversion problems, - DK4_E_BUFFER_TOO_SMALL
if the internal buffer is too small to hold the file name of the executed file, the users home directory, login name or a conversion buffer is too small, - DK4_E_SYNTAX
if a Windows registry entry differs from the expected type. - DK4_E_MATH_OVERFLOW
if a numeric overflow occured in a memory allocation size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if a memory allocation attempt failed due to insufficient memory. */ bool Initialize( const wxChar *argv0, const wxChar *vendorName, const dkChar *groupName, dk4_er_t *erp = NULL ); /** Clean up internal data structures. You should call this from the applications OnExit() method. */ void Cleanup(void); /** Search for data file. @param fnb File name buffer. @param szfnb Buffer size (number of dkChar). @param sfn Short file name. @param maxpass Maximum pass number for search. @param aco Flag: Allow compressed versions. @return True if the file was found (name in fnb), false otherwise. */ bool FindDataFile( dkChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass = DK4_FS_DATA_MAX_SYS, bool aco = false ); #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE /** Search for data file. @param fnb File name buffer. @param szfnb Buffer size (number of wxChar). @param sfn Short file name. @param maxpass Maximum pass number for search. @param aco Flag: Allow compressed versions. @return True if the file was found (name in fnb), false otherwise. */ bool FindDataFile( wxChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass = DK4_FS_DATA_MAX_SYS, bool aco = false ); #endif /** Retrieve dkChar encoding. @return Encoding. */ int GetDkEncoding(void); /** Retrieve wxChar encoding. @return Encoding. */ int GetWxEncoding(void); /** Retrieve expected input encoding when reading files. @return Encoding. */ int GetFiEncoding(void); /** Retrieve a string table. @param tableName Short string table file name. @param defaultTable Default strings to use if not found. @return Pointer to string table found or defaultTable. */ const wxChar * const * GetStringTable( const dkChar *tableName, const wxChar * const *defaultTable ); /** Retrieve one of the basic strings. @param numstr Index of string in basic strings array. @return String pointer on success, NULL on error (index out of range). */ const wxChar * GetBasicString(size_t numstr); /** Retrieve entire basic strings array. @param pNumBasicStrings Address of variable to store the array length, may be NULL. @return Pointer to array of basic strings. */ const wxChar * const * GetBasicStrings(size_t *pNumBasicStrings = NULL); /** Convert dkChar string to wxChar string. @param dptr Result buffer. @param dsz Buffer size (number of wxChar). @param sptr Source string. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if dptr or sptr is NULL or dsz is 0, - DK4_E_BUFFER_TOO_SMALL
if dptr is too small, - DK4_E_SYNTAX
if a non-recodable character was found. */ bool StringToWx( wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp = NULL ); /** Convert wxChar string to dkChar string. @param dptr Result buffer. @param dsz Result buffer size (number of dkChar). @param sptr Source string. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if dptr or sptr is NULL or dsz is 0, - DK4_E_BUFFER_TOO_SMALL
if dptr is too small, - DK4_E_SYNTAX
if a non-recodable character was found. */ bool StringToDk( dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp = NULL ); /** Convert wxChar string to char string. @param dptr Result buffer. @param dsz Result buffer size (number of char). @param sptr Source string. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if dptr or sptr is NULL or dsz is 0, - DK4_E_BUFFER_TOO_SMALL
if dptr is too small, - DK4_E_SYNTAX
if a non-recodable character was found. */ bool StringToChar( char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp = NULL ); /** Save multiple long values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool SetMultiple(const wxChar * const *names, long *array, size_t sz); /** Save multiple int values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool SetMultiple(const wxChar * const *names, int *array, size_t sz); /** Save multiple bool values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool SetMultiple(const wxChar * const *names, bool *array, size_t sz); /** Save multiple double values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool SetMultiple(const wxChar * const *names, double *array, size_t sz); /** Save multiple string values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool SetMultiple( const wxChar * const *names, const wxChar * const *array, size_t sz ); /** Retrieve multiple long values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool GetMultiple(const wxChar * const *names, long *array, size_t sz); /** Retrieve multiple int values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool GetMultiple(const wxChar * const *names, int *array, size_t sz); /** Retrieve multiple bool values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool GetMultiple(const wxChar * const *names, bool *array, size_t sz); /** Retrieve multiple double values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @return True on success, false on error. */ bool GetMultiple(const wxChar * const *names, double *array, size_t sz); /** Retrieve multiple string values. @param names Entry names array, sz elements. @param array Values, sz elements. @param sz Array size for names and array. @param ov Flag: Overwrite existing strings. Memory for already existing strings is freed, memory for the new found string is allocated if the flag is set. Existing strings are left untouched if the flag is not set. @return True on success, false on error. */ bool GetMultiple( const wxChar * const *names, wxChar **array, size_t sz, bool ov = true ); /** Correct top level frame position. @param x Window x position. @param y Window y position. @param w Window width. @param h Window height. */ static void CorrectPosition(int & x, int & y, int & w, int & h); /** Correct position of a top level window (frame or dialog). @param w Window to correct. */ static void CorrectPosition(wxWindow & w); /** Choose position for a child top level window (frame or dialog). @param p Parent window, unchanged. @param c Child window, position is set. @param beside Flag: Position child beside parent, not on top. */ static void ChooseChildPosition( const wxWindow & p, wxWindow & c, bool beside = false ); /** Find string table size (number of strings in table). @param sttptr String table to find size for. @return Size of string table. */ static size_t StringTableSize(const wxChar * const *sttptr); /** Release array of wxChar strings. @param array Array, array contents is to release. @param sz Array size. @param ea Flag: After releasing contents, release array itself. */ static void ReleaseWxcharStringArray(wxChar **array, size_t sz, bool ea = false); }; %% module #include "Dk4WxApplicationHelper.h" #include "dk4mem.h" #include "dk4enc.h" #include "dk4strd.h" #include "dk4strx.h" #include "dk4recwx.h" #include "dk4wxpref.h" #include "dk4wxstt.h" #include "dk4hnamed.h" #include "dk4loc.h" #include "dk4user.h" #include "dk4mpl.h" #include "dk4vers.h" #include "dk4exepd.h" #include "dk4inst.h" #include "dk4pathd.h" #if DK4_SIZEOF_WXCHAR > 1 #include "dk4strw.h" #include "dk4maiwdil.h" #include "dk4maiwdbl.h" #else #include "dk4str8.h" #include "dk4mai8dil.h" #include "dk4mai8dbl.h" #endif $!trace-include $* Type definitions. $* /** Pointer to constant wxChar. */ typedef const wxChar *PCWXCHAR; /** Error codes in Initialize(). */ enum { /** No error occured. */ ERROR_NONE = 0, /** Not enough memory. */ ERROR_MEMORY , /** Failed to find host name. */ ERROR_HOSTNAME , /** Failed to find localization settings. */ ERROR_LANG_REG_ENC , /** Failed to find login name. */ ERROR_LOGNAME , /** Failed to find home directory. */ ERROR_HOMEDIR , /** Failed to find path name of executable. */ ERROR_EXECUTABLE , /** Executable file name too long. */ ERROR_EXEC_TOO_LONG , /** Invalid arguments were passed to Initialize(). */ ERROR_ARGUMENTS , }; $* Variables. $* /** Empty string, returned for all strings not found. */ static const wxChar dk4wxah_empty_string[] = { wxT("") }; /** File name separator string */ static const dkChar dk4wxah_fnsep_str[] = { #if DK4_ON_WINDOWS dkT("\\") #else dkT("/") #endif } ; /** Texts used in error message boxes in the Initialize() function. */ static const wxChar * const dkwxah_msgb_texts[] = { $!string-table macro=wxT # # 0 Initialization failed! # Initialization failed! # # 1 Not enough memory! # Not enough memory! # # 2 Failed to find current host name! # Failed to find current host name! # # 3 Failed to find language, region, and encoding settings! # Failed to find language, region, and encoding settings! # # 4 Failed to find users login name! # Failed to find users login name! # # 5 Failed to find users home directory! # Failed to find users home directory! # # 6 Failed to find executable file name! # Failed to find executable file name! # # 7 Executable file name too long! # Executable file name too long! # # 8 Illegal arguments (NULL pointers) to Initialize() function! # Illegal arguments (NULL pointers) to Initialize() function! $!end }; /** Constant text keywords used by module, not localized. */ static const dkChar * const dk4wxah_kwnl_dk[] = { $!string-table macro=dkT # # 0 String table file name for basic strings. # dk4wxbase.str $!end }; /** Constant text strings used by the module, not localized. */ static const char * const dk4wxah_kwnl_c8[] = { $!string-table C $!end }; /** Final directory names for good installations. */ static const dkChar * const dk4wxah_final_directories[] = { $!string-table macro=dkT bin sbin libexec lib $!end }; /** New final directory names to append. */ static const dkChar * const dk4wxah_new_directories[] = { $!string-table macro=dkT etc share $!end }; /** Basic strings, replaced by localized texts later. */ static const wxChar * const dk4wxah_basic_strings[] = { $!string-table macro=wxT # # 0 Dialog box title: Help file not found # Help file not found # # 1 Dialog box text: Help file not found! # The file containing online help text was not found on your computer! # # 2 Progress dialog title # Processing in progress # # 3 4 5 Progress dialog cancel button, tooltip and response # Cancel Abort current operation Abortion scheduled, wait please! # # 6 7 8 Further error messages printed by Dk4WxHelpController # Error Not enough memory (RAM)! Illegal arguments in Dk4WxHelpController constructor (bug)! $!end }; $* Internal tool functions, not object-oriented. $* /** Check whether a directory or file name ends in one of the names mentioned in array. @param dirname Directory name to check. @param array String array containing name ends. @return 1 on success with prefix in dirname, 0 on error. */ static int dk4wxapplicationhelper_isinsub(dkChar *dirname, const dkChar * const *array) { dkChar *p1; dkChar *p2; int cc; /* Flag: Can continue */ int back = 0; /* Function result */ $? "+ dk4wxapplicationhelper_isinsub" do { cc = 0; p1 = dirname; p2 = NULL; while (dkT('\0') != *p1) { if ((dkT('/') == *p1) || (dkT('\\') == *p1)) { p2 = p1; } p1++; } if (NULL != p2) { *(p2++) = dkT('\0'); cc = 1; #if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES if (0 <= dk4str_array_index(array, p2, 0)) #else if (0 <= dk4str_array_index(array, p2, 1)) #endif { back = 1; cc = 0; } } else { } } while ((1 == cc) && (0 == back)); $? "- dk4wxapplicationhelper_isinsub %d", back return back; } $* Constructor, destructor, initialization and cleanup. $* Dk4WxApplicationHelper::Dk4WxApplicationHelper() { /* Set all member variables to "resource not available". Real initialization is in the Initialize() method. */ $? "+ Dk4WxApplicationHelper" ppBasicStrings = NULL; pcwxsArgv0 = NULL; pcwxsVendor = NULL; pcdksGroup = NULL; pwxsApp = NULL; pdksHost = NULL; pdksLogname = NULL; pdksHome = NULL; pdksApp = NULL; pdksSysconf = NULL; pdksShare = NULL; pdksLanguage = NULL; pdksRegion = NULL; sStt = NULL; iStt = NULL; sPrSys = NULL; iPrSys = NULL; sPrUser = NULL; iPrUser = NULL; nBasicStrings = 0; iDkEncoding = DK4_ENCODING_ASCII; iWxEncoding = DK4_ENCODING_ASCII; iFiEncoding = DK4_FILE_ENCODING_ASCII; bActive = false; $? "- Dk4WxApplicationHelper" } /* We do not need a critical section locker as Initialize() is invoked from the applications OnInit() method. At this time there is no top level window or worker thread yet. */ bool Dk4WxApplicationHelper::Initialize( const wxChar *argv0, const wxChar *vendorName, const dkChar *groupName, dk4_er_t *erp ) { dkChar labuf[DK4_MAX_PATH]; dkChar rebuf[DK4_MAX_PATH]; wxChar anbuf[DK4_MAX_PATH]; const wxChar *msgbtext = NULL; const wxChar *msgbtitle = NULL; dkChar *p1; dkChar *p2; #if DK4_ON_WINDOWS dkChar *p4; #endif size_t szrebuf = DK4_SIZEOF(rebuf,dkChar); size_t szlabuf = DK4_SIZEOF(labuf,dkChar); size_t szanbuf = DK4_SIZEOF(anbuf,wxChar); int errc = ERROR_NONE; int res; int pn; bool back = false; $? "+ Initialize" /* Keep some of the arguments. */ if ((NULL == argv0) || (NULL == vendorName) || (NULL == groupName)) { errc = ERROR_ARGUMENTS; goto finished; } pcwxsArgv0 = argv0; pcwxsVendor = vendorName; pcdksGroup = groupName; $? ". function call arguments saved" /* Some default values. */ ppBasicStrings = dk4wxah_basic_strings; nBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1; $? ". default basic strings set up" /* Host name. */ if (0 != dk4hostname(labuf, szlabuf, NULL)) { p1 = dk4str_chr(labuf, dkT('.')); if (NULL != p1) { *p1 = dkT('\0'); } pdksHost = dk4str_dup(labuf, NULL); if (NULL == pdksHost) { errc = ERROR_MEMORY; goto finished; } } else { errc = ERROR_HOSTNAME; goto finished; } $? ". host name found" /* Language and encoding. */ res = dk4loc_get_settings(labuf, szlabuf, rebuf, szrebuf, &iDkEncoding, erp); if (0 == res) { errc = ERROR_LANG_REG_ENC; goto finished; } #if DK4_SIZEOF_WXCHAR > 1 #if DK4_SIZEOF_WXCHAR > 2 iWxEncoding = DK4_ENCODING_32; #else iWxEncoding = DK4_ENCODING_UTF16; #endif #else switch (iDkEncoding) { case DK4_ENCODING_ANSI : { iWxEncoding = DK4_ENCODING_ANSI; } break; case DK4_ENCODING_UTF8 : { iWxEncoding = DK4_ENCODING_UTF8; } break; default : { iWxEncoding = DK4_ENCODING_ASCII; } break; } #endif switch (iDkEncoding) { case DK4_ENCODING_ANSI : { iFiEncoding = DK4_ENCODING_ANSI; } break; case DK4_ENCODING_UTF8 : { iFiEncoding = DK4_ENCODING_UTF8; } break; default : { iFiEncoding = DK4_ENCODING_ASCII; } break; } if (0 < dk4str_len(labuf)) { pdksLanguage = dk4str_dup(labuf, erp); if (NULL == pdksLanguage) { errc = ERROR_MEMORY; goto finished; } } if (0 < dk4str_len(rebuf)) { pdksRegion = dk4str_dup(rebuf, erp); if (NULL == pdksRegion) { errc = ERROR_MEMORY; goto finished; } } $? ". language encoding region ok" /* Login name and home directory. */ res = dk4user_get_logname(labuf, szlabuf, 0, erp); if (0 == res) { errc = ERROR_LOGNAME; goto finished; } pdksLogname = dk4str_dup(labuf, erp); if (NULL == pdksLogname) { errc = ERROR_MEMORY; goto finished; } res = dk4user_get_homedir(labuf, szlabuf, 0, erp); if (0 == res) { $? "! home dir not found" errc = ERROR_HOMEDIR; goto finished; } pdksHome = dk4str_dup(labuf, erp); if (NULL == pdksHome) { $? "! memory" errc = ERROR_MEMORY; goto finished; } $? ". login name and home directory found" /* System configuration and data directory. */ res = dk4recwx_wxchar_to_dkchar( labuf, szlabuf, iDkEncoding, argv0, iWxEncoding, erp ); $? ". dk4recwx_wxchar_to_dkchar=%d", res res = dk4execpath( rebuf, szrebuf, ((0 != res) ? labuf : NULL), erp ); if (0 == res) { $? "! executable not found" errc = ERROR_EXECUTABLE; goto finished; } $? ". got executable" p1 = rebuf; p2 = NULL; while (dkT('\0') != *p1) { if (dk4wxah_fnsep_str[0] == *p1) { p2 = p1; } /* We must increase this pointer. */ p1++; } if (NULL == p2) { $? "! separator not found" errc = ERROR_EXECUTABLE; goto finished; } *(p2++) = dkT('\0'); /* Binary directory in rebuf, p2 is application name */ #if DK4_ON_WINDOWS /* On Windows, strip .exe suffix. */ p4 = dk4path_get_suffix(p2, NULL); if (NULL != p4) { *p4 = dkT('\0'); } #endif pdksApp = dk4str_dup(p2, NULL); if (NULL == pdksApp) { errc = ERROR_MEMORY; goto finished; } res = dk4recwx_dkchar_to_wxchar( anbuf, szanbuf, iWxEncoding, pdksApp, iDkEncoding, NULL ); if (0 == res) { $? "! dk4recwx_dkchar_to_wxchar" errc = ERROR_EXECUTABLE; goto finished; } pwxsApp = dk4strx_dup(anbuf, NULL); if (NULL == pwxsApp) { errc = ERROR_MEMORY; goto finished; } /* Check whether the binary resides in one of the installation directories */ res = 0; if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(4), NULL)) { res = 1; } if (0 == res) { if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(5), NULL)) { res = 1; } } if (0 == res) { if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(6), NULL)) { res = 1; } } if (0 == res) { if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(10), NULL)) { res = 1; } } if (0 != res) { pdksSysconf = dk4str_dup(dk4inst_get_directory(1), NULL); pdksShare = dk4str_dup(dk4inst_get_directory(2), NULL); if ((NULL == pdksSysconf) || (NULL == pdksShare)) { errc = ERROR_MEMORY; goto finished; } } else { dk4str_cpy_s(labuf, szlabuf, rebuf, NULL); if (0 != dk4wxapplicationhelper_isinsub(labuf, dk4wxah_final_directories)) { res = 0; if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) { if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) { if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[0],NULL)) { res = 1; } } } if (0 != res) { pdksSysconf = dk4str_dup(rebuf, NULL); if (NULL == pdksSysconf) { errc = ERROR_MEMORY; goto finished; } } else { errc = ERROR_EXEC_TOO_LONG; goto finished; } res = 0; if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) { if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) { if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[1],NULL)) { res = 1; } } } if (0 != res) { pdksShare = dk4str_dup(rebuf, NULL); if (NULL == pdksShare) { errc = ERROR_MEMORY; goto finished; } } else { errc = ERROR_EXEC_TOO_LONG; goto finished; } } else { pdksSysconf = dk4str_dup(rebuf, NULL); pdksShare = dk4str_dup(rebuf, NULL); if ((NULL == pdksSysconf) || (NULL == pdksShare)) { errc = ERROR_MEMORY; goto finished; } } } $? ". sysconf and data dir found" /* Containers and iterators for string tables and preferences. */ sStt = dk4sto_open(NULL); if (NULL == sStt) { errc = ERROR_MEMORY; goto finished; } dk4sto_set_comp(sStt, dk4wxstt_compare, 0); iStt = dk4sto_it_open(sStt, NULL); if (NULL == iStt) { errc = ERROR_MEMORY; goto finished; } sPrSys = dk4sto_open(NULL); if (NULL == sPrSys) { errc = ERROR_MEMORY; goto finished; } dk4sto_set_comp(sPrSys, dk4wxpref_compare, 0); iPrSys = dk4sto_it_open(sPrSys, NULL); if (NULL == iPrSys) { errc = ERROR_MEMORY; goto finished; } sPrUser = dk4sto_open(NULL); if (NULL == sPrUser) { errc = ERROR_MEMORY; goto finished; } dk4sto_set_comp(sPrUser, dk4wxpref_compare, 0); iPrUser = dk4sto_it_open(sPrUser, NULL); if (NULL == iPrUser) { errc = ERROR_MEMORY; goto finished; } $? ". storages created" /* Read preference files. */ for (pn = 0; pn <= DK4_FS_CONF_MAX; pn++) { dk4wxpref_one_pass( ((DK4_FS_CONF_SYS_MAX < pn) ? sPrUser : sPrSys), ((DK4_FS_CONF_SYS_MAX < pn) ? iPrUser : iPrSys), pdksApp, pcdksGroup, pdksLogname, pdksHost, pdksLanguage, pdksRegion, pdksHome, pdksSysconf, pdksShare, iWxEncoding, iDkEncoding, ( (DK4_ENCODING_UTF8 == iDkEncoding) ? DK4_FILE_ENCODING_UTF8 : DK4_FILE_ENCODING_ASCII ), pn ); } $? ". preference files processed" /* Localized basic strings. */ ppBasicStrings = InternalGetStringTable( dk4wxah_kwnl_dk[0], (DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1) ); if (NULL == ppBasicStrings) { ppBasicStrings = dk4wxah_basic_strings; } nBasicStrings = Dk4WxApplicationHelper::StringTableSize(ppBasicStrings); $? ". localized strings found" /* Finally mark success. */ bActive = back = true; /* Clean up if not successfully. */ finished: if (!(back)) { $? "! error" switch (errc) { case ERROR_MEMORY : { $? "! memory" msgbtext = dkwxah_msgb_texts[1]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_HOSTNAME : { $? "! host name not found" msgbtext = dkwxah_msgb_texts[2]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_LANG_REG_ENC : { $? "! region/encoding not found" msgbtext = dkwxah_msgb_texts[3]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_LOGNAME : { $? "! log name not found" msgbtext = dkwxah_msgb_texts[4]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_HOMEDIR : { $? "! home directory not found" msgbtext = dkwxah_msgb_texts[5]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_EXECUTABLE : { $? "! executable file name not found" msgbtext = dkwxah_msgb_texts[6]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_EXEC_TOO_LONG : { $? "! executable file name too long" msgbtext = dkwxah_msgb_texts[7]; msgbtitle = dkwxah_msgb_texts[0]; } break; case ERROR_ARGUMENTS : { $? "! invalid arguments" msgbtext = dkwxah_msgb_texts[8]; msgbtitle = dkwxah_msgb_texts[0]; } break; } if ((NULL != msgbtext) && (NULL != msgbtitle)) { wxMessageBox( msgbtext, msgbtitle, (wxOK | wxCENTRE | wxICON_ERROR) ); } InternalCleanup(); } $? "- Initialize %d", ((back) ? 1 : 0) return back; } void Dk4WxApplicationHelper::InternalCleanup(void) { dk4_wx_string_table_t *wxsttptr; dk4_wx_pref_t *pptr; $? "+ InternalCleanup" bActive = false; // Object can not longer be used. ppBasicStrings = NULL; pcwxsArgv0 = NULL; pcwxsVendor = NULL; pcdksGroup = NULL; if (NULL != sPrUser) { if (NULL != iPrUser) { dk4sto_it_reset(iPrUser); do { pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrUser); if (NULL != pptr) { dk4wxpref_close(pptr); } } while (NULL != pptr); dk4sto_it_close(iPrUser); iPrUser = NULL; } dk4sto_close(sPrUser); sPrUser = NULL; } if (NULL != sPrSys) { if (NULL != iPrSys) { dk4sto_it_reset(iPrSys); do { pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrSys); if (NULL != pptr) { dk4wxpref_close(pptr); } } while (NULL != pptr); dk4sto_it_close(iPrSys); iPrSys = NULL; } dk4sto_close(sPrSys); sPrSys = NULL; } if (NULL != sStt) { if (NULL != iStt) { dk4sto_it_reset(iStt); do { wxsttptr = (dk4_wx_string_table_t *)dk4sto_it_next(iStt); if (NULL != wxsttptr) { dk4wxstt_close(wxsttptr); } } while (NULL != wxsttptr); dk4sto_it_close(iStt); iStt = NULL; } dk4sto_close(sStt); sStt = NULL; } nBasicStrings = 0; #if 0 /* Leave these integer variables as is. */ iDkEncoding = DK4_ENCODING_ASCII; iWxEncoding = DK4_ENCODING_ASCII; iFiEncoding = DK4_FILE_ENCODING_ASCII; #endif dk4mem_release(pdksRegion); dk4mem_release(pdksLanguage); dk4mem_release(pdksShare); dk4mem_release(pdksSysconf); dk4mem_release(pdksApp); dk4mem_release(pdksHost); dk4mem_release(pwxsApp); dk4mem_release(pdksLogname); dk4mem_release(pdksHome); $? "- InternalCleanup" } void Dk4WxApplicationHelper::Cleanup(void) { $? "+ Cleanup" { wxCriticalSectionLocker lock(csProtect); InternalCleanup(); } $? "- Cleanup" } /* We do not need a critical section locker as the destructor is invoked from the applications destructor. At this we have no more top level windows or worker threads. */ Dk4WxApplicationHelper::~Dk4WxApplicationHelper() { $? "+ ~Dk4WxApplicationHelper" InternalCleanup(); $? "- ~Dk4WxApplicationHelper" } $* Internal functions. These functions do not attempt synchronization. $* bool Dk4WxApplicationHelper::InternalStringToWx( wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp ) { int res = 0; bool back = false; $? "+ InternalStringToWx" res = dk4recwx_dkchar_to_wxchar(dptr,dsz,iWxEncoding,sptr,iDkEncoding,erp); if (0 != res) { back = true; } $? "- InternalStringToWx %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalStringToDk( dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp ) { int res = 0; bool back = false; $? "+ InternalStringToDk" res = dk4recwx_wxchar_to_dkchar(dptr,dsz,iDkEncoding,sptr,iWxEncoding,erp); if (0 != res) { back = true; } $? "- InternalStringToDk %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalFindDataFile( dkChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass, bool aco ) { int passno = 0; int res = 0; bool back = false; $? "+ InternalFindDataFile dkChar" for (passno = 0; ((passno < maxpass) && (!(back))); passno++) { res = dk4fs_data_one( fnb, szfnb, sfn, pdksShare, pdksHome, pdksApp, pcdksGroup, pdksLanguage, pdksRegion, passno, ((aco) ? 1 : 0), NULL ); if (0 != res) { back = true; } } $? "- InternalFindDataFile %d", (back ? 1 : 0) return back; } #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE bool Dk4WxApplicationHelper::InternalFindDataFile( wxChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass, bool aco ) { dkChar buf[DK4_MAX_PATH]; size_t szbuf = DK4_SIZEOF(buf,dkChar); bool back = false; $? "+ InternalFindDataFile wxChar" back = InternalFindDataFile(buf, szbuf, sfn, maxpass, aco); if (back) { back = InternalStringToWx(fnb, szfnb, buf, NULL); } $? "- InternalFindDataFile %d", (back ? 1 : 0) return back; } #endif const wxChar * const * Dk4WxApplicationHelper::InternalGetStringTable( const dkChar *tableName, size_t tableSize ) { dkChar fnb[DK4_MAX_PATH]; dk4_er_t e1; dk4_er_t e2; const wxChar * const *back = NULL; dk4_wx_string_table_t *tabptr = NULL; dk4_stream_t *strm = NULL; size_t szfnb = DK4_SIZEOF(fnb,dkChar); $? "+ InternalGetStringTable" tabptr = (dk4_wx_string_table_t *)dk4sto_it_find_like(iStt, tableName, 1); if (NULL == tabptr) { if (InternalFindDataFile(fnb, szfnb, tableName, DK4_FS_DATA_MAX_SYS, 1)) { strm = dk4stream_open_file_reader(fnb, NULL); if (NULL != strm) { tabptr = dk4wxstt_open(tableName, tableSize, NULL); if (NULL != tabptr) { if (0 != dk4sto_add(sStt, tabptr, NULL)) { dk4error_init(&e1); dk4error_init(&e2); if (!dk4wxstt_apply_stream(tabptr, strm, iWxEncoding, &e1, &e2)) { dk4wxstt_shutdown(tabptr); } } else { dk4wxstt_close(tabptr); tabptr = NULL; } } dk4stream_close(strm, NULL); } } } if (NULL != tabptr) { if (tabptr->nstrings >= tableSize) { back = (const wxChar * const *)(tabptr->strings); } } $? "- InternalGetStringTable %d", ((NULL != back) ? 1 : 0) return back; } bool Dk4WxApplicationHelper::InternalSetMultiple( const wxChar * const *names, long *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); size_t i = 0; bool back = false; $? "+ InternalSetMultiple long" if ((NULL != names) && (NULL != array) && (0 < sz)) { back = true; for (i = 0; i < sz; i++) { if (!(conf.Write(names[i], array[i]))) { back = false; } } } $? "- InternalSetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalSetMultiple( const wxChar * const *names, int *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); size_t i = 0; bool back = false; $? "+ InternalSetMultiple int" if ((NULL != names) && (NULL != array) && (0 < sz)) { back = true; for (i = 0; i < sz; i++) { if (!(conf.Write(names[i], array[i]))) { back = false; } } } $? "- InternalSetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalSetMultiple( const wxChar * const *names, bool *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); size_t i = 0; bool back = false; $? "+ InternalSetMultiple bool" if ((NULL != names) && (NULL != array) && (0 < sz)) { back = true; for (i = 0; i < sz; i++) { if (!(conf.Write(names[i], array[i]))) { back = false; } } } $? "- InternalSetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalSetMultiple( const wxChar * const *names, double *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); size_t i = 0; bool back = false; $? "+ InternalSetMultiple double" if ((NULL != names) && (NULL != array) && (0 < sz)) { back = true; for (i = 0; i < sz; i++) { if (!(conf.Write(names[i], array[i]))) { back = false; } } } $? "- InternalSetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalSetMultiple( const wxChar * const *names, const wxChar * const *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); size_t i = 0; bool back = false; $? "+ InternalSetMultiple string" if ((NULL != names) && (NULL != array) && (0 < sz)) { back = true; for (i = 0; i < sz; i++) { if (!(conf.Write(names[i], array[i]))) { back = false; } } } $? "- InternalSetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalGetMultiple( const wxChar * const *names, long *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); dk4_wx_pref_t *pptr = NULL; #if DK4_SIZEOF_WXCHAR > 1 const wchar_t *ep = NULL; #else const char *ep = NULL; #endif size_t i; long l; int res; bool back = false; $? "+ InternalGetMultiple" back = true; for (i = 0; i < sz; i++) { l = 0L; if (conf.Read(names[i], &l)) { array[i] = l; } else { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1); if (NULL == pptr) { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1); } if (NULL != pptr) { #if DK4_SIZEOF_WXCHAR > 1 res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL); #else res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL); #endif if (0 != res) { array[i] = l; } else { back = false; } } } } $? "- InternalGetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalGetMultiple( const wxChar * const *names, int *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); dk4_wx_pref_t *pptr = NULL; #if DK4_SIZEOF_WXCHAR > 1 const wchar_t *ep = NULL; #else const char *ep = NULL; #endif size_t i; long l; int res; bool back = false; $? "+ InternalGetMultiple" back = true; for (i = 0; i < sz; i++) { l = 0L; if (conf.Read(names[i], &l)) { if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) { array[i] = (int)l; } else { back = false; } } else { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1); if (NULL == pptr) { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1); } if (NULL != pptr) { #if DK4_SIZEOF_WXCHAR > 1 res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL); #else res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL); #endif if (0 != res) { if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) { array[i] = (int)l; } else { back = false; } } else { back = false; } } } } $? "- InternalGetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalGetMultiple( const wxChar * const *names, bool *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); dk4_wx_pref_t *pptr = NULL; size_t i; bool l; bool back = false; $? "+ InternalGetMultiple bool" back = true; for (i = 0; i < sz; i++) { l = 0L; $? ". name \"%!ws\"", TR_WXSTR(names[i]) if (conf.Read(names[i], &l)) { array[i] = l; } else { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1); if (NULL == pptr) { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1); } if (NULL != pptr) { $? ". found" $? ". pptr" $? ". pptr->value = %!ws", TR_WXSTR(pptr->value) #if DK4_SIZEOF_WXCHAR > 1 $? ". wide" if (0 != dk4strw_is_bool(pptr->value)) { if (0 != dk4strw_is_on(pptr->value)) { array[i] = true; $? ". on" } else { array[i] = false; $? ". off" } } else { $? "! not boolean" back = false; } #else $? ". 8 bit" if (0 != dk4str8_is_bool(pptr->value)) { if (0 != dk4str8_is_on(pptr->value)) { array[i] = true; $? ". on" } else { array[i] = false; $? ". off" } } else { back = false; $? "! not boolean" } #endif } else { $? ". not found" } } } $? "- InternalGetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalGetMultiple( const wxChar * const *names, double *array, size_t sz ) { wxConfig conf(pwxsApp, pcwxsVendor); dk4_wx_pref_t *pptr = NULL; #if DK4_SIZEOF_WXCHAR > 1 const wchar_t *ep = NULL; #else const char *ep = NULL; #endif #if DK4_HAVE_SETLOCALE char *oldloc = NULL; #endif double l; size_t i; int res; bool back = false; $? "+ InternalGetMultiple" back = true; for (i = 0; i < sz; i++) { l = 0.0; if (conf.Read(names[i], &l)) { array[i] = l; } else { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1); if (NULL == pptr) { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1); } if (NULL != pptr) { #if DK4_HAVE_SETLOCALE oldloc = setlocale(LC_NUMERIC, dk4wxah_kwnl_c8[0]); #endif #if DK4_SIZEOF_WXCHAR > 1 res = dk4ma_input_wc_double(&l, pptr->value, &ep, 1, NULL); #else res = dk4ma_input_c8_double(&l, pptr->value, &ep, 1, NULL); #endif #if DK4_HAVE_SETLOCALE if (NULL != oldloc) { setlocale(LC_NUMERIC, oldloc); } #endif if (0 != res) { array[i] = l; } else { back = false; } } } } $? "- InternalGetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::InternalGetMultiple( const wxChar * const *names, wxChar **array, size_t sz, bool ov ) { wxConfig conf(pwxsApp, pcwxsVendor); dk4_wx_pref_t *pptr = NULL; const wxChar *vptr = NULL; wxChar *nptr = NULL; size_t i; bool back = false; $? "+ InternalGetMultiple strings" back = true; for (i = 0; i < sz; i++) { if ((NULL == array[i]) || (ov)) { wxString value = wxEmptyString; if (conf.Read(names[i], &value)) { vptr = value.c_str(); if (NULL != vptr) { nptr = dk4strx_dup(vptr, NULL); if (NULL != nptr) { if (NULL != array[i]) { dk4mem_free(array[i]); } array[i] = nptr; } else { back = false; } } else { back = false; } } else { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1); if (NULL == pptr) { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1); } if (NULL != pptr) { nptr = dk4strx_dup(pptr->value, NULL); if (nptr) { if (NULL != array[i]) { dk4mem_free(array[i]); } array[i] = nptr; } else { back = false; } } } } } $? "- InternalGetMultiple %d", (int)back return back; } $* Public interface. The methods must (a) synchronize access attempts from multiple threads and (b) ensure the object is in a usable state. $* bool Dk4WxApplicationHelper::FindDataFile( dkChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass, bool aco ) { bool back = false; $? "+ FindDataFile dkChar" if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco); } } $? "- FindDataFile %d", (int)back return back; } #if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE bool Dk4WxApplicationHelper::FindDataFile( wxChar *fnb, size_t szfnb, dkChar const *sfn, int maxpass, bool aco ) { bool back = false; $? "+ FindDataFile wxChar" if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco); } } $? "- FindDataFile %d", (int)back return back; } #endif int Dk4WxApplicationHelper::GetDkEncoding(void) { int back = DK4_ENCODING_ASCII; $? "+ GetDkEncoding" { wxCriticalSectionLocker lock(csProtect); back = iDkEncoding; } $? "- GetDkEncoding %d", back return back; } int Dk4WxApplicationHelper::GetWxEncoding(void) { int back = DK4_ENCODING_ASCII; $? "+ GetWxEncoding" { wxCriticalSectionLocker lock(csProtect); back = iWxEncoding; } $? "- GetWxEncoding %d", back return back; } int Dk4WxApplicationHelper::GetFiEncoding(void) { int back = DK4_ENCODING_ASCII; $? "+ GetFiEncoding" { wxCriticalSectionLocker lock(csProtect); back = iFiEncoding; } $? "- GetFiEncoding %d", back return back; } const wxChar * const * Dk4WxApplicationHelper::GetStringTable( const dkChar *tableName, const wxChar * const *defaultTable ) { const wxChar * const *back = NULL; size_t sz = 0; $? "+ GetStringTable" if ((NULL != tableName) && (NULL != defaultTable)) { sz = Dk4WxApplicationHelper::StringTableSize(defaultTable); if (0 < sz) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalGetStringTable(tableName, sz); } } } if (NULL == back) { back = defaultTable; } $? "- GetStringTable %d", ((NULL != back) ? 1 : 0) return back; } const wxChar * Dk4WxApplicationHelper::GetBasicString( size_t numstr ) { const wxChar *back = NULL; $? "+ GetBasicString" { wxCriticalSectionLocker lock(csProtect); if (bActive) { if ((NULL != ppBasicStrings) && (0 < nBasicStrings)) { if (numstr < nBasicStrings) { back = ppBasicStrings[numstr]; } } } } if (NULL == back) { if (numstr < (DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1)) { back = dk4wxah_basic_strings[numstr]; } else { back = dk4wxah_empty_string; } } $? "- GetBasicString %d", ((NULL != back) ? 1 : 0) return back; } const wxChar * const * Dk4WxApplicationHelper::GetBasicStrings( size_t *pNumBasicStrings ) { const wxChar * const *back = NULL; $? "+ GetBasicStrings" { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = ppBasicStrings; if (NULL != pNumBasicStrings) { *pNumBasicStrings = nBasicStrings; } } } if (NULL == back) { back = dk4wxah_basic_strings; if (NULL != pNumBasicStrings) { *pNumBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1; } } $? "- GetBasicStrings %d", ((NULL != back) ? 1 : 0) return back; } bool Dk4WxApplicationHelper::StringToWx( wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp ) { int res = 0; int wxe = DK4_ENCODING_ASCII; int dke = DK4_ENCODING_ASCII; bool back = false; $? "+ StringToWx" if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) { { wxCriticalSectionLocker lock(csProtect); wxe = iWxEncoding; dke = iDkEncoding; } res = dk4recwx_dkchar_to_wxchar(dptr, dsz, wxe, sptr, dke, erp); if (0 != res) { back = true; } } $? "- StringToWx %d", (int)back return back; } bool Dk4WxApplicationHelper::StringToDk( dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp ) { int res = 0; int wxe = DK4_ENCODING_ASCII; int dke = DK4_ENCODING_ASCII; bool back = false; $? "+ StringToDk" if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) { { wxCriticalSectionLocker lock(csProtect); wxe = iWxEncoding; dke = iDkEncoding; } res = dk4recwx_wxchar_to_dkchar(dptr, dsz, dke, sptr, wxe, erp); if (0 != res) { back = true; } } $? "- StringToDk %d", (int)back return back; } bool Dk4WxApplicationHelper::StringToChar( char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp ) { int res = 0; int wxe = DK4_ENCODING_ASCII; int dke = DK4_ENCODING_ASCII; bool back = false; if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) { { wxCriticalSectionLocker lock(csProtect); wxe = iWxEncoding; dke = iDkEncoding; } if (DK4_ENCODING_UTF8 != dke) { if (DK4_ENCODING_ANSI != dke) { dke = DK4_ENCODING_ASCII; } } res = dk4recwx_wxchar_to_char(dptr, dsz, dke, sptr, wxe, erp); if (0 != res) { back = true; } } return back; } bool Dk4WxApplicationHelper::SetMultiple( const wxChar * const *names, long *array, size_t sz ) { bool back = false; $? "+ SetMultiple long" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalSetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- SetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::SetMultiple( const wxChar * const *names, int *array, size_t sz ) { bool back = false; $? "+ SetMultiple int" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalSetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- SetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::SetMultiple( const wxChar * const *names, bool *array, size_t sz ) { bool back = false; $? "+ SetMultiple bool" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalSetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- SetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::SetMultiple( const wxChar * const *names, double *array, size_t sz ) { bool back = false; $? "+ SetMultiple double" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalSetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- SetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::SetMultiple( const wxChar * const *names, const wxChar * const *array, size_t sz ) { bool back = false; $? "+ SetMultiple strings" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalSetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- SetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::GetMultiple( const wxChar * const *names, long *array, size_t sz ) { bool back = false; $? "+ GetMultiple long" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalGetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- GetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::GetMultiple( const wxChar * const *names, int *array, size_t sz ) { bool back = false; $? "+ GetMultiple int" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalGetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- GetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::GetMultiple( const wxChar * const *names, bool *array, size_t sz ) { bool back = false; $? "+ GetMultiple bool" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalGetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- GetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::GetMultiple( const wxChar * const *names, double *array, size_t sz ) { bool back = false; $? "+ GetMultiple double" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalGetMultiple(names, array, sz); } else { /* Object not active */ } } $? "- GetMultiple %d", (int)back return back; } bool Dk4WxApplicationHelper::GetMultiple( const wxChar * const *names, wxChar **array, size_t sz, bool ov ) { bool back = false; $? "+ GetMultiple strings" if ((NULL != names) && (NULL != array) && (0 < sz)) { wxCriticalSectionLocker lock(csProtect); if (bActive) { back = InternalGetMultiple(names, array, sz, ov); } else { /* Object not active */ } } $? "- GetMultiple %d", (int)back return back; } $* Static class functions. $* void Dk4WxApplicationHelper::CorrectPosition( int & x, int & y, int & w, int & h ) { wxSize scsz; $? "+ CorrectPosition %d %d %d %d", x, y, w, h scsz = wxGetDisplaySize(); if (0 > x) { x = (scsz.x - w) / 2; } if (0 > y) { y = (scsz.y - h) / 2; } if (scsz.x < (x + w)) { x = scsz.x - w; } if (scsz.y < (y + h)) { y = scsz.y - h; } if (0 > x) { x = 0; } if (0 > y) { y = 0; } $? "- CorrectPosition %d %d %d %d", x, y, w, h } void Dk4WxApplicationHelper::CorrectPosition( wxWindow & wnd ) { int x, y, w, h; $? "+ CorrectPosition window" wnd.GetPosition(&x, &y); wnd.GetSize(&w, &h); Dk4WxApplicationHelper::CorrectPosition(x, y, w, h); wnd.SetSize(x, y, w, h); $? "- CorrectPosition" } void Dk4WxApplicationHelper::ChooseChildPosition( const wxWindow & p, wxWindow & c, bool beside ) { wxSize scsz = wxGetDisplaySize(); int px = 0; int py = 0; int pw = 0; int ph = 0; int cx = 0; int cy = 0; int cw = 0; int ch = 0; bool done = false; bool findy = false; $? "+ ChooseChildPosition" p.GetPosition(&px, &py); p.GetSize(&pw, &ph); c.GetSize(&cw, &ch); if (beside) { /* Attempt right side */ if (scsz.x > px + pw + cw) { cx = px + pw; done = true; findy = true; } /* Attempt bottom side */ if (!done) { if (scsz.y > py + ph + ch) { cy = py + ph; done = true; } } /* Attempt left side */ if (!done) { if (px > cw) { cx = px - cw; done = true; findy = true; } } /* Attempt top side */ if (!done) { if (py < ch) { cy = py - ch; done = true; } } if (done) { if (findy) { if (scsz.y > (py + ch)) { cy = py; } else { if (0 <= (py + ph - ch)) { cy = py + ph - ch; } else { cy = py + (ph - ch) / 2; if (scsz.y <= (cy + ch)) { cy = scsz.y - ch - 1; } if (0 > cy) { cy = 0; } } } } else { if (scsz.x > (px + cw)) { cx = px; } else { if (0 <= (px + pw - cw)) { cx = px + pw - cw; } else { cx = px + (pw - cw) / 2; if (scsz.x <= (cx + cw)) { cx = scsz.x - cw - 1; } if (0 > cx) { cx = 0; } } } } c.SetSize(cx, cy, cw, ch); } } if (!done) { cx = px + (pw - cw) / 2; cy = py + (ph - ch) / 2; Dk4WxApplicationHelper::CorrectPosition(cx, cy, cw, ch); c.SetSize(cx, cy, cw, ch); } $? "- ChooseChildPosition" } size_t Dk4WxApplicationHelper::StringTableSize(const wxChar * const *sttptr) { size_t back = 0; $? "+ StringTableSize" if (NULL != sttptr) { while (NULL != *(sttptr++)) { back++; } } $? "- StringTableSize %lu", (unsigned long)back return back; } void Dk4WxApplicationHelper::ReleaseWxcharStringArray( wxChar **array, size_t sz, bool ea ) { wxChar **ap; if ((NULL != array) && (0 < sz)) { ap = array; while (0 < sz--) { dk4mem_release(*array); array++; } if (ea) { dk4mem_free(ap); } } }