campo-sirio/include/diction.cpp
alex 6e0d5b4275 Patch level : aga 2.0 patch 335
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la versione Partners 2.0 patch 335


git-svn-id: svn://10.65.10.50/trunk@10496 c028cbd2-c16b-5b4b-a496-9718f37d4682
2002-09-13 14:56:23 +00:00

307 lines
6.1 KiB
C++
Executable File

/*
<xml>
<dictionary>
<entry module="ba">
<ita>Attezione: premere OK per cancellare</ita>
<eng>Atension: pres OK to dilit</eng>
</entry>
</dictionary>
</xml>
*/
#include <xvt.h>
#include <config.h>
#include <diction.h>
#include <netsock.h>
#include <scanner.h>
#include <utility.h>
///////////////////////////////////////////////////////////
// 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 << unesc(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 = 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())
{
TString str = sentence; str.trim();
bool has_letters = false;
for (int i = 0; str[i]; i++)
{
if (isalpha(str[i]))
{
has_letters = true;
break;
}
}
if (has_letters)
{
TString* trans = (TString*)objptr(str);
if (trans != NULL && trans->not_empty())
sentence = (const char*)*trans;
}
}
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;
}
}