diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/Dk4WxApplicationHelper.cpt |
Initial commit
Diffstat (limited to 'support/dktools/Dk4WxApplicationHelper.cpt')
-rw-r--r-- | support/dktools/Dk4WxApplicationHelper.cpt | 2677 |
1 files changed, 2677 insertions, 0 deletions
diff --git a/support/dktools/Dk4WxApplicationHelper.cpt b/support/dktools/Dk4WxApplicationHelper.cpt new file mode 100644 index 0000000000..f81e068a47 --- /dev/null +++ b/support/dktools/Dk4WxApplicationHelper.cpt @@ -0,0 +1,2677 @@ +%% 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 <wx/config.h> +#define WX_CONFIG_H_INCLUDED 1 +#endif + +#ifndef WX_FILENAME_H_INCLUDED +#include <wx/filename.h> +#define WX_FILENAME_H_INCLUDED 1 +#endif + +#ifndef WX_THREAD_H_INCLUDED +#include <wx/thread.h> +#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<br> + if dptr or sptr is NULL or dsz is 0, + - DK4_E_BUFFER_TOO_SMALL<br> + if dptr is too small, + - DK4_E_SYNTAX<br> + 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<br> + if dptr or sptr is NULL or dsz is 0, + - DK4_E_BUFFER_TOO_SMALL<br> + if dptr is too small, + - DK4_E_SYNTAX<br> + 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<br> + 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<br> + if the function failed to find the current working directory, + - DK4_E_SYNTAX<br> + if there are string conversion problems, + - DK4_E_BUFFER_TOO_SMALL<br> + 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<br> + if a Windows registry entry differs from the expected type. + - DK4_E_MATH_OVERFLOW<br> + if a numeric overflow occured in a memory allocation size + calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + 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<br> + if dptr or sptr is NULL or dsz is 0, + - DK4_E_BUFFER_TOO_SMALL<br> + if dptr is too small, + - DK4_E_SYNTAX<br> + 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<br> + if dptr or sptr is NULL or dsz is 0, + - DK4_E_BUFFER_TOO_SMALL<br> + if dptr is too small, + - DK4_E_SYNTAX<br> + 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<br> + if dptr or sptr is NULL or dsz is 0, + - DK4_E_BUFFER_TOO_SMALL<br> + if dptr is too small, + - DK4_E_SYNTAX<br> + 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); } + } +} + |