Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunte utili per gestione dizionario assoc.cpp Aggiunta possibilita' di selezionare un elemento causale di un assoc controls.cpp Corretta gestione scrollbar dei listbox diction.cpp Migliorata selezione caratteri da trimmare dalle traduzioni isam.cpp Corretto azzeramento dei memo (non azzerava il TString_array corrispondente) msksheet.cpp Resa personalizzabile la larghezza della colonna col numero di riga netsock.cpp Migliorata gestione "a capo" in protocollo soap progind.cpp Corretto posizionamento progind sovrapposte relapp.cpp Cambiato un messaggio di richiesta annullamento git-svn-id: svn://10.65.10.50/trunk@11651 c028cbd2-c16b-5b4b-a496-9718f37d4682
348 lines
7.0 KiB
C++
Executable File
348 lines
7.0 KiB
C++
Executable File
/*
|
|
<dictionary>
|
|
<entry>
|
|
<ita>Attezione: premere OK per cancellare</ita>
|
|
<eng>Atension: pres ochei to dilit</eng>
|
|
<src>ba1.exe</src>
|
|
</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("", 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;
|
|
|
|
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
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
|