campo-sirio/include/diction.cpp
guy f386003944 Patch level : 4.0
Files correlati     : librerie
Ricompilazione Demo : [ ]
Commento            :
diction.cpp:  aggiunto logging delle frasi non tradotte
isam.cpp: aggiunti commenti e migliorati prompt delle importazioni
reprint.cpp: aggiunti commenti


git-svn-id: svn://10.65.10.50/trunk@14325 c028cbd2-c16b-5b4b-a496-9718f37d4682
2006-09-15 15:27:47 +00:00

361 lines
7.2 KiB
C++
Executable File

/*
<dictionary>
<entry>
<ita>Attezione: premere OK per cancellare</ita>
<eng>Atension: pres ochei to dilit</eng>
<src>ba1.exe</src>
<max>40</max>
</entry>
</dictionary>
*/
#include <xvt.h>
#include <config.h>
#include <diction.h>
#include <netsock.h>
#include <scanner.h>
///////////////////////////////////////////////////////////
// Utility di conversione
///////////////////////////////////////////////////////////
TString& txt2xml(const TString& str)
{
TString& tmp = get_tmp_string();
for (int i = 0; str[i]; i++)
{
if (str[i] < ' ' || str[i] > 'z' || strchr("&<>/", str[i]) != NULL)
{
TString8 code;
code.format("&#%X;", (int)(unsigned char)(str[i]));
tmp << code;
}
else
tmp << str[i];
}
return tmp;
}
TString& xml2txt(const TString& str)
{
TString& tmp = get_tmp_string();
for (int i = 0; str[i]; i++)
{
if (str[i] == '&' && str[i+1] == '#')
{
i += 2;
const int semicolon = str.find(';', i);
if (semicolon > 0)
{
int n;
sscanf(str.sub(i, semicolon), "%X", &n);
tmp << char(n & 0xFF);
i = semicolon;
}
}
else
tmp << str[i];
}
return tmp;
}
///////////////////////////////////////////////////////////
// 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 = "<sentence>";
const char* const posfix = "</sentence>";
_str.cut(0);
_str << "<m:Translate>\n"
<< prefix << txt2xml(key) << posfix << '\n'
<< "</m:Translate>\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("<sentence");
if (start > 0)
start = buf.find('>', start+1)+1;
if (start > 0)
{
const int stop = buf.find('<', start);
if (stop > 0)
_str = xml2txt(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("3883", 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)
{
#ifdef WIN32
if (memcmp(sentence, TO_BE_TRANSLATED, 4) == 0)
sentence = dictionary_translate(sentence+4);
#else
sentence = dictionary_translate(sentence);
#endif
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;
int prefixlen = 0;
if (str[0] == '@')
prefixlen = 2; else
if (str[0] == '$')
prefixlen = 6;
TString8 prefix;
if (prefixlen > 0)
{
prefix = str.left(prefixlen);
str = str.mid(prefixlen);
}
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
int i;
for (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)
{
#ifdef WIN32
if (memcmp(sentence, TO_BE_TRANSLATED, 4) == 0)
sentence = dictionary_translate_prompt(sentence+4, maxlen);
#else
sentence = dictionary_translate_prompt(sentence, maxlen);
#endif
return sentence;
}
const char* dictionary_translate_header(const char* head)
{
if (head && *head && dictionary_active())
{
const TFixed_string str(head);
const int at = str.rfind('@');
if (at >= 0)
{
TString& tmp = get_tmp_string();
tmp = dictionary_translate(str.left(at));
tmp << str.mid(at);
return tmp;
}
if (str.ends_with(" "))
return dictionary_translate_prompt(head);
return dictionary_translate(head);
}
return head;
}
const char* dictionary_translate_macro_header(const char* head)
{
#ifdef WIN32
if (memcmp(head, TO_BE_TRANSLATED, 4) == 0)
head = dictionary_translate_header(head+4);
#else
head = dictionary_translate_header(head);
#endif
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;
}
}