News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Multilingual GUI

Started by Biterider, November 13, 2022, 05:58:54 PM

Previous topic - Next topic

Biterider

Hi
Deploying an application for the international market mostly requires some kind of localization (https://en.wikipedia.org/wiki/Multilingual_User_Interface).

In recent years, several online services have started offering online translations into a large number of languages, more than what is normally supported by a regular application.
In this sense, it would be nice to use these services on-site to translate the text resources into the target language chosen by the user and store them locally, avoiding further use of the translator.
From what I've seen, using such services can be done using a relatively simple HTTP API set and a user account. This last point requires registration and payment.

I was wondering how Google's Chrome does this since it doesn't require a login? Does anyone have an idea how it works? Any link or working example?  :tongue:

Biterider

jj2007

I've played with the idea, see attached multilingual editor, but with a slightly different approach:
- all GUI strings are handled in an Excel spreadsheet (attached)
- that implies getting translations for each column manually from Google or DeepL
- a copy gets saved in Utf8 format as GuiData.tab
- the tab file gets embedded as a resource
- the editor picks the language "on the fly" from that resource

You can test it using the Language menu entry.

Your version would go online to request the desired language for each GUI string, is that correct?

Biterider

Hi
Quote from: jj2007 on November 13, 2022, 08:52:30 PM
Your version would go online to request the desired language for each GUI string, is that correct?
Yes, but only if the provided localization is not available. If you cannot go online, a default language, in most cases English, will be selected and must always be present.

Biterider

Biterider

#3
Hi
I found something on GitHub easygoogletranslate
The author claims that he uses an "unofficial Google Translate API".
I extracted the relevant request from the Python code
https://translate.google.com/m?tl=sv&sl=en&q=Open%20File which, for example, translates "Open File" from English to Swedish

Available languages are listed here https://cloud.google.com/translate/docs/languages

Biterider

jj2007

Try this link for a change. It works in a browser, but not as a direct download request, unfortunately. They have an API, though, but it requires authentication, i.e. your user would have to register. That is one reason why I would prefer the Excel spreadsheet approach mentioned above: a few kBytes more embedded in the executable, but no hassle with registration etc

Biterider

#5
Hi
After all, it wasn't that difficult :cool:
Here is the unpolished code:

TranslateText proc uses xbx xdi, pDstLang:PSTRING, pSrcLang:PSTRING, pSrcText:PSTRING
  local hInternet:HINTERNET, hConnect:HINTERNET, hRequest:HINTERNET
  local dBytesRead:DWORD, pStartChar:POINTER, pTranslation:PSTRINGW
  local pBuffer:POINTER, wDstBuffer[128]:CHRW, bURI[128]:CHRA

  RCV_BUFFER_SIZE equ 4*PAGESIZE         ;Reserve 4 pages, should be enough

  mov pTranslation, NULL
  invoke InternetOpen, $OfsCStr("Chrome/5.0"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0
  .if xax != 0
    mov hInternet, xax
    invoke InternetConnect, hInternet, $OfsCStr("translate.google.com"), INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL
    .if xax != 0
      mov hConnect, xax
      lea xdi, bURI
      WriteF xdi, "/m?hl=en&tl=¦ST&sl=¦ST&q=¦ST", pDstLang, pSrcLang, pSrcText
      invoke HttpOpenRequest, hConnect, $OfsCStr("GET"), addr bURI, NULL, NULL, NULL, INTERNET_FLAG_RELOAD or INTERNET_FLAG_EXISTING_CONNECT or INTERNET_FLAG_SECURE, NULL
      .if xax != 0
        mov hRequest, xax
        invoke HttpSendRequest, hRequest, NULL, 0, NULL, 0
        invoke VirtualAlloc, NULL, RCV_BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE
        .if xax != NULL
          mov pBuffer, xax
          mov xdi, xax
          mov ebx, RCV_BUFFER_SIZE - 1
          .repeat
            invoke InternetReadFile, hRequest, xdi, ebx, addr dBytesRead
            mov ecx, dBytesRead
            .break .if eax == 0 || ecx == 0
            add xdi, xcx
            sub ebx, ecx
          .until FALSE
          mov CHRA ptr [xdi], 0
          .if eax != 0
            invoke StrPosA, pBuffer, $OfsCStrA(3Ch, 'div class="result-container"', 3Eh)
            .if xax != NULL
              add xax, 30
              mov pStartChar, xax
              invoke StrPos, xax, $OfsCStr(3Ch)
              mov CHRA ptr [xax], 0
              invoke UTF8ToWide, addr wDstBuffer, pStartChar, sizeof wDstBuffer
              invoke StrNewW, addr wDstBuffer
              mov pTranslation, xax
            .endif
          .endif
          invoke VirtualFree, pBuffer, RCV_BUFFER_SIZE, MEM_RELEASE
        .endif
        invoke InternetCloseHandle, hRequest
      .endif
      invoke InternetCloseHandle, hConnect
    .endif 
    invoke InternetCloseHandle, hInternet
  .endif
  mov xax, pTranslation
  ret
TranslateText endp 


For example, to translate "Open File" into Spanish, the code should look like this
  invoke TranslateText, $OfsCStr("es"), $OfsCStr("en"), $OfsCStr("Open File")
  .if xax != NULL
    DbgStrW xax
    invoke StrDispose, xax
  .else
    DbgWarning "No translation"
  .endif


In this case the output is "Abrir documento"

Biterider

HSE

Hi Biterider!

But correct translation is "Abrir archivo"  :biggrin: :biggrin: :biggrin:

HSE
Equations in Assembly: SmplMath

Biterider

Hi HSE
In this regard, DeepL does a better job.

Biterider

jj2007

Quote from: Biterider on November 15, 2022, 05:57:36 PM
In this regard, DeepL does a better job.

If I need a translation, I rarely use Google. DeepL does an incredible job (and I can judge it, I am 100% fluent in 4 languages). Even very difficult phrases get translated correctly, it's really flabbergasting what these guys have achieved.

Biterider

Hi
Looking at how DeepL can be used, it seems very complicated to use the web browser approach. It is easier to register and use the free version. Unfortunately, you have to give them your credit card information to register. An absolute no-go for me.  :sad:

Biterider

jj2007

With the Excel approach, see reply #1, DeepL is very easy to use. I select the English column:
&File
&New
&Open
&Save
&Save as...

E&xit
&Language
english
español
portogues
italiano
deutsch
français


Then I copy the column, paste it in DeepL and choose e.g. Spanish. Result:
&Archivo
&Nuevo
&Abrir
&Ahorro
&Guardar como...

E&Sit
&Idioma
inglés
english
portogues
italiano
alemán
francés


Ready to be pasted in the Spanish column of the spreadsheet, including even the ampersands :thumbsup:

And no hassle with registration or missing online access etc for the user.

Biterider

Hi JJ
There are many other ways to get multilingual support, including your spreadsheet approach, but that's not the goal here.
As explained in the very first post, the concept I am following is using an online service on the customer side, as it is practically impossible to provide all the languages offered by these services.

BTW, I don't think that's the intended translation "E&Sit". It seems that the & is handled in a special way... Google has a similar issue.

Biterider

Biterider

Hi
Looking again at the DeepL translations into Spanish using JJ's example, I saw the translation of "&Save" as "&Ahorro", which is completely wrong in this context. This shows me that this translator is also struggling with some isolated words. Maybe they can do better if the AI has more context from a full sentence.

Biterider

TimoVJL

What is a best word for context ?

option &Save

opción &Guardar
May the source be with you

Biterider

Hi TimoVJL
Exactly, that's what I mean. If you try to precede each item with the word "menu" then the result will be correct.
I guess it acts like a hint for the AI. I don't know if it works in all situations, but I will try it.

Biterider