diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp index 4001bd9d404786bdf44b5392f9f87e356902ade9..d109abfdcf85895eb6cc5fab53d675bf50515c53 100644 --- a/src/sbbs3/atcodes.cpp +++ b/src/sbbs3/atcodes.cpp @@ -61,6 +61,7 @@ int sbbs_t::show_atcode(const char *instr) bool zero_padded=false; bool truncated = true; bool doubled = false; + long pmode = 0; const char *cp; SAFECOPY(str,instr); @@ -96,7 +97,7 @@ int sbbs_t::show_atcode(const char *instr) *p=0; } - cp=atcode(sp,str2,sizeof(str2)); + cp = atcode(sp, str2, sizeof(str2), &pmode); if(cp==NULL) return(0); @@ -111,32 +112,38 @@ int sbbs_t::show_atcode(const char *instr) disp_len = (cols - 1) - column; } } + if(pmode & P_UTF8) { + if(term_supports(UTF8)) + disp_len += strlen(cp) - utf8_str_total_width(cp); + else + disp_len += strlen(cp) - utf8_str_count_width(cp, /* min: */1, /* max: */2); + } if(padded_left) - bprintf("%-*.*s",disp_len,disp_len,cp); + bprintf(pmode, "%-*.*s",disp_len,disp_len,cp); else if(padded_right) - bprintf("%*.*s",disp_len,disp_len,cp); + bprintf(pmode, "%*.*s",disp_len,disp_len,cp); else if(centered) { int vlen = strlen(cp); if(vlen < disp_len) { int left = (disp_len - vlen) / 2; - bprintf("%*s%-*s", left, "", disp_len - left, cp); + bprintf(pmode, "%*s%-*s", left, "", disp_len - left, cp); } else - bprintf("%.*s", disp_len, cp); + bprintf(pmode, "%.*s", disp_len, cp); } else if(doubled) { wide(cp); } else if(zero_padded) { int vlen = strlen(cp); if(vlen < disp_len) - bprintf("%-.*s%s", (int)(disp_len - strlen(cp)), "0000000000", cp); + bprintf(pmode, "%-.*s%s", (int)(disp_len - strlen(cp)), "0000000000", cp); else - bprintf("%.*s", disp_len, cp); + bprintf(pmode, "%.*s", disp_len, cp); } else - bprintf("%.*s", disp_len, cp); + bprintf(pmode, "%.*s", disp_len, cp); return(len); } -const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) +const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen, long* pmode) { char* tp = NULL; uint i; @@ -1112,6 +1119,8 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) /* Message header codes */ if(!strcmp(sp,"MSG_TO") && current_msg!=NULL && current_msg_to!=NULL) { + if(pmode != NULL) + *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); if(current_msg->to_ext!=NULL) safe_snprintf(str,maxlen,"%s #%s",current_msg_to,current_msg->to_ext); else if(current_msg->to_net.addr != NULL) { @@ -1122,8 +1131,11 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) return(current_msg_to); return(str); } - if(!strcmp(sp,"MSG_TO_NAME") && current_msg_to!=NULL) + if(!strcmp(sp,"MSG_TO_NAME") && current_msg_to!=NULL) { + if(pmode != NULL && current_msg != NULL) + *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); return(current_msg_to); + } if(!strcmp(sp,"MSG_TO_EXT") && current_msg!=NULL) { if(current_msg->to_ext==NULL) return(nulstr); @@ -1144,6 +1156,8 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) if(!strcmp(sp,"MSG_FROM") && current_msg != NULL && current_msg_from != NULL) { if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) return(text[Anonymous]); + if(pmode != NULL) + *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); if(current_msg->from_ext!=NULL) safe_snprintf(str,maxlen,"%s #%s",current_msg_from,current_msg->from_ext); else if(current_msg->from_net.addr != NULL) { @@ -1157,6 +1171,8 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) if(!strcmp(sp,"MSG_FROM_NAME") && current_msg_from!=NULL) { if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) return(text[Anonymous]); + if(pmode != NULL && current_msg != NULL) + *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); return(current_msg_from); } if(!strcmp(sp,"MSG_FROM_EXT") && current_msg!=NULL) { @@ -1176,8 +1192,11 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen) return nulstr; return(smb_nettype((enum smb_net_type)current_msg->from_net.type)); } - if(!strcmp(sp,"MSG_SUBJECT") && current_msg_subj != NULL) + if(!strcmp(sp,"MSG_SUBJECT") && current_msg_subj != NULL) { + if(pmode != NULL && current_msg != NULL) + *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); return(current_msg_subj); + } if(!strcmp(sp,"MSG_SUMMARY") && current_msg!=NULL) return(current_msg->summary==NULL ? nulstr : current_msg->summary); if(!strcmp(sp,"MSG_TAGS") && current_msg!=NULL) diff --git a/src/sbbs3/getmsg.cpp b/src/sbbs3/getmsg.cpp index ab1edfff17833b20bb942b37aeefa3b3fa3fe873..0069028a993766f4f8fa0c5dc2fbceac04fc77ed 100644 --- a/src/sbbs3/getmsg.cpp +++ b/src/sbbs3/getmsg.cpp @@ -118,6 +118,18 @@ void sbbs_t::show_msgattr(smbmsg_t* msg) ); } +/* Returns a CP437 text.dat string converted to UTF-8, when appropriate */ +const char* sbbs_t::msghdr_text(const smbmsg_t* msg, uint index) +{ + if(msg == NULL || !(msg->hdr.auxattr & MSG_HFIELDS_UTF8)) + return text[index]; + + if(cp437_to_utf8_str(text[index], msghdr_utf8_text, sizeof(msghdr_utf8_text), /* min-char-val: */'\x80') < 1) + return text[index]; + + return msghdr_utf8_text; +} + /****************************************************************************/ /* Displays a message header to the screen */ /****************************************************************************/ @@ -128,6 +140,7 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg, const char* subject, const c char *sender=NULL; int i; smb_t saved_smb = this->smb; + long pmode = 0; if(smb != NULL) this->smb = *smb; // Needed for @-codes and JS bbs.smb_* properties @@ -136,6 +149,8 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg, const char* subject, const c current_msg_subj = msg->subj; current_msg_from = msg->from; current_msg_to = msg->to; + if(msg->hdr.auxattr & MSG_HFIELDS_UTF8) + pmode |= P_UTF8; } if(subject != NULL) current_msg_subj = subject; @@ -153,13 +168,13 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg, const char* subject, const c } msghdr_tos = tos; if(!menu("msghdr", P_NOERROR)) { - bprintf(text[MsgSubj], current_msg_subj); + bprintf(pmode, msghdr_text(msg, MsgSubj), current_msg_subj); if(msg->tags && *msg->tags) bprintf(text[MsgTags], msg->tags); if(msg->hdr.attr || msg->hdr.netattr || msg->hdr.auxattr) show_msgattr(msg); if(current_msg_to != NULL && *current_msg_to != 0) { - bprintf(text[MsgTo], current_msg_to); + bprintf(pmode, msghdr_text(msg, MsgTo), current_msg_to); if(msg->to_net.addr!=NULL) bprintf(text[MsgToNet],smb_netaddrstr(&msg->to_net,str)); if(msg->to_ext) @@ -168,7 +183,7 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg, const char* subject, const c if(msg->cc_list != NULL) bprintf(text[MsgCarbonCopyList], msg->cc_list); if(current_msg_from != NULL && (!(msg->hdr.attr&MSG_ANONYMOUS) || SYSOP)) { - bprintf(text[MsgFrom], current_msg_from); + bprintf(pmode, msghdr_text(msg, MsgFrom), current_msg_from); if(msg->from_ext) bprintf(text[MsgFromExt],msg->from_ext); if(msg->from_net.addr!=NULL && (current_msg_from == NULL || strchr(current_msg_from,'@')==NULL)) diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 06e4afde63743a4ae6087b7b30b1bc7d81b25c8e..73f7ac3869fc7a8aa9dcfc96792731f849e6d05a 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -688,6 +688,8 @@ public: void show_msghdr(smb_t*, smbmsg_t*, const char *subj = NULL, const char* from = NULL, const char* to = NULL); bool show_msg(smb_t*, smbmsg_t*, long p_mode = 0, post_t* post = NULL); bool msgtotxt(smb_t*, smbmsg_t*, const char *fname, bool header = true, ulong gettxt_mode = GETMSGTXT_ALL); + const char* msghdr_text(const smbmsg_t*, uint index); + char msghdr_utf8_text[128]; ulong getlastmsg(uint subnum, uint32_t *ptr, time_t *t); time_t getmsgtime(uint subnum, ulong ptr); ulong getmsgnum(uint subnum, time_t t); @@ -787,7 +789,7 @@ public: /* atcodes.cpp */ int show_atcode(const char *code); - const char* atcode(char* sp, char* str, size_t maxlen); + const char* atcode(char* sp, char* str, size_t maxlen, long* pmode = NULL); /* getnode.cpp */ int getsmsg(int usernumber, bool clearline = false); diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp index 415fc33eb84ca234dd89e6414af682b318d44216..37f183c3ead5a4c26d0fc75762a5d44e5e97de03 100644 --- a/src/sbbs3/writemsg.cpp +++ b/src/sbbs3/writemsg.cpp @@ -749,7 +749,10 @@ void sbbs_t::editor_info_to_msg(smbmsg_t* msg, const char* editor, const char* c if(editor == NULL || useron_xedit == 0 || (cfg.xedit[useron_xedit - 1]->misc&SAVECOLUMNS)) smb_hfield_bin(msg, SMB_COLUMNS, cols); -} + + if(!str_is_ascii(msg->subj) && utf8_str_is_valid(msg->subj)) + msg->hdr.auxattr |= MSG_HFIELDS_UTF8; +} /****************************************************************************/ /****************************************************************************/