f386003944
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
361 lines
7.2 KiB
C++
Executable File
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;
|
|
}
|
|
}
|
|
|
|
|
|
|