/* Attezione: premere OK per cancellare Attension: pres ochei to dilit */ #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TTraduttore /////////////////////////////////////////////////////////// class TTraduttore : public TCache { TString _str; TSocketClient _client; CONNID _connection; protected: virtual TObject* key2obj(const char* key); public: bool active() const { return _connection != 0; } const char* translate(const char* sentence); TTraduttore(); virtual ~TTraduttore(); }; TObject* TTraduttore::key2obj(const char* key) { const char* const prefix = ""; const char* const posfix = ""; _str.cut(0); _str << "\n" << prefix << unesc(key) << posfix << '\n' << "\n"; if (_client.HttpSoap(_connection, _str)) { _str.cut(0); size_t size; const TFixed_string buf((const char*)_client.GetBuffer(size)); int start = buf.find(" 0) start = buf.find('>', start+1)+1; if (start > 0) { const int stop = buf.find('<', start); if (stop > 0) _str = esc(buf.sub(start, stop)); } // _client.ReleaseBuffer(); // Non perdiamo tempo in 'ste cose } else return NULL; return _str.dup(); } const char* TTraduttore::translate(const char* sentence) { if (sentence && *sentence && active()) { for (int i = 0; sentence[i]; i++) { if (isalpha(sentence[i])) { TString* trans = (TString*)objptr(sentence); if (trans != NULL && trans->not_empty()) return (const char*) *trans; break; } } } return sentence; } TTraduttore::TTraduttore() : _connection(0) { TConfig ini(CONFIG_INSTALL, "Server"); const TString& server = ini.get("Dictionary"); if (server.not_empty()) _connection = _client.QueryConnection("", server); } TTraduttore::~TTraduttore() { // Autoclose connection } static TTraduttore* _DevotoOli = NULL; const char* dictionary_translate(const char* sentence) { if (_DevotoOli == NULL) _DevotoOli = new TTraduttore; return _DevotoOli->translate(sentence); } const char* dictionary_translate_macro(const char* sentence) { if (memcmp(sentence, TO_BE_TRANSLATED, 4) == 0) sentence = dictionary_translate(sentence+4); return sentence; } char strip_accelerator(TString& str) { char tilde= '\0'; for (int i = 0; str[i]; i++) { if (str[i] == '~' || str[i] == '&') { tilde = str[i+1]; str.strip("~&"); break; } } return tilde; } void restore_accelerator(TString& str, char acc, char tilde) { if (acc > ' ') { int newtilde = 0; for (int m = 0; str[m]; m++) { if (toupper(str[m]) == acc) { newtilde = m; break; } } const char s[2] = { tilde, '\0' }; str.insert(s, newtilde); } } // len - Effect // -1 - No length limit // 0 - Exactly same lenght as original // >0 - Maximum specified length const char* dictionary_translate_prompt(const char* prompt, int maxlen) { if (prompt && *prompt && dictionary_active()) { TString& str = get_tmp_string(); str = prompt; TString8 prefix; if (str[0] == '@') { prefix = str.left(2); // Usually bold = @b str.ltrim(2); } const char matilde = strip_accelerator(str); // Ricorda tasto rapido const int oldlen = str.len(); // Memorizza vecchia lunghezza str = dictionary_translate(str); if (maxlen >= 0) { const int limit = maxlen == 0 ? oldlen : maxlen; if (str.len() > limit) { // Abbrevio all'ultima consonante for (int i = limit-2; i > 0; i--) { if (strchr("aeiou", str[i]) == NULL) { str.cut(i+1); str << '.'; break; } } if (i <= 0) str.cut(limit); } if (maxlen == 0 && str.len() < limit) str.left_just(limit); } restore_accelerator(str, matilde, '~'); str.insert(prefix); return str; } return prompt; } const char* dictionary_translate_macro_prompt(const char* sentence, int maxlen) { if (memcmp(sentence, TO_BE_TRANSLATED, 4) == 0) sentence = dictionary_translate_prompt(sentence+4, maxlen); return sentence; } const char* dictionary_translate_header(const char* head) { if (head && *head && dictionary_active()) { TString str = head; const int at = str.rfind('@'); if (at >= 0) { TString8 postfix; postfix = str.mid(at); str.cut(at); str = dictionary_translate(str); str << postfix; return str; } if (str.right(1)[0] == ' ') return dictionary_translate_prompt(head); return dictionary_translate(head); } return head; } const char* dictionary_translate_macro_header(const char* head) { if (memcmp(head, TO_BE_TRANSLATED, 4) == 0) head = dictionary_translate_header(head+4); return head; } const char* dictionary_translate_menu_item(const char* text) { TString& str = get_tmp_string(); str = text; const char matilde = strip_accelerator(str); TString16 posfix; int start = str.find('\t'); if (start < 0) start = str.find("..."); if (start > 0) { posfix = str.mid(start); str.cut(start); } const char* newtext = dictionary_translate(str); if (str != newtext) { str = newtext; restore_accelerator(str, matilde, '&'); if (posfix.not_empty()) str << posfix; return str; } return text; } void dictionary_translate_menu(MENU_ITEM* menu) { if (menu && dictionary_active()) for (int m = 0; menu[m].tag != 0; m++) { MENU_ITEM& mi = menu[m]; if (!mi.separator) { const char* newtext = dictionary_translate_menu_item(mi.text); if (strlen(newtext) > strlen(mi.text)) // Posso sovrascrivere? mi.text = xvt_mem_realloc(mi.text, strlen(newtext)+1); strcpy(mi.text, newtext); if (mi.child) dictionary_translate_menu(mi.child); } } } bool dictionary_active() { return _DevotoOli != NULL && _DevotoOli->active(); } void dictionary_close() { if (_DevotoOli != NULL) { delete _DevotoOli; _DevotoOli = NULL; } }