/*============================ * mvcwaddnstr -- convert to GUI codeset & call mvwaddstr with length limit * Created: 2002/12/13 (Perry Rapp) *==========================*/ int mvccwaddnstr (WINDOW *wp, int y, int x, const char *cp, int n) { ZSTR zstr = zs_news(cp); int rtn=0; int_to_disp(zstr); if (zs_len(zstr) < (unsigned int)n) { rtn = mvwaddstr(wp, y, x, zs_str(zstr)); } else { if (output_width(zstr) > (size_t)n) { STRING str = zs_str(zstr); /* We need to do length truncation correctly for UTF-8 output */ /* #1) We need to not break UTF-8 multibytes */ INT width=0; STRING prev = find_prev_char(&str[n-1], &width, str, gui8); width += (prev - str); zs_chop(zstr, width); /* #2) We should account for zero-width characters, eg, use wcwidth */ /* Unfortunately, lifelines doesn't yet use wcwidth or config test it */ /* TODO: config test for wcswidth and substitute Markus Kuhn's http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c */ } rtn = mvwaddnstr(wp, y, x, zs_str(zstr), n); } zs_free(&zstr); return rtn; }
/*========================================================== * transl_get_predefined_menukey -- Menu key for predefined translation * (localized) *========================================================*/ ZSTR transl_get_predefined_menukey (INT trnum) { ASSERT(trnum>=0); ASSERT(trnum<ARRSIZE(conversions_keys)); return zs_news(sgettext(conversions_keys[trnum])); }
/*=================================================== * translate_string_to_zstring -- Translate string via TRANTABLE * xlat: [IN] translation to apply * in: [IN] string to translate * Created: 2001/07/19 (Perry Rapp) * Copied from translate_string, except this version * uses dynamic buffer, so it can expand if necessary *=================================================*/ ZSTR translate_string_to_zstring (XLAT xlat, CNSTRING in) { ZSTR zstr = zs_news(in); transl_xlat(xlat, zstr); return zstr; }
/*============================ * mvcwaddstr -- convert to GUI codeset & call mvwaddstr * Created: 2002/12/03 (Perry Rapp) * TODO: Convert all calls of this to call mvccuwaddstr (or mvccwaddnstr) ! *==========================*/ int mvccwaddstr (WINDOW *wp, int y, int x, const char *cp) { ZSTR zstr = zs_news(cp); int rtn; int_to_disp(zstr); rtn = mvwaddstr(wp, y, x, zs_str(zstr)); zs_free(&zstr); return rtn; }
/*============================ * wgetccnstr -- wgetnstr with codeset convert from GUI to internal * Created: 2002/12/03 (Perry Rapp) *==========================*/ int wgetccnstr (WINDOW *wp, char *cp, int n) { ZSTR zstr=0; /* TODO: Need Win32-specific code here to handle Unicode input on NT family */ int rtn = wgetnstr(wp, (char *)cp, n); zstr = zs_news(cp); disp_to_int(zstr); llstrsets(cp, n, uu8, zs_str(zstr)); zs_free(&zstr); return rtn; }
/*======================================================= * annotate_node -- Alter a node by * expanding refns (eg, "@S25@" to "<1850.Census>") * annotating pointers (eg, "@I1@" to "@I1@ {{ John/SMITH }}") * Used during editing *=====================================================*/ static void annotate_node (NODE node, BOOLEAN expand_refns, BOOLEAN annotate_pointers, RFMT rfmt) { STRING key=0; RECORD rec=0; key = value_to_xref(nval(node)); if (!key) return; rec = key_possible_to_record(key, *key); if (!rec) return; if (expand_refns) { NODE refn = REFN(nztop(rec)); char buffer[60]; /* if there is a REFN, and it fits in our buffer, and it doesn't have any (confusing) > in it */ if (refn && nval(refn) && !strchr(nval(refn), '>') && strlen(nval(refn))<=sizeof(buffer)-3) { /* then replace, eg, @S25@, with, eg, <1850.Census> */ buffer[0]=0; strcpy(buffer, "<"); strcat(buffer, nval(refn)); strcat(buffer, ">"); stdfree(nval(node)); nval(node) = strsave(buffer); } } if (annotate_pointers) { STRING str = generic_to_list_string(nztop(rec), key, 60, ", ", rfmt, FALSE); ZSTR zstr = zs_news(nval(node)); zs_apps(zstr, " {{"); zs_apps(zstr, str); zs_apps(zstr, " }}"); stdfree(nval(node)); nval(node) = strsave(zs_str(zstr)); zs_free(&zstr); } }
/*========================================================== * transl_get_predefined_name -- Fetch name of a predefined translation * eg, transl_get_predefined_name(MEDIN) == "editor-to-internal" * Created: 2002/12/13 (Perry Rapp) *========================================================*/ ZSTR transl_get_predefined_name (INT trnum) { return zs_news(_(getconvert(trnum)->name)); }
/*========================================== * do_zformat_date * See description above for do_format_date * (Except this returns alloc'd ZSTR *========================================*/ static ZSTR do_zformat_date (STRING str, INT dfmt, INT mfmt, INT yfmt, INT sfmt, INT efmt, INT cmplx) { STRING smo, syr; static char daystr[3]; GDATEVAL gdv = 0; ZSTR zstr=zs_newn(40); if (!str) return zstr; initialize_if_needed(); if (sfmt==12) { /* This is what used to be the shrt flag */ zs_free(&zstr); return zshorten_date(str); } if (sfmt==14) { zs_sets(zstr, str); return zstr; } if (!cmplx) { /* simple */ gdv = extract_date(str); if (gdv->valid == GDV_V_PHRASE) { /* GEDCOM date phrases (parenthesized) shown "as is" */ return zs_news(gdv->text); } format_day(gdv->date1.day, dfmt, daystr); smo = format_month(gdv->date1.calendar, gdv->date1.month, mfmt); syr = format_year(gdv->date1.year, yfmt); format_ymd(zstr, syr, smo, daystr, sfmt); format_eratime(zstr, gdv->date1.eratime, efmt); if (gdv->date1.calendar) { format_cal(zstr, gdv->date1.calendar); } free_gdateval(gdv); return zstr; } else { ZSTR zstr2 = zs_newn(40); ZSTR zstr3=0; /* complex (include modifier words) */ gdv = extract_date(str); if (gdv->valid == GDV_V_PHRASE) { /* GEDCOM date phrases (parenthesized) shown "as is" */ return zs_news(gdv->text); } format_day(gdv->date1.day, dfmt, daystr); smo = format_month(gdv->date1.calendar, gdv->date1.month, mfmt); syr = (gdv->date1.year.str ? gdv->date1.year.str : format_year(gdv->date1.year, yfmt)); format_ymd(zstr, syr, smo, daystr, sfmt); format_eratime(zstr, gdv->date1.eratime, efmt); if (gdv->date1.calendar) { format_cal(zstr, gdv->date1.calendar); } if (gdateval_isdual(gdv)) { /* build 2nd date string into ymd2 */ format_day(gdv->date2.day, dfmt, daystr); smo = format_month(gdv->date2.calendar, gdv->date2.month, mfmt); syr = (gdv->date2.year.str ? gdv->date2.year.str : format_year(gdv->date2.year, yfmt)); format_ymd(zstr2, syr, smo, daystr, sfmt); format_eratime(zstr2, gdv->date2.eratime, efmt); if (gdv->date2.calendar) { format_cal(zstr2, gdv->date2.calendar); } } zstr3 = format_complex(gdv, cmplx, zs_str(zstr), zs_str(zstr2)); zs_free(&zstr); zs_free(&zstr2); free_gdateval(gdv); return zstr3; } }
/*=================================================== * format_complex -- Format date string with modifiers * gdv: [IN] actual date_val * output: [I/O] whither to write string * len: [IN] size of output * cmplx: [IN] cmplx format code * 1=about (same as 8) * 3=ABT * 4=Abt * 5=ABOUT * 6=About * 7=abt * 8=about * ymd2: [IN] formatted date1 * ymd3: [IN] formatted date2 (only used for dual dates) * (ie, full period or full range) * Created: 2001/12/28 (Perry Rapp) *=================================================*/ static ZSTR format_complex (GDATEVAL gdv, INT cmplx , STRING ymd2, STRING ymd3) { STRING pic; ZSTR zstr=0; INT cmplxnum=cmplx-3; /* map cmplx to 0-5 */ if (cmplxnum<0 || cmplxnum>5) cmplxnum=5; switch (gdv->type) { case GDV_PERIOD: switch (gdv->subtype) { case GDVP_FROM: pic = get_cmplx_pic(ECMPLX_FROM, cmplxnum); zstr = zprintpic1(pic, ymd2); break; case GDVP_TO: pic = get_cmplx_pic(ECMPLX_TO, cmplxnum); zstr = zprintpic1(pic, ymd2); break; case GDVP_FROM_TO: pic = get_cmplx_pic(ECMPLX_FROM_TO, cmplxnum); zstr = zprintpic2(pic, ymd2, ymd3); break; default: FATAL(); /* invalid period subtype */ break; } break; case GDV_RANGE: switch (gdv->subtype) { case GDVR_BEF: pic = get_cmplx_pic(ECMPLX_BEF, cmplxnum); zstr = zprintpic1(pic, ymd2); break; case GDVR_AFT: case GDVR_BET: /* BET with no AND is treated as AFT */ pic = get_cmplx_pic(ECMPLX_AFT, cmplxnum); zstr = zprintpic1(pic, ymd2); break; case GDVR_BET_AND: pic = get_cmplx_pic(ECMPLX_BET_AND, cmplxnum); zstr = zprintpic2(pic, ymd2, ymd3); break; default: FATAL(); /* invalid period subtype */ break; } break; case GDV_APPROX: switch (gdv->subtype) { case GDVA_ABT: pic = get_cmplx_pic(ECMPLX_ABT, cmplxnum); zstr = zprintpic1(pic, ymd2); break; case GDVA_EST: pic = get_cmplx_pic(ECMPLX_EST, cmplxnum); zstr = zprintpic1(pic, ymd2); break; case GDVA_CAL: pic = get_cmplx_pic(ECMPLX_CAL, cmplxnum); zstr = zprintpic1(pic, ymd2); break; } break; case GDV_DATE: default: zstr = zs_news(ymd2); break; } return zstr; }