/* GUI tool to help translation of .dic files. */ /* TODO: Independant search dialog. You enter a word and it look in all messages. It shows all the message, including translations containing that word or sentence. Bouton dans le taskbar pour aller au prochain nouveau, prochain changer, précédant etc... Validation des %s et %d */ #include #include #include #include #include #include #include "tledit.h" #include "tledit.m" class MSGTRA: public ARRAY_OBJ{ public: SSTRING id; SSTRING comment; SSTRING source_old; SSTRING source; SSTRING oldtrans; SSTRING newtrans; SSTRING suggest; // Picked from either babel or ref dict. }; class MSGTRAS: public ARRAY_OBJS{ public: int version; bool is_modified() const; MSGTRAS(); }; class MSGTRASS: public ARRAY_OBJS{ public: }; MSGTRAS::MSGTRAS() { version = 0; } bool MSGTRAS::is_modified() const { bool ret = false; for (int i=0; icomment.is_filled() && tra->newtrans.is_filled()) ret = true; } return ret; } class DICDOC: public FRAMEWORK_DOCUMENT{ public: SSTRING dic; DICDOC (const char *_dic){ dic = _dic; } bool same(const FRAMEWORK_DOCUMENT &other){ return ((DICDOC&)other).dic == dic; } }; static void updstatus ( MSGTRAS &tbmsg, SSTRING &status1, PRIVATE_MESSAGE &status1_msg) { int nb = tbmsg.size(); int nbdone = 0,nbnew=0,nbupd=0; for (int i=0; inewtrans.is_filled()) nbdone++; if (tra->comment.stristr("new")!=NULL){ nbnew++; }else{ nbupd++; } } status1.setfromf (MSG_U(I_DOCSTATS,"%d msgs, %d new, %d updated, %d done") ,nb,nbnew,nbupd,nbdone); dialog_sendmessage (status1_msg); } static void printmsg (FILE *fout, const char letter, const SSTRING &msg) { if (msg.is_filled()){ SSTRINGS lines; str_cnv2lines (msg.get(),lines); SSTRING prefix; prefix.setfromf (" :%c ",letter); for (int i=0; iget()); prefix = " +"; } } } static void readdic (const char *file, MSGTRAS &tbmsg) { glocal MSGTRAS *tbmsg = &tbmsg; glocal MSGTRA last,empty; glocal SSTRING *last_line=NULL; // Used to fill // continuation lines ERROR_PREFIX pre (MSG_U(E_INDICFILE,"In dictionary file %s:"),file); (file,true); line = str_skip(line); if (strncmp(line,"@version",8)==0){ glocal.tbmsg->version = atoi(str_skip(line+8)); }else if (line[0] == '#' || line[0] == '!'){ if (glocal.last.id.is_filled()){ glocal.tbmsg->add (new MSGTRA(glocal.last)); glocal.last = glocal.empty; glocal.last_line = NULL; } if (line[0] == '#'){ glocal.last.comment = str_skip(line+1); }else if (line[0] == '!'){ glocal.last.id = line+1; } }else if (line[0] == ':' && line[1] == 'E'){ glocal.last.source = str_skip(line+2); glocal.last_line = &glocal.last.source; }else if (line[0] == ':' && line[1] == 'Z'){ glocal.last.source_old = str_skip(line+2); glocal.last_line = &glocal.last.source_old; }else if (line[0] == ':' && line[1] == 'T'){ if (glocal.last.comment.is_filled()){ glocal.last.oldtrans = str_skip(line+2); glocal.last_line = &glocal.last.oldtrans; }else{ glocal.last.newtrans = str_skip(line+2); glocal.last_line = &glocal.last.newtrans; } }else if (line[0] == '+'){ if (glocal.last_line == NULL){ tlmp_error (MSG_U(E_IVLDCONT,"Invalid continuation on line %d"),noline); }else{ glocal.last_line->appendf ("\n%s",line+1); } } return 0; if (glocal.last.id.is_filled()){ tbmsg.add (new MSGTRA(glocal.last)); } } static int savedic (const char *file, MSGTRAS &tbmsg) { glocal MSGTRAS *tb = &tbmsg; int ret = -1; SSTRING old; old.setfromf ("%s.bak",file); rename (file,old.get()); //SSTRING tmp; // tmp.setfromf ("%s.tmp",file); ret = (file,false); fprintf (fout,"@version %d\n",glocal.tb->version); for (int i=0; isize(); i++){ MSGTRA *tra = glocal.tb->getitem(i); bool changed = tra->newtrans.is_filled(); if (!changed && tra->comment.is_filled()){ fprintf (fout,"# %s\n",tra->comment.get()); } fprintf (fout,"!%s\n",tra->id.get()); if (!changed){ printmsg (fout,'Z',tra->source_old); } printmsg (fout,'E',tra->source); if (!changed){ printmsg (fout,'T',tra->oldtrans); }else{ printmsg (fout,'T',tra->newtrans); } } return 0; return ret; } /* Add message from src in dst if missing, copy dst to file */ static void mergedic (const MSGTRAS &src, MSGTRAS &dst, const char *file) { bool modified = false; for (int i=0; inewtrans.is_filled()){ const char *source = tra->source.get(); const char *id = tra->id.get(); bool found = false; for (int j=0; jid.ncmp(id,2)==0 && d->source.cmp(source)==0){ found = true; break; } } if (!found){ MSGTRA *n = new MSGTRA; n->id = id; n->source = source; n->newtrans = tra->newtrans; dst.add (n); modified = true; } } } if (modified){ savedic (file,dst); } } /* We find matching messages in ref (same ID prefix: B_ I_ ...) and copy their translation in the suggest field. */ #if 0 static void suggest (const MSGTRAS &ref, MSGTRAS &tb) { for (int i=0; isource.get(); const char *id = tra->id.get(); for (int j=0; jid.ncmp(id,2)==0 && d->source.cmp(source)==0){ tra->suggest = d->newtrans; break; } } } } #else static void suggest (COROUTINE *co, MSGTRA *&cotra, MSGTRAS &tb) { for (int i=0; isource.get(); const char *id = tra->id.get(); co->restart(); while (co->next()){ if (cotra->id.ncmp(id,2)==0 && cotra->source.cmp(source)==0 && cotra->newtrans.is_filled()){ tra->suggest = cotra->newtrans; co->stop(); } } } } #endif int main (int argc, char *argv[]) { glocal int toto=0; int ret = -1; ret = (argc,argv,"tlmpwork"); extern const char *version; setproginfo ("dictrans",version,MSG_U(I_DICTRANS ,"Tool to help translation of program messages")); xconf_error ("%s",msg); glocal SSTRING status1,status2; glocal PRIVATE_MESSAGE status1_msg,status2_msg; glocal MSGTRAS refmsgs; // Dictionary of all translated // message done by the user glocal MSGTRASS allmsgs; glocal MSGTRA *cotra; // Message selected by the coroutine glocal SSTRING refdic; // HOME/.dictrans.dic glocal.refdic.setfromf ("%s/.dictrans.dic",getenv("HOME")); glocal.allmsgs.neverdelete(); glocal.allmsgs.add (&glocal.refmsgs); (); int ret = 0; for (int i=0; ret == 0 && isize(); j++){ glocal.cotra = msgs->getitem(j); ret = yield(); } } glocal COROUTINE *co = &co; if (file_exist (glocal.refdic.get())){ readdic (glocal.refdic.get(),glocal.refmsgs); } (MSG_U(T_DICTRANS,"Messages translator")); layout_area1(true); extern const char *version; (MSG_R(T_DICTRANS),version); printf (MSG_R(I_DICTRANS)); printf ("Jacques Gélinas jack@solucorp.qc.ca\n"); setgpl(); printf ("http://www.solucorp.qc.ca/tlmp\n"); topmenu(MSG_R(M_FILE)); menuentry (1,MSG_R(M_SAVE)); menuentry (2,MSG_R(M_CLOSE)); menuentry (3,MSG_U(M_EXPORT,"Export to ref")); endmenu(); helpmenu(); endmenu(); newbutton (1,"",MSG_U(B_NEXTNEW,"Next new/mod"),""); newbutton (2,"",MSG_U(B_NEXT,"Next"),""); newbutton (3,"",MSG_U(B_PREV,"Previous"),""); glocal.status1 = "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"; (ending); dia.newf_str (NULL,glocal.status1,40); dia.set_lastreadonly(); dia.newf_str (NULL,glocal.status2,30); dia.set_lastreadonly(); dia.waitfor (glocal.status1_msg); dia.waitfor (glocal.status2_msg); if (dialog_testmessage(glocal.status1_msg)){ dia.reload(0); }else if (dialog_testmessage(glocal.status2_msg)){ dia.reload(1); } DICDOC *doc = (DICDOC*)info.data; glocal FRAMEWORK_INFO *topinfo = &info; glocal PRIVATE_MESSAGE reload; glocal int edit=-1; glocal MSGTRAS tbmsg; glocal const char *file = doc->dic.get(); glocal PRIVATE_MESSAGE updmsg; glocal.allmsgs.add (&glocal.tbmsg); readdic (glocal.file,glocal.tbmsg); //suggest (glocal.allmsgs,glocal.tbmsg); suggest (glocal.co,glocal.cotra,glocal.tbmsg); (glocal.file,info); layout_area1(false); layout_newline(); layout_area2(false); glocal FRAMEWORK_INFO *info = &info; ("","",help_nil); newf_head (MSG_U(H_MSGS,"ID\tStatus\tDone\tText")); sortable(); sortpolicy ("aaaa"); handle (glocal.info->msgs); nobutton(); waitfor (glocal.topinfo->docmsgs.focus); waitfor (glocal.updmsg); waitfor (glocal.topinfo->docmsgs.taskbar); for (int i=0; icomment.is_filled()){ if (tra->comment.stristr("new")!=NULL){ status = MSG_U(I_NEWMSG,"New message"); }else{ status = MSG_U(I_CHANGED,"Modified"); } } SSTRING text (tra->source); const char *start = text.get(); const char *pt = text.strchr('\n'); if (pt != NULL){ text.setfrom (start,pt-start); } if (glocal.edit == i){ setnexttagged(); } new_menuitemf (tra->id.get(),"%s\t%s\t%s" ,status ,tra->newtrans.is_filled() ? MSG_R(I_YES) : " " ,text.get()); } glocal.edit = no; dialog_sendmessage (glocal.reload); if (dialog_testmessage(glocal.topinfo->docmsgs.focus) || dialog_testmessage(glocal.updmsg)){ updstatus (glocal.tbmsg,glocal.status1,glocal.status1_msg); }else if (dialog_testmessage(glocal.topinfo->docmsgs.taskbar)){ int id = glocal.topinfo->taskid; if (id == 1){ int nxt = glocal.edit; while (1){ nxt = getnext (nxt); if (nxt == -1) break; MSGTRA *tra = glocal.tbmsg.getitem(nxt); if (tra->comment.is_filled()){ glocal.edit = nxt; dialog_sendmessage(glocal.reload); break; } } }else if (id == 2){ int nxt = getnext (glocal.edit); if (nxt != -1){ glocal.edit = nxt; dialog_sendmessage(glocal.reload); } }else if (id == 3){ int nxt = getprev (glocal.edit); if (nxt != -1){ glocal.edit = nxt; dialog_sendmessage(glocal.reload); } } } DIALOG dia; MSGTRA msg,*pt = NULL; dia.newf_str (MSG_U(F_ID,"Message ID"),msg.id); dia.set_lastreadonly(); dia.newline(); dia.newf_str (MSG_U(F_TASK,"Task"),msg.comment); dia.set_lastreadonly(); dia.newline(); dia.newf_textarea (MSG_U(F_OLDENGLISH,"Last in source"),msg.source_old,60,3); //dia.set_lastreadonly(); dia.newline(); dia.newf_textarea (MSG_U(F_ENGLISH,"Current in source"),msg.source,60,3); //dia.set_lastreadonly(); PRIVATE_MESSAGE msg_copy; dia.new_button (MSG_R(B_COPY),MSG_U(I_COPY,"Do not translate"),msg_copy); dia.newline(); dia.newf_textarea (MSG_U(F_TRANS1,"Original translation"),msg.oldtrans,60,3); //dia.set_lastreadonly(); PRIVATE_MESSAGE msg_keep; dia.new_button (MSG_U(B_KEEP,"Keep"),MSG_U(I_KEEP,"Keep the original translation"),msg_keep); dia.newline(); int field_newtrans = dia.size(); dia.newf_textarea (MSG_U(F_TRANS2,"New translation"),msg.newtrans,60,3); dia.newline(); dia.newf_textarea (MSG_U(F_SUGGEST,"Suggested"),msg.suggest,60,3); PRIVATE_MESSAGE msg_suggest; dia.new_button (MSG_R(B_COPY),MSG_R(I_COPY),msg_suggest); info.msgs.waitfor (dia); dia.waitfor (glocal.reload); dia.waitfor (glocal.topinfo->docmsgs.menubar); int nof = 0; while (1){ MENU_STATUS code = dia.edit ("","",help_nil,nof,0); if (code == MENU_MESSAGE){ dia.save(); if (dialog_testmessage(msg_copy)){ msg.newtrans = msg.source; dia.reload(field_newtrans); }else if (dialog_testmessage(msg_keep)){ msg.newtrans = msg.oldtrans; dia.reload(field_newtrans); }else if (dialog_testmessage(msg_suggest)){ msg.newtrans = msg.suggest; dia.reload(field_newtrans); }else{ if (pt !=NULL){ *pt = msg; dialog_sendmessage (glocal.updmsg); } if (info.msgs.is_mayend()){ if (!glocal.tbmsg.is_modified()){ endok(); }else{ DIALOG dok; dok.settype (DIATYPE_POPUP); char quit = 1; dok.newf_radio (MSG_U(F_QUIT,"Quit"),quit,0,MSG_U(I_WITHOUTSAVE,"without save")); dok.newf_radio ("",quit,1,MSG_U(I_BUTSAVE,"but save first")); while (1){ SSTRING buf; buf.setfromf (MSG_U(I_LOOSEMODIF ,"Some translations were performed in file %s") ,glocal.file); MENU_STATUS code = dok.edit ( MSG_U(Q_LOOSEMODIF,"Document was modified") ,buf.get(),help_nil); if (code == MENU_CANCEL){ break; }else if (code == MENU_ACCEPT){ if (quit == 1){ savedic (glocal.file,glocal.tbmsg); } endok(); break; } } } }else if (info.msgs.is_ending()){ break; }else if (dialog_testmessage(glocal.reload)){ pt = glocal.tbmsg.getitem(glocal.edit); msg = *pt; dia.reload(); }else if (dialog_testmessage(glocal.topinfo->docmsgs.menubar)){ int id = glocal.topinfo->menuid; if (id == 1){ savedic (glocal.file,glocal.tbmsg); }else if (id == 2){ end(); }else if (id == 3){ mergedic (glocal.tbmsg,glocal.refmsgs,glocal.refdic.get()); } } } } } frm.loop(); glocal.allmsgs.remove (&glocal.tbmsg); for (int i=0; i return main(0,NULL); return ret; }