%% options copyright owner = Dirk Krause copyright year = 2011-xxxx license = bsd %% header #if 0 #include #else #include #include #include #endif #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #include #include /** Application helper class, provides file search, internationalization and some functions for GUI development using the wxWidgets libraries. */ class DkWxAppHelper { protected: /** Application structure. */ dk3_app_t *app; /** Storage for string tables. */ dk3_sto_t *sStringTables; /** Iterator through string tables storage. */ dk3_sto_it_t *iStringTables; /** Basic strings used by wxWidgets applications. */ wxChar const * const *basicStrings; /** First command line argument. */ wxChar const *cmdName; /** Application name. */ wxChar const *appName; /** Software vendor name. */ wxChar const *vendorName; /** Number of entries in the basicStrings array. */ size_t nBasicStrings; /** Encoding for dkChar. */ int dkEncoding; /** Encoding for wxChar. */ int wxEncoding; /** Code for errors from constructor. */ int errorCode; protected: /** Report problems within the constructor, if any. */ void reportProblemsIfAny(void); /** Show an error message. @param i_title Index of dialog title in basic strings. @param i_text Index of message text in basic strings. */ void showErrorMessage(size_t i_title, size_t i_text); public: /** Constructor. @param arg0 First command line argument. @param vName Software vendor name. @param groupName Application group name. */ DkWxAppHelper( wxChar const *arg0, wxChar const *vName, dkChar const *groupName ); /** Destructor. */ ~DkWxAppHelper(); /** Check whether application helper object is set up correctly and is ready to use. @return 1 on success, 0 on error. */ int checkSetup() const; /** Retrieve array of localized texts. @param dt Default texts, used if problems occur. @param tn Table name. @return Pointer to localized messages array or dt. */ wxChar const * const * getStringTable( wxChar const * const *dt, dkChar const *tn ); /** Find data file name. Provide a short file name like "x.y", on success the program writes a full path like "/usr/share/myapp/en/x.y" to the result buffer. @param fn Short file name. @param fnb Buffer for full path name. @param szfnb Size of @arg fnb (number of wxChar). @return 1 on success, 0 on error. */ int findDataFile(wxChar const *fn, wxChar *fnb, size_t szfnb); /** Retrieve multiple int settings at once. @param names Pointer to names array, must be terminated by a NULL pointer. @param values Pointer to destination value array. @return Number of items read successfully. */ size_t retrieveMultipleInts( wxChar const * const *names, int *values ) const; /** Retrieve multiple long settings at once. @param names Pointer to names array, must be terminated by a NULL pointer. @param values Pointer to destination value array. @return Number of items read successfully. */ size_t retrieveMultipleLongs( wxChar const * const *names, long *values ) const; /** Save multiple int settings at once. @param names Pointer to names array, must be terminated by a NULL pointer. @param values Pointer to values array. @return Number of items successfully written. */ size_t saveMultipleInts( wxChar const * const *names, int *values ) const; /** Save multiple long settings at once. @param names Pointer to names array, must be terminated by a NULL pointer. @param values Pointer to values array. @return Number of items successfully written. */ size_t saveMultipleLongs( wxChar const * const *names, long *values ) const; /** Retrieve multiple double settings at once. @param names Pointer to names array, must be terminated by a NULL pointer. @param values Pointer to values array. @return Number of items successfully read. */ size_t retrieveMultipleDoubles( wxChar const * const *names, double *values ) const; /** Save multiple doubles at once. @param names Pointer to names array, must be terminated by a NULL pointer. @param values Pointer to values array. @return Number of items successfully written. */ size_t saveMultipleDoubles( wxChar const * const *names, double *values ) const; /** Retrieve a string preference. @param name Preference name. @return Pointer to new string on success, NULL on error. */ wxChar const * retrieveString( wxChar const *name ) const; /** Save a string entry. @param name Entry name. @param value Entry value. @return 1 on success, 0 on error. */ int saveString( wxChar const *name, wxChar const *value ) const; /** Retrieve encoding for wxChar. @return Encoding used for wxChar. */ int getWxEncoding() const; /** Retrieve encoding for dkChar. @return Encoding used for dkChar. */ int getDkEncoding() const; /** Retrieve encoding to use for 8 bit characters. @return Encoding to use for 8 bit character strings. */ int getC8Encoding() const; /** Retrieve application structure. @return Application structure on success, NULL on error. */ dk3_app_t * getApp() const; /** Get one of the basic application strings. @param i Index of string in array. @return String pointer on success or NULL on error. */ wxChar const * getBasicString(size_t i) const; /** Get basic strings array. @return Array pointer to basic strings. */ wxChar const * const * getBasicStrings() const; /** Find number of basic strings stored in the \a basicStrings array. @return Number of strings in the array. */ size_t getBasicStringNumbers() const; /** Convert wxChar string to dkChar string. @param bu Destination buffer. @param sz Destination buffer size (number of dkChar). @param src Source buffer. @return true on success, false on error. */ bool wxToDk(dkChar *bu, size_t sz, wxChar const *src) const; /** Convert wxChar string to 8-bit char string. @param bu Destination buffer. @param sz Destination buffer size. @param src Source buffer. @return true on success, false on error. */ bool wxToC8(char *bu, size_t sz, wxChar const *src) const; /** Convert wxChar string to 8-bit char string. @param bu Destination buffer. @param sz Destination buffer size. @param str Source string. @return true on success, false on error. */ bool wxToC8(char *bu, size_t sz, wxString & str) const; /** Convert dkChar string to wxChar string. @param bu Destination buffer. @param sz Destination buffer size (number of wxChar). @param src Source buffer. @return true on success, false on error. */ bool dkToWx(wxChar *bu, size_t sz, dkChar const *src) const; /** Set related position (child over parent), the child is either placed on a known previous position or placed centered on top of the parent. @param parent Parent top level window (frame). @param child Child top level window (dialog). @param pcx Pointer to previous child x position. @param pcy Pointer to previous child y position. */ void setRelatedPosition( wxWindow *parent, wxWindow *child, int *pcx = NULL, int *pcy = NULL ) const; }; %% module #include #include "DkWxAppHelper.h" #include "dk3wxs.h" $!trace-include /** Storage entry for wxChar string table. */ typedef struct { wxChar const **array; /**< String table contents. */ dkChar const *name; /**< String table name. */ size_t nelem; /**< Number of elements. */ } DkAppHelperWxStringTable; /** Pointer to constant wxChar string. */ typedef wxChar const *wxConstPtr; /** Error codes. */ enum { /** No error occured. */ ERROR_NONE = 0, /** Failed to encode arg0 to dkChar. */ ERROR_ENCODE_ARG0 , }; /** Basic texts issued by wxWidgets applications. */ static wxChar const * const dkwxapphelper_defwxappstr[] = { $!string-table macro=wxT # # 0: Log level: Worse than panic # Error worse than Panic # # 1: Log level: Panic # Panic # # 2: Log level: Fatal error # Fatal error # # 3: Log level: Error # Error # # 4: Log level: Warning # Warning # # 5: Log level: Information # Information # # 6: Log level: Progress message # Progress # # 7: Log level: Debug message # Debug # # 8: Log level: Ignore message # Ignore # # 9: Error: Not enough memory! # Not enough memory! # # 10: Error: Help file not found! # Help file not found! # # 11: Error: Failed to initialize application structure! # Failed to initialize application structure! # # 12: Error: Failed to recode command line! # Failed to recode command line! $!end }; /** String table file containing localized versions of the texts in \a dkwxapphelper_defwxappstr. */ static dkChar const dkwxapphelper_sttname[] = { dkT("dkwx.str") }; /** Compare two string table entries. @param l Left entry. @param r Right entry. @param cr Comparison criteria (0=entry/entry, 1=entr/name). @return Comparison result. */ static int dkwxah_string_table_compare(void const *l, void const *r, int cr) { int back = 0; DkAppHelperWxStringTable const *pl; DkAppHelperWxStringTable const *pr; if(l) { if(r) { pl = (DkAppHelperWxStringTable const *)l; pr = (DkAppHelperWxStringTable const *)r; switch(cr) { case 1: { if(pl->name) { back = dk3str_cmp(pl->name, (dkChar const *)r); } else { back = -1; } } break; default: { if(pl->name) { if(pr->name) { back = dk3str_cmp(pl->name, pr->name); } else { back = 1;} } else { if(pr->name) { back = -1; } } } break; } } else { back = 1; } } else { if(r) { back = -1; } } if(back < -1) { back = -1; } if(back > 1) { back = 1; } return back; } /** Close string table. @param p String table to close. */ static void dkwxah_string_table_close(DkAppHelperWxStringTable *p) { wxChar const **ptr; size_t i; $? "+ dkwxah_string_table_close PTR=%d", TR_IPTR(p) if(p) { if(p->array) { if(p->nelem) { $? ". %lu elements", (unsigned long)(p->nelem) ptr = p->array; for(i = 0; i < p->nelem; i++) { if(*ptr) { $? ". delete element %lu", (unsigned long)i } dk3_release(*ptr); ptr++; } } dk3_delete(p->array); } dk3_release(p->name); dk3_delete(p); } $? "- dkwxah_string_table_close" } #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /** Separator character for file names. */ #define SEP wxT('\\') #else /** Separator character for file names. */ #define SEP wxT('/') #endif /** Non-localized keywords, 8-bit characters. */ static char const * const dkwxapphelper_c8_kw[] = { /* 0 */ "UTF-8", /* 1 */ "utf8", NULL }; DkWxAppHelper::DkWxAppHelper( wxChar const *arg0, wxChar const *vName, dkChar const *groupName ) { dkChar dkcb[DK3_MAX_PATH]; dkChar *newargv[2]; wxChar *ptr; wxChar const *cptr; wxChar const * const *ptrGetNumBasicStrings; $? "+ DkWxAppHelper::DkWxAppHelper" newargv[0] = NULL; app = NULL; sStringTables = NULL; iStringTables = NULL; basicStrings = NULL; nBasicStrings = 0; cmdName = NULL; appName = NULL; vendorName = NULL; errorCode = ERROR_NONE; dkEncoding = DK3_ENCODING_PLAIN; wxEncoding = DK3_ENCODING_PLAIN; if(DK3_CHAR_SIZE > 1) { if(DK3_CHAR_SIZE > 2) { dkEncoding = DK3_ENCODING_UNICODE; } else { dkEncoding = DK3_ENCODING_UTF16; } } else { /* dkChar is 1 byte. */ #if DK3_ON_WINDOWS #else char *ptr; ptr = getenv("LANG"); if(ptr) { ptr = dk3str_c8_chr(ptr, '.'); if(ptr) { ptr++; if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[0], ptr) == 0) { dkEncoding = DK3_ENCODING_UTF8; } else { if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[1], ptr) == 0) { dkEncoding = DK3_ENCODING_UTF8; } } } } #endif } if(sizeof(wxChar) > 1) { if(sizeof(wxChar) > 2) { wxEncoding = DK3_ENCODING_UNICODE; } else { wxEncoding = DK3_ENCODING_UTF16; } } else { #if DK3_ON_WINDOWS #else char *ptr; ptr = getenv("LANG"); if(ptr) { ptr = dk3str_c8_chr(ptr, '.'); if(ptr) { ptr++; if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[0], ptr) == 0) { wxEncoding = DK3_ENCODING_UTF8; } else { if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[1], ptr) == 0) { wxEncoding = DK3_ENCODING_UTF8; } } } } #endif } if(dk3wxs_to_dkstr(dkcb,DK3_SIZEOF(dkcb,dkChar),dkEncoding,arg0,wxEncoding)) { newargv[0] = dkcb, newargv[1] = 0; app = dk3app_open_gui(1, newargv, groupName); if(app) { sStringTables = dk3sto_open_app(app); if(sStringTables) { dk3sto_set_comp(sStringTables, dkwxah_string_table_compare, 0); iStringTables = dk3sto_it_open(sStringTables); if(iStringTables) { } } } } else { errorCode = ERROR_ENCODE_ARG0; } cmdName = dk3wxs_dup_app(arg0, app); if(cmdName) { cptr = dk3wxs_rchr(cmdName, SEP); if(cptr) { cptr++; } else { cptr = cmdName; } appName = dk3wxs_dup_app(cptr, app); if(appName) { ptr = dk3wxs_rchr(appName, '.'); if(ptr) { *ptr = wxT('\0'); } } } vendorName = dk3wxs_dup_app(vName, app); /* Finally retrieve the basic application strings. */ ptrGetNumBasicStrings = dkwxapphelper_defwxappstr; while(*(ptrGetNumBasicStrings++)) { nBasicStrings++; } basicStrings = getStringTable( dkwxapphelper_defwxappstr, dkwxapphelper_sttname ); reportProblemsIfAny(); $? "- DkWxAppHelper::DkWxAppHelper" } DkWxAppHelper::~DkWxAppHelper() { $? "+ DkWxAppHelper::~DkWxAppHelper" DkAppHelperWxStringTable *e; basicStrings = NULL; if(sStringTables) { if(iStringTables) { dk3sto_it_reset(iStringTables); do { e = (DkAppHelperWxStringTable *)dk3sto_it_next(iStringTables); if(e) { dkwxah_string_table_close(e); } } while(e != NULL); dk3sto_it_close(iStringTables); } dk3sto_close(sStringTables); } sStringTables = NULL; iStringTables = NULL; if(app) { dk3app_close(app); app = NULL; } dk3_release(cmdName); dk3_release(appName); dk3_release(vendorName); $? "- DkWxAppHelper::~DkWxAppHelper" } int DkWxAppHelper::checkSetup() const { int back = 0; $? "+ DkWxAppHelper::checkSetup" if(app) { $? ". app ok" if(sStringTables) { $? ". string table storage ok" if(iStringTables) { $? ". string table iterator ok" if(cmdName) { $? ". cmdName ok" if(appName) { $? ". appName ok" if(vendorName) { $? ". vendorName ok" back = 1; } else { $? "! vendorName" } } else { $? "! appName" } } else { $? "! cmdName" } } else { $? "! string table iterator" } } else { $? "! string table storage" } } else { $? "! app" } $? "- DkWxAppHelper::checkSetup %d", back return back; } wxChar const * const * DkWxAppHelper::getStringTable( wxChar const * const *dt, dkChar const *tn ) { #if 0 wxChar const * const *back = NULL; wxChar const * *wxptr; DkAppHelperWxStringTable *tp = NULL; FILE *fipo = NULL; dkChar const *oldsource = NULL; #if 0 dkChar dkb[4096]; #endif dkChar fnb[DK3_MAX_PATH]; wxChar wxb[4096]; char il[4096]; unsigned long lineno = 0UL; unsigned long oldline = 0UL; size_t nelem = 0; size_t i = 0; int cc = 1; int ok = 0; $? "+ DkWxAppHelper::getStringTable \"%!ds\"", TR_STR(tn) if((dt) && (tn)) { $? ". args ok" if(checkSetup()) { $? ". setup ok" tp = (DkAppHelperWxStringTable *)dk3sto_it_find_like( iStringTables, (void *)tn, 1 ); if(!(tp)) { $? ". must read from file" if(dk3app_find_data_file(app, tn, fnb, DK3_SIZEOF(fnb,dkChar))) { $? ". find" fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app); if(fipo) { $? ". fopen ok" wxptr = (wxChar const **)dt; nelem = 0; while(*(wxptr++)) { nelem++; } if(nelem) { $? ". have %lu elements", (unsigned long)nelem tp = dk3_new_app(DkAppHelperWxStringTable,1,app); if(tp) { $? ". allocation ok" ok = 0; tp->array = NULL; tp->nelem = nelem; tp->name = dk3str_dup_app(tn, app); if(tp->name) { $? ". dup ok for name" tp->array = dk3_new_app(wxConstPtr,nelem,app); if(tp->array) { $? ". array allocation ok" wxptr = tp->array; tp->nelem = nelem; for(i = 0; i < nelem; i++) { *(wxptr++) = NULL; } if(dk3sto_add(sStringTables, (void *)tp)) { $? ". add ok" ok = 1; oldsource = dk3app_get_source_file(app); oldline = dk3app_get_source_line(app); dk3app_set_source_file(app, fnb); dk3app_set_source_line(app, 0UL); lineno = 0UL; wxptr = tp->array; nelem = 0; do { $? ". loop start" cc = 0; if(fgets(il, sizeof(il), fipo)) { $? ". line ok" dk3app_set_source_line(app, ++lineno); cc = 1; if(il[0] != '#') { $? ". no comment" dk3app_squeeze_line(il); if(dk3wxs_from_utf8(wxb,DK3_SIZEOF(wxb,wxChar),il)) { *wxptr = dk3wxs_dup_app(wxb, app); if(!(*wxptr)) { $? "! dup failed" ok = 0; } wxptr++; } else { ok = 0; $? "! conversion failed" } } else { $? ". comment line" } if(nelem >= tp->nelem) { cc = 0; } } else { $? "! no more lines" } } while((cc) && (ok)); if(nelem < tp->nelem) { ok = 0; } dk3app_set_source_file(app, oldsource); dk3app_set_source_line(app, oldline); } else { $? "! add failed" } } else { $? "! array allocation failed" } } else { $? "! dup failed for name" } if(ok) { back = (wxChar const * const *)(tp->array); } else { dkwxah_string_table_close(tp); } } else { $? "! allocation failed" } } else { $? "! defaults array empty" } fclose(fipo); } else { $? "! fopen" } } else { $? "! not found" } } else { $? ". found in storage" } if(tp) { $? ". have entry" back = (wxChar const * const *)(tp->array); } } else { $? "! setup" } } else { $? "! args" } if(!(back)) { back = dt; } $? "- DkWxAppHelper::getStringTable PTR=%d", TR_IPTR(back) #else dkChar fnb[DK3_MAX_PATH]; /* Full file name. */ char il[4096]; /* Input line */ wxChar wxb[sizeof(il)]; wxChar const * const *back = NULL; DkAppHelperWxStringTable *tp; /* String table if exists. */ wxChar const * *wxptr; /* Traverse dt array. */ FILE *fipo; /* Read input file. */ #if VERSION_BEFORE_20150821 unsigned long lineno; /* Current line. */ #endif size_t nelem; /* Number of elements in dt. */ size_t i; /* Current string to process. */ int res; /* Search result. */ int cc; /* Flag: Can continue. */ int ok; /* Flag: All strings read succes. */ $? "+ getStringTable" if((dt) && (tn)) { $? ". args ok" if(checkSetup()) { $? ". controller setup ok" tp = (DkAppHelperWxStringTable *)dk3sto_it_find_like( iStringTables, (void *)tn, 1 ); if(!(tp)) { $? ". table not yet found, must read" res = dk3app_find_data_file(app,tn,fnb,DK3_SIZEOF(fnb,dkChar)); $? ". res = %d", res if(res) { $? ". file found" fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app); if(fipo) { $? ". file opened" wxptr = (wxChar const **)dt; nelem = 0; while(*(wxptr++)) { nelem++; } if(nelem) { tp = dk3_new_app(DkAppHelperWxStringTable,1,app); if(tp) { tp->array = NULL; tp->nelem = nelem; tp->name = NULL; tp->name = dk3str_dup_app(tn, app); if(tp->name) { tp->array = dk3_new_app(wxConstPtr,nelem,app); if(tp->array) { wxptr = tp->array; tp->nelem = nelem; for(i = 0; i < nelem; i++) { *(wxptr++) = NULL; } wxptr = tp->array; nelem = 0; #if VERSION_BEFORE_20150821 lineno = 0UL; #endif #if VERSION_BEFORE_20150821 cc = 1; #endif ok = 1; do { cc = 0; if(fgets(il, sizeof(il), fipo)) { cc = 1; $? ". line \"%!8s\"", il if(il[0] != '#') { $? ". no comment" dk3app_squeeze_line(il); if(dk3wxs_from_utf8(wxb,DK3_SIZEOF(wxb,wxChar),il)) { *wxptr = dk3wxs_dup_app(wxb, app); if(*wxptr) { nelem++; if(nelem >= tp->nelem) { cc = 0; } } else { ok = 0; cc = 0; } wxptr++; } else { $? "! conversion failed" ok = 0; cc = 0; } } else { $? ". comment" } } } while(cc); if(nelem < tp->nelem) { ok = 0; $? "! too few elements" } if(ok) { $? ". success so far" if(!dk3sto_add(sStringTables, (void *)tp)) { dkwxah_string_table_close(tp); $? "! memory" tp = NULL; } } else { $? "! anything wrong" dkwxah_string_table_close(tp); tp = NULL; } } else { dkwxah_string_table_close(tp); tp = NULL; } } else { dkwxah_string_table_close(tp); tp = NULL; } } else { $? "! memory" } } fclose(fipo); } else { $? "! failed to open file" } } else { $? "! file not found" } } if(tp) { $? ". table found" back = (wxChar const * const *)(tp->array); } } else { $? "! controller setup not ok" } } else { $? "! invalid args" } if(!(back)) { $? "! no result, using default texts" back = dt; } $? "- getStringTable PTR=%d", TR_IPTR(back) #endif return back; } size_t DkWxAppHelper::retrieveMultipleInts( wxChar const * const *names, int *values ) const { size_t back = 0; wxChar const * const *nptr; int *vptr; long l; $? "+ DkWxAppHelper::retrieveMultipleInts" if((appName) && (vendorName) && (names) && (values)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { nptr = names; vptr = values; while(*nptr) { l = 0L; if(conf->Read(*nptr, &l)) { *vptr = (int)l; back++; } nptr++; vptr++; } delete(conf); } } $? "- DkWxAppHelper::retrieveMultipleInts %lu", (unsigned long)back return back; } size_t DkWxAppHelper::retrieveMultipleLongs( wxChar const * const *names, long *values ) const { size_t back = 0; wxChar const * const *nptr; long *vptr; long l; $? "+ DkWxAppHelper::retrieveMultipleLongs" if((appName) && (vendorName) && (names) && (values)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { nptr = names; vptr = values; while(*nptr) { l = 0L; if(conf->Read(*nptr, &l)) { *vptr = l; back++; } nptr++; vptr++; } delete(conf); } } $? "- DkWxAppHelper::retrieveMultipleLongs %u", (unsigned)back return back; } size_t DkWxAppHelper::retrieveMultipleDoubles( wxChar const * const *names, double *values ) const { size_t back = 0; double d; wxChar const * const *nptr; double *vptr; $? "+ DkWxAppHelper::retrieveMultipleDoubles" if((appName) && (vendorName) && (names) && (values)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { nptr = names; vptr = values; while(*nptr) { d = 0.0; if(conf->Read(*nptr, &d)) { *vptr = d; back++; } nptr++; vptr++; } delete(conf); } } $? "- DkWxAppHelper::retrieveMultipleDoubles %u", (unsigned)back return back; } size_t DkWxAppHelper::saveMultipleInts( wxChar const * const *names, int *values ) const { size_t back = 0; wxChar const * const *nptr; int *vptr; long l; $? "+ DkWxAppHelper::saveMultipleInts" if((appName) && (vendorName) && (names) && (values)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { $? ". conf ok" nptr = names; vptr = values; while(*nptr) { $? ". write entry" l = (long)(*vptr); if(conf->Write(*nptr, l)) { back++; } nptr++; vptr++; } delete(conf); } } $? "- DkWxAppHelper::saveMultipleInts %lu", (unsigned long)back return back; } size_t DkWxAppHelper::saveMultipleLongs( wxChar const * const *names, long *values ) const { size_t back = 0; wxChar const * const *nptr; long *vptr; long l; $? "+ DkWxAppHelper::saveMultipleLongs" if((appName) && (vendorName) && (names) && (values)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { nptr = names; vptr = values; while(*nptr) { l = *vptr; if(conf->Write(*nptr, l)) { back++; } nptr++; vptr++; } delete(conf); } } $? "- DkWxAppHelper::saveMultipleLongs %u", (unsigned)back return back; } size_t DkWxAppHelper::saveMultipleDoubles( wxChar const * const *names, double *values ) const { size_t back = 0; double d; wxChar const * const *nptr; double *vptr; $? "+ DkWxAppHelper::saveMultipleDoubles" if((appName) && (vendorName) && (names) && (values)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { nptr = names; vptr = values; while(*nptr) { d = *vptr; if(conf->Write(*nptr, d)) { back++; } nptr++; vptr++; } delete(conf); } } $? "- DkWxAppHelper::saveMultipleDoubles %u", (unsigned)back return back; } wxChar const * DkWxAppHelper::retrieveString( wxChar const *name ) const { wxChar const *back = NULL; wxChar const *ptr; $? "+ DkWxAppHelper::retrieveString" if((name) && (appName) && (vendorName)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { wxString str; if(conf->Read(name, &str)) { ptr = str.c_str(); if(ptr) { back = dk3wxs_dup_app(ptr, app); } } delete(conf); } } $? "- DkWxAppHelper::retrieveString PTR=%d", TR_IPTR(back) return back; } int DkWxAppHelper::saveString( wxChar const *name, wxChar const *value ) const { int back = 0; $? "+ DkWxAppHelper::saveString" if((name) && (value) && (appName) && (vendorName)) { wxConfig *conf = new wxConfig(appName, vendorName); if(conf) { conf->Write(name, value); delete(conf); } } $? "- DkWxAppHelper::saveString %d", back return back; } int DkWxAppHelper::getWxEncoding() const { $? "= getWxEncoding %d", wxEncoding return wxEncoding; } int DkWxAppHelper::getDkEncoding() const { $? "= getDkEncoding %d", dkEncoding return dkEncoding; } int DkWxAppHelper::getC8Encoding() const { int back; $? "+ DkWxAppHelper::getC8Encoding" back = dkEncoding; if(DK3_ENCODING_UTF8 != back) { back = DK3_ENCODING_PLAIN; } $? "- DkWxAppHelper::getC8Encoding %d", back return back; } dk3_app_t * DkWxAppHelper::getApp() const { $? "= DkWxAppHelper::getApp PTR=%d", TR_IPTR(app) return app; } int DkWxAppHelper::findDataFile(wxChar const *fn, wxChar *fnb, size_t szfnb) { dkChar shnDk[DK3_MAX_PATH]; dkChar ffnDk[DK3_MAX_PATH]; int back = 0; $? "+ findDataFile" if((fn) && (fnb) && (szfnb)) { $? ". args ok" if(checkSetup()) { $? ". setup ok" if(dk3wxs_to_dkstr( shnDk, DK3_SIZEOF(shnDk,dkChar), dkEncoding, fn, wxEncoding ) ) { if(app) { $? ". app available" if(dk3app_find_data_file(app,shnDk,ffnDk,DK3_SIZEOF(ffnDk,dkChar))) { if(dk3wxs_from_dkstr(fnb, szfnb, wxEncoding, ffnDk, dkEncoding)) { back = 1; $? ". found" } else { $? "! conversion failed" } } else { $? "! not found" } } else { $? "! no app" } } else { $? "! conversion failed" } } } $? "- findDataFile %d", back return back; } wxChar const * DkWxAppHelper::getBasicString(size_t i) const { wxChar const *back = NULL; $? "+ DkWxAppHelper::getBasicString" if(basicStrings) { if(i < nBasicStrings) { back = basicStrings[i]; } } $? "- DkWxAppHelper::getBasicString PTR=%d", TR_IPTR(back) return back; } wxChar const * const * DkWxAppHelper::getBasicStrings() const { $? "= DkWxAppHelper::getBasicStrings PTR=%d", TR_IPTR(basicStrings) return basicStrings; } size_t DkWxAppHelper::getBasicStringNumbers() const { $? "= DkWxAppHelper::getBasicStringNumbers %u", (unsigned)nBasicStrings return nBasicStrings; } bool DkWxAppHelper::wxToDk(dkChar *bu, size_t sz, wxChar const *src) const { bool back = false; $? "+ DkWxAppHelper::wxToDk" if((bu) && (sz) && (src)) { if(dk3wxs_to_dkstr(bu, sz, dkEncoding, src, wxEncoding)) { back = true; } } $? "- DkWxAppHelper::wxToDk %d", ((back) ? 1 : 0) return back; } bool DkWxAppHelper::wxToC8(char *bu, size_t sz, wxChar const *src) const { bool back = false; $? "+ DkWxAppHelper::wxToC8" if((bu) && (sz) && (src)) { if(dk3wxs_to_c8(bu, sz, getC8Encoding(), src, wxEncoding)) { back = true; } } $? "- DkWxAppHelper::wxToC8 %d", (back ? 1 : 0) return back; } bool DkWxAppHelper::wxToC8(char *bu, size_t sz, wxString & str) const { bool back = false; wxChar const *ptr; $? "+ DkWxAppHelper::wxToC8" if((bu) && (sz)) { ptr = str.c_str(); if(ptr) { back = wxToC8(bu, sz, ptr); } } $? "- DkWxAppHelper::wxToC8 %d", ((back) ? 1 : 0) return back; } bool DkWxAppHelper::dkToWx(wxChar *bu, size_t sz, dkChar const *src) const { bool back = false; $? "+ DkWxAppHelper::dkToWx" if((bu) && (sz) && (src)) { if(dk3wxs_from_dkstr(bu, sz, wxEncoding, src, dkEncoding)) { back = true; } } $? "- DkWxAppHelper::dkToWx %d", ((back) ? 1 : 0) return back; } void DkWxAppHelper::setRelatedPosition( wxWindow *parent, wxWindow *child, int *pcx, int *pcy ) const { int px = 0; /* Parent x position. */ int py = 0; /* Parent y position. */ int pw = 0; /* Parent width. */ int ph = 0; /* Parent height. */ int cx = 0; /* Child x position. */ int cy = 0; /* Child y position. */ int cw = 0; /* Child width. */ int ch = 0; /* Child height. */ wxSize scsz; /* Screen size. */ scsz = wxGetDisplaySize(); parent->GetPosition(&px, &py); parent->GetSize(&pw, &ph); child->GetSize(&cw, &ch); cx = px + (pw - cw) / 2; cy = py + (ph - ch) / 2; if((cx + cw) > scsz.x) { cx = scsz.x - cw; } if((cy + ch) > scsz.y) { cy = scsz.y - ch; } if(cx < 0) { cx = 0; } if(cy < 0) { cy = 0; } if((pcx) && (pcy)) { if(((*pcx) >= 0) && ((*pcy) >= 0)) { cx = *pcx; cy = *pcy; } } child->SetSize(cx, cy, cw, ch); } void DkWxAppHelper::reportProblemsIfAny(void) { bool didReport = false; if (!didReport) { if (NULL == app) { didReport = true; switch (errorCode) { case ERROR_ENCODE_ARG0 : { /* ERROR: Failed to encode arg0 to dkChar */ showErrorMessage(3, 12); } break; default : { /* ERROR: Failed to initialize application structure */ showErrorMessage(3, 11); } break; } } } if (!didReport) { if (NULL != app) { if ((NULL == sStringTables) || (NULL == iStringTables)) { didReport = true; /* ERROR: Memory */ showErrorMessage(3, 9); } } } if (!didReport) { if ((NULL == cmdName) || (NULL == appName) || (NULL == vendorName)) { didReport = true; /* ERROR: Memory */ showErrorMessage(3, 9); } } } void DkWxAppHelper::showErrorMessage(size_t i_title, size_t i_text) { const wxChar *str_title = NULL; const wxChar *str_text = NULL; if (NULL != basicStrings) { str_title = basicStrings[i_title]; str_text = basicStrings[i_text]; } else { str_title = dkwxapphelper_defwxappstr[i_title]; str_text = dkwxapphelper_defwxappstr[i_text]; } wxMessageBox(str_text, str_title, (wxOK | wxCENTRE | wxICON_ERROR)); }