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;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 |