Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add translations for any hard-coded text within widgets #144

Open
NewbieXvwu opened this issue Jan 20, 2022 · 80 comments · Fixed by #148, #151 or #153
Open

Add translations for any hard-coded text within widgets #144

NewbieXvwu opened this issue Jan 20, 2022 · 80 comments · Fixed by #148, #151 or #153
Assignees
Labels
enhancement New feature or request

Comments

@NewbieXvwu
Copy link
Contributor

Some custom windows (such as themed dialog boxes) are used in your program, but it seems that some of their contents are in English and cannot be changed. Would you mind providing an way to translate it to other languages? I am willing to help translate it into Chinese.

@israel-dryer
Copy link
Owner

@NewbieXvwu, thank you for submitting. This is a good catch.

Can you try running this code and post the results? I've read that this tcl/tk package can do the translations automatically... that would be nice.

import tkinter as tk

def translate(text):
    return root.tk.eval("namespace eval ::tk {::msgcat::mc %s}" % text)


root = tk.Tk()
tk.Button(root, text=translate("retry")).pack()
root.mainloop()

image

@israel-dryer israel-dryer self-assigned this Jan 20, 2022
@israel-dryer israel-dryer added the enhancement New feature or request label Jan 20, 2022
@israel-dryer israel-dryer changed the title Translate Add translations for any hard-coded text within widgets Jan 20, 2022
@israel-dryer
Copy link
Owner

User test
FB_IMG_1642719122574.jpg

@israel-dryer
Copy link
Owner

User test
FB_IMG_1642720277598.jpg

@NewbieXvwu
Copy link
Contributor Author

image

@NewbieXvwu
Copy link
Contributor Author

My operating system is in Chinese, but it doesn't seem to translate... Maybe the translation function only supports some languages.

@NewbieXvwu
Copy link
Contributor Author

Another possibility is that the translation function calls Google translation. Chinese mainland can not visit Google translation.

@NewbieXvwu
Copy link
Contributor Author

Maybe only Linux system supports this function? I don't have a Linux environment.

@israel-dryer
Copy link
Owner

@NewbieXvwu I forced my system to german swiss and it worked on Windows 11. For some reason, I can't get it to work with the Chinese locale codes though.

What result do you get if you run this?

from gettext import gettext

result = gettext('Retry')
print(result)

@NewbieXvwu
Copy link
Contributor Author

NewbieXvwu commented Jan 21, 2022

Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
from gettext import gettext
result = gettext('Retry')
print(result)
Retry

@NewbieXvwu
Copy link
Contributor Author

Maybe there is no Chinese translation in tk?

@NewbieXvwu
Copy link
Contributor Author

My idea is this: add a file similar to "en_US.json". When the program needs to read hard coded data, read it from the file, and automatically read the file similar to "zh_CN.json" by judging the system language setting to realize translation. This may be a supplement to TK's own translation function.

@israel-dryer
Copy link
Owner

@NewbieXvwu, I think this is something that is important to fix, but I'll need some time to consider the best way to implement something like this. At a minimum I could probably add a module that includes translations of standard labels used in custom widgets and dialogs.

@israel-dryer
Copy link
Owner

@NewbieXvwu, It looks like this mapping can be done within tcl/tk. I used google translate so hopefully it is right.

image

I used the first command listed below, the 2nd one could be used to map multiple translations at once for a single locale.

::msgcat::mcset locale src-string ?translate-string?
Sets the translation for src-string to translate-string in the specified locale and the current namespace. If translate-string is not specified, src-string is used for both. The function returns translate-string.

::msgcat::mcmset locale src-trans-list
Sets the translation for multiple source strings in src-trans-list in the specified locale and the current namespace. src-trans-list must have an even number of elements and is in the form {src-string translate-string ?src-string translate-string ...?} ::msgcat::mcmset can be significantly faster than multiple invocations of ::msgcat::mcset. The function returns the number of translations set.

If you will compile a list of all the translations you think I will need, I'll add it in a test module and we can see how it works in the application. Then we can test how it might scale to the other languages that are not supported (apparently) by tkinter.

@NewbieXvwu
Copy link
Contributor Author

I think your idea is very good. What can I do for you now?

@NewbieXvwu
Copy link
Contributor Author

I hope to separate the translation file from the code (similar to "zh_CN.json"), so that even people without Python basics can participate in the translation.

@NewbieXvwu
Copy link
Contributor Author

I heard TK offered a "zh_cn.msg" file can help with translation.

@israel-dryer
Copy link
Owner

israel-dryer commented Jan 21, 2022

I don't see one. But we can definitely use one of these as a template.

https://github.com/tcltk/tk/tree/main/library%2Fmsgs

Would you mind taking one of these msg files and converting it to Chinese?

Otherwise, if it's too big a task, I might be able to run a script to look them up.

@NewbieXvwu
Copy link
Contributor Author

NewbieXvwu commented Jan 21, 2022

Wait a moment. I'm trying translate from en.msg.

@NewbieXvwu
Copy link
Contributor Author

zh_cn.zip
I am not a professional translator. This translation may contain errors. It is based on "en.msg".

@NewbieXvwu
Copy link
Contributor Author

I tested it on Kubuntu virtual machine. It doesn't seem to be a problem with Windows itself.
image

@NewbieXvwu
Copy link
Contributor Author

When I am free, I may be able to help translate your documents.

@antrrax
Copy link
Contributor

antrrax commented Jan 21, 2022

If possible also add translation for widgets.

weblate offers a free hosting plan, I don't know if it's compatible with tk inter

https://docs.weblate.org/en/latest/index.html
https://docs.weblate.org/en/latest/user/files.html

@israel-dryer
Copy link
Owner

@NewbieXvwu, two things... I created a check that loads the custom msg file if it's in a list of locales... which there is only one currently.

image

The other thing is that the msg file has to map between English and Chinese as you can see from this Russian msg file. I added it in manually for retry in the msg file, but we'll have to add the Chinese translation after the English word for all of them.

image

@NewbieXvwu
Copy link
Contributor Author

@antrrax I tried weblate, but it doesn't seem compatible with msg format.

@NewbieXvwu
Copy link
Contributor Author

zh_cn.zip

@israel-dryer I'm finished.

@NewbieXvwu
Copy link
Contributor Author

@israel-dryer What should be "langdir" in your code?

@israel-dryer
Copy link
Owner

@israel-dryer What should be "langdir" in your code?

That's the directory that contains the msg file

@antrrax
Copy link
Contributor

antrrax commented Jan 23, 2022

Your work was excellent, congratulations for your dedication.

I did a PR for the pt translation.

But it might be more appropriate to create a 'pt_br' file, as Brazilian Portuguese is different from Portuguese from Portugal


I did some tests here.

Some questions about the translation:
The Fonts dialog has some terms with no translation option yet.
01

Regarding the term "Slant" in the font dialog, it might be more suitable for internationalization purposes to change it to "Style". As it is the most common term that users are used to and would facilitate the reuse of the term for translation.
00
Ps: In the file I send I used the Portuguese term for Style.


In the future, do you intend to add translation for the Color dialog, the DatePickerDialog, and the Tableview?

@israel-dryer
Copy link
Owner

Your work was excellent, congratulations for your dedication.

I did a PR for the pt translation.
But it might be more appropriate to create a 'pt_br' file, as Brazilian Portuguese is different from Portuguese from Portugal

I did some tests here.

Some questions about the translation: The Fonts dialog has some terms with no translation option yet. 01

Regarding the term "Slant" in the font dialog, it might be more suitable for internationalization purposes to change it to "Style". As it is the most common term that users are used to and would facilitate the reuse of the term for translation. 00 Ps: In the file I send I used the Portuguese term for Style.

In the future, do you intend to add translation for the Color dialog, the DatePickerDialog, and the Tableview?

If you see something that you think should get a translation, submit a PR of the change.

  1. Add the mapping in the msg file.
  2. Add the new word or phrase in the README.txt in the localization module (this will help us keep track of the words that need translated - it's going to be a group effort).
  3. Use the following method on the text you want to translate:
MessageCatalog.translate("text you want to translate")

@antrrax
Copy link
Contributor

antrrax commented Jan 24, 2022

MessageCatalog.translate("text you want to translate")

I searched for the terms to be translated. Here is the sample in Brazilian Portuguese.

pt_br.msg:

::msgcat::mcset pt_br "Ok" "Ok"
::msgcat::mcset pt_br "Retry" "Repetir"
::msgcat::mcset pt_br "Delete" "Exlcuir"
::msgcat::mcset pt_br "Next" "Próximo"
::msgcat::mcset pt_br "Prev" "Anterior"
::msgcat::mcset pt_br "Yes" "Sim"
::msgcat::mcset pt_br "No" "Não"
::msgcat::mcset pt_br "Open" "Abrir"
::msgcat::mcset pt_br "Close" "Fechar"
::msgcat::mcset pt_br "Add" "Adicionar"
::msgcat::mcset pt_br "Remove" "Remover"
::msgcat::mcset pt_br "Submit" "Enviar"
::msgcat::mcset pt_br "Family" "Família"
::msgcat::mcset pt_br "Weight" "Espessura"
::msgcat::mcset pt_br "Slant" "Estilo"
::msgcat::mcset pt_br "Effects" "Efeitos"
::msgcat::mcset pt_br "Preview" "Visualizar"
::msgcat::mcset pt_br "Size" "Tamanho"
::msgcat::mcset pt_br "Should be of data type" "Deve ser do tipo de dados"
::msgcat::mcset pt_br "Invalid data type" "Tipo de dados inválido"
::msgcat::mcset pt_br "Number cannot be greater than" "O número não deve ser maior que"
::msgcat::mcset pt_br "Out of range" "Fora do limite"
::msgcat::mcset pt_br "Submit" "Enviar"
::msgcat::mcset pt_br "Delete" "Excluir"
::msgcat::mcset pt_br "Next" "Próximo"
::msgcat::mcset pt_br "Previous" "Anterior"
::msgcat::mcset pt_br "Open" "Abrir"
::msgcat::mcset pt_br "Close" "Fechar"
::msgcat::mcset pt_br "Add" "Adicionar"
::msgcat::mcset pt_br "Remove" "Remover"
::msgcat::mcset pt_br "Family" "Família"
::msgcat::mcset pt_br "Weight" "Espessura"
::msgcat::mcset pt_br "Slant" "Estilo"
::msgcat::mcset pt_br "Effects" "Efeitos"
::msgcat::mcset pt_br "Preview" "Visualizar"
::msgcat::mcset pt_br "Size" "Tamanho"
::msgcat::mcset pt_br "The quick brown fox jumps over the lazy dog." "A rápida raposa marrom pula sobre o cachorro preguiçoso."

::msgcat::mcset pt_br "Font Selector" "Seletor de Fontes"
::msgcat::mcset pt_br "normal" "normal"
::msgcat::mcset pt_br "bold"  "negrito"
::msgcat::mcset pt_br "roman" "romano"
::msgcat::mcset pt_br "italic" "itálico"
::msgcat::mcset pt_br "underline" "sublinhado"
::msgcat::mcset pt_br "overstrike" "taxado"
::msgcat::mcset pt_br "Color Chooser" "Seletor de Cores"
::msgcat::mcset pt_br "Advanced" "Avançado"
::msgcat::mcset pt_br "Themd" "Tema"
::msgcat::mcset pt_br "Standard" "Básicas"
::msgcat::mcset pt_br "Current" "Atual"
::msgcat::mcset pt_br "New" "Nova"
::msgcat::mcset pt_br "Red" "Vermelho"
::msgcat::mcset pt_br "Green" "Verde"
::msgcat::mcset pt_br "Blue" "Azul"
::msgcat::mcset pt_br "color dropper" "Selecionador de cores (conta-gotas)"
::msgcat::mcset pt_br "January" "Janeiro"
::msgcat::mcset pt_br "February" "Fevereiro"
::msgcat::mcset pt_br "March" "Março"
::msgcat::mcset pt_br "April" "Abril"
::msgcat::mcset pt_br "May" "Maio"
::msgcat::mcset pt_br "June" "Junho"
::msgcat::mcset pt_br "July" "Julho"
::msgcat::mcset pt_br "August" "Agosto"
::msgcat::mcset pt_br "September" "Setembro"
::msgcat::mcset pt_br "October" "Outubro"
::msgcat::mcset pt_br "November" "Novembro"
::msgcat::mcset pt_br "December" "Dezembro"
::msgcat::mcset pt_br "Su" "D"
::msgcat::mcset pt_br "Mo" "S"
::msgcat::mcset pt_br "Tu" "T"
::msgcat::mcset pt_br "We" "Q"
::msgcat::mcset pt_br "Th" "Q"
::msgcat::mcset pt_br "Fr" "S"
::msgcat::mcset pt_br "Sa" "S"
::msgcat::mcset pt_br "Search" "Buscar"
::msgcat::mcset pt_br "Page" "Página"
::msgcat::mcset pt_br "of" "de"
::msgcat::mcset pt_br "Reset table" "Resetar Tabela"
::msgcat::mcset pt_br "Columns" "Colunas"
::msgcat::mcset pt_br "Move" "Mover"
::msgcat::mcset pt_br "Align" "Alinhar"
::msgcat::mcset pt_br "Hide column" "Ocultar coluna"
::msgcat::mcset pt_br "Delete column" "Excluir coluna"
::msgcat::mcset pt_br "Show All" "Exibir todas"
::msgcat::mcset pt_br "Move to left" "Mover para esquerda"
::msgcat::mcset pt_br "Move to right" "Mover para direira"
::msgcat::mcset pt_br "Move to first" "Mover para o início"
::msgcat::mcset pt_br "Move to last" "Mover para o fim"
::msgcat::mcset pt_br "Align left" "Alinhar à esquerda"
::msgcat::mcset pt_br "Align center" "Alinhar ao centro"
::msgcat::mcset pt_br "Align right" "Alinhar à direita"
::msgcat::mcset pt_br "Sort" "Classificar"
::msgcat::mcset pt_br "Filter" "Filtrar"
::msgcat::mcset pt_br "Export" "Exportar"
::msgcat::mcset pt_br "Move" "Mover"
::msgcat::mcset pt_br "Align" "Alinhar"
::msgcat::mcset pt_br "Delete selected rows" "Excluir linhas selecionadas"
::msgcat::mcset pt_br "Sort Ascending" "Ordem crescente"
::msgcat::mcset pt_br "Sort Descending" "Ordem decrescente"
::msgcat::mcset pt_br "Clear filters" "Limpar filtros"
::msgcat::mcset pt_br "Filter by cell's value" "Filtrar pelo valor da célula"
::msgcat::mcset pt_br "Hide select rows" "Ocultar linha selecionada"
::msgcat::mcset pt_br "Show only select rows" "Exibir somente as linhas selecionadas"
::msgcat::mcset pt_br "Export all records" "Exportar todos os dados"
::msgcat::mcset pt_br "Export current page" "Exportar página atual"
::msgcat::mcset pt_br "Export current selection" "Exportar seleção atual"
::msgcat::mcset pt_br "Export records in filter" "Exportar dados do filtro"
::msgcat::mcset pt_br "Move up" "Mover para cima"
::msgcat::mcset pt_br "Move down" "Mover para baixo"
::msgcat::mcset pt_br "Move to top" "Mover para o início"
::msgcat::mcset pt_br "Move to bottom" "Mover para o fim"
::msgcat::mcset pt_br "Align left" "Alinhar à esquerda"
::msgcat::mcset pt_br "Align center" "Alinhar ao centro"
::msgcat::mcset pt_br "Align right" "Alinhar à direita"

on the recommended site to generate the language code:
https://wiki.freepascal.org/Language_Codes

uses hyfem to separate language from country (pt-br)
in your chinese sample, the file used the underscore symbol (zh_cn). Which symbol should be used "-" or "_"?


The windows title cannot be translated. It shows an error there try to use this
"MessageCatalog.translate()"


From what I've observed, you search for the translation by the term and not by a code.

In your Readme file, list some repeated terms. The question remains, how does the code deal with this? Using the term to search for a translation is a serious problem, as there are some words that in English can have more than one meaning depending on the context. Ex: glass, can
The correct thing would be to create code for the terms to be translated.

Another example, "Slant" the literal translation would be "inclinado". However, in fluent Portuguese, no one would use this term to refer to the style of a font. ("Slant" - "inclinado") would be used in the context of a "sloping" street (rua "inclinada")

Reusing terms is problematic, as translation depends on context.


Complement;

Another problem, in English some words do not have gender or plural variation.

term: New

English example: New Folder
Portuguese translation: Nova Pasta

English example: New Document
Portuguese translation: Novo Documento

English example (plural): New Documents
Portuguese translation (plural): Novos Documentos

Portuguese translation: 'Novo' (masculine)
Portuguese translation: 'Nova' (feminine)


In fluent Portuguese 'Weight' refers to the mass of an object. So the literal translation would be correct in the mass context, but wrong in the font property context. Reusing English terms will have translation context problems. The correct thing is that each sentence has its own translation.

That's why it's important to use code to search for a term/phrase

@israel-dryer
Copy link
Owner

israel-dryer commented Jan 24, 2022

MessageCatalog.translate("text you want to translate")

I searched for the terms to be translated. Here is the sample in Brazilian Portuguese.

pt_br.msg:

::msgcat::mcset pt_br "Ok" "Ok"
::msgcat::mcset pt_br "Retry" "Repetir"
::msgcat::mcset pt_br "Delete" "Exlcuir"
::msgcat::mcset pt_br "Next" "Próximo"
::msgcat::mcset pt_br "Prev" "Anterior"
::msgcat::mcset pt_br "Yes" "Sim"
::msgcat::mcset pt_br "No" "Não"
::msgcat::mcset pt_br "Open" "Abrir"
::msgcat::mcset pt_br "Close" "Fechar"
::msgcat::mcset pt_br "Add" "Adicionar"
::msgcat::mcset pt_br "Remove" "Remover"
::msgcat::mcset pt_br "Submit" "Enviar"
::msgcat::mcset pt_br "Family" "Família"
::msgcat::mcset pt_br "Weight" "Espessura"
::msgcat::mcset pt_br "Slant" "Estilo"
::msgcat::mcset pt_br "Effects" "Efeitos"
::msgcat::mcset pt_br "Preview" "Visualizar"
::msgcat::mcset pt_br "Size" "Tamanho"
::msgcat::mcset pt_br "Should be of data type" "Deve ser do tipo de dados"
::msgcat::mcset pt_br "Invalid data type" "Tipo de dados inválido"
::msgcat::mcset pt_br "Number cannot be greater than" "O número não deve ser maior que"
::msgcat::mcset pt_br "Out of range" "Fora do limite"
::msgcat::mcset pt_br "Submit" "Enviar"
::msgcat::mcset pt_br "Delete" "Excluir"
::msgcat::mcset pt_br "Next" "Próximo"
::msgcat::mcset pt_br "Previous" "Anterior"
::msgcat::mcset pt_br "Open" "Abrir"
::msgcat::mcset pt_br "Close" "Fechar"
::msgcat::mcset pt_br "Add" "Adicionar"
::msgcat::mcset pt_br "Remove" "Remover"
::msgcat::mcset pt_br "Family" "Família"
::msgcat::mcset pt_br "Weight" "Espessura"
::msgcat::mcset pt_br "Slant" "Estilo"
::msgcat::mcset pt_br "Effects" "Efeitos"
::msgcat::mcset pt_br "Preview" "Visualizar"
::msgcat::mcset pt_br "Size" "Tamanho"
::msgcat::mcset pt_br "The quick brown fox jumps over the lazy dog." "A rápida raposa marrom pula sobre o cachorro preguiçoso."

::msgcat::mcset pt_br "Font Selector" "Seletor de Fontes"
::msgcat::mcset pt_br "normal" "normal"
::msgcat::mcset pt_br "bold"  "negrito"
::msgcat::mcset pt_br "roman" "romano"
::msgcat::mcset pt_br "italic" "itálico"
::msgcat::mcset pt_br "underline" "sublinhado"
::msgcat::mcset pt_br "overstrike" "taxado"
::msgcat::mcset pt_br "Color Chooser" "Seletor de Cores"
::msgcat::mcset pt_br "Advanced" "Avançado"
::msgcat::mcset pt_br "Themd" "Tema"
::msgcat::mcset pt_br "Standard" "Básicas"
::msgcat::mcset pt_br "Current" "Atual"
::msgcat::mcset pt_br "New" "Nova"
::msgcat::mcset pt_br "Red" "Vermelho"
::msgcat::mcset pt_br "Green" "Verde"
::msgcat::mcset pt_br "Blue" "Azul"
::msgcat::mcset pt_br "color dropper" "Selecionador de cores (conta-gotas)"
::msgcat::mcset pt_br "January" "Janeiro"
::msgcat::mcset pt_br "February" "Fevereiro"
::msgcat::mcset pt_br "March" "Março"
::msgcat::mcset pt_br "April" "Abril"
::msgcat::mcset pt_br "May" "Maio"
::msgcat::mcset pt_br "June" "Junho"
::msgcat::mcset pt_br "July" "Julho"
::msgcat::mcset pt_br "August" "Agosto"
::msgcat::mcset pt_br "September" "Setembro"
::msgcat::mcset pt_br "October" "Outubro"
::msgcat::mcset pt_br "November" "Novembro"
::msgcat::mcset pt_br "December" "Dezembro"
::msgcat::mcset pt_br "Su" "D"
::msgcat::mcset pt_br "Mo" "S"
::msgcat::mcset pt_br "Tu" "T"
::msgcat::mcset pt_br "We" "Q"
::msgcat::mcset pt_br "Th" "Q"
::msgcat::mcset pt_br "Fr" "S"
::msgcat::mcset pt_br "Sa" "S"
::msgcat::mcset pt_br "Search" "Buscar"
::msgcat::mcset pt_br "Page" "Página"
::msgcat::mcset pt_br "of" "de"
::msgcat::mcset pt_br "Reset table" "Resetar Tabela"
::msgcat::mcset pt_br "Columns" "Colunas"
::msgcat::mcset pt_br "Move" "Mover"
::msgcat::mcset pt_br "Align" "Alinhar"
::msgcat::mcset pt_br "Hide column" "Ocultar coluna"
::msgcat::mcset pt_br "Delete column" "Excluir coluna"
::msgcat::mcset pt_br "Show All" "Exibir todas"
::msgcat::mcset pt_br "Move to left" "Mover para esquerda"
::msgcat::mcset pt_br "Move to right" "Mover para direira"
::msgcat::mcset pt_br "Move to first" "Mover para o início"
::msgcat::mcset pt_br "Move to last" "Mover para o fim"
::msgcat::mcset pt_br "Align left" "Alinhar à esquerda"
::msgcat::mcset pt_br "Align center" "Alinhar ao centro"
::msgcat::mcset pt_br "Align right" "Alinhar à direita"
::msgcat::mcset pt_br "Sort" "Classificar"
::msgcat::mcset pt_br "Filter" "Filtrar"
::msgcat::mcset pt_br "Export" "Exportar"
::msgcat::mcset pt_br "Move" "Mover"
::msgcat::mcset pt_br "Align" "Alinhar"
::msgcat::mcset pt_br "Delete selected rows" "Excluir linhas selecionadas"
::msgcat::mcset pt_br "Sort Ascending" "Ordem crescente"
::msgcat::mcset pt_br "Sort Descending" "Ordem decrescente"
::msgcat::mcset pt_br "Clear filters" "Limpar filtros"
::msgcat::mcset pt_br "Filter by cell's value" "Filtrar pelo valor da célula"
::msgcat::mcset pt_br "Hide select rows" "Ocultar linha selecionada"
::msgcat::mcset pt_br "Show only select rows" "Exibir somente as linhas selecionadas"
::msgcat::mcset pt_br "Export all records" "Exportar todos os dados"
::msgcat::mcset pt_br "Export current page" "Exportar página atual"
::msgcat::mcset pt_br "Export current selection" "Exportar seleção atual"
::msgcat::mcset pt_br "Export records in filter" "Exportar dados do filtro"
::msgcat::mcset pt_br "Move up" "Mover para cima"
::msgcat::mcset pt_br "Move down" "Mover para baixo"
::msgcat::mcset pt_br "Move to top" "Mover para o início"
::msgcat::mcset pt_br "Move to bottom" "Mover para o fim"
::msgcat::mcset pt_br "Align left" "Alinhar à esquerda"
::msgcat::mcset pt_br "Align center" "Alinhar ao centro"
::msgcat::mcset pt_br "Align right" "Alinhar à direita"

on the recommended site to generate the language code: https://wiki.freepascal.org/Language_Codes

uses hyfem to separate language from country (pt-br) in your chinese sample, the file used the underscore symbol (zh_cn). Which symbol should be used "-" or "_"?

The windows title cannot be translated. It shows an error there try to use this "MessageCatalog.translate()"

From what I've observed, you search for the translation by the term and not by a code.

In your Readme file, list some repeated terms. The question remains, how does the code deal with this? Using the term to search for a translation is a serious problem, as there are some words that in English can have more than one meaning depending on the context. Ex: glass, can The correct thing would be to create code for the terms to be translated.

Another example, "Slant" the literal translation would be "inclinado". However, in fluent Portuguese, no one would use this term to refer to the style of a font. ("Slant" - "inclinado") would be used in the context of a "sloping" street (rua "inclinada")

Reusing terms is problematic, as translation depends on context.

Complement;

Another problem, in English some words do not have gender or plural variation.

term: New

English example: New Folder Portuguese translation: Nova Pasta

English example: New Document Portuguese translation: Novo Documento

English example (plural): New Documents Portuguese translation (plural): Novos Documentos

Portuguese translation: 'Novo' (masculine) Portuguese translation: 'Nova' (feminine)

In fluent Portuguese 'Weight' refers to the mass of an object. So the literal translation would be correct in the mass context, but wrong in the font property context. Reusing English terms will have translation context problems. The correct thing is that each sentence has its own translation.

That's why it's important to use code to search for a term/phrase

I think the MessageCatalog component has a very limited application... localizing button text and labels and other standard application elements. The 'msg' file acts almost like a python dictionary where it looks the term used and attempts to find a match. It's also case sensitive from what I can tell, so it treats "ok", "Ok", and "OK" as 3 separate tokens. This is why you may see a repeated term with different capitalization applied. It's a simplistic mechanism for translating your buttons and labels via the use of msg files instead of putting that business logic in your code.

When looking for a translation, I would go for the meaning and not necessarily a literal translation. I'm guessing there is a typical way that different localities handle ok, cancel, new, etc... So, if you are familiar with that culture, I would leave it up to you to convey the correct meaning with the mapped term.

Can you show the error you get when translating the title?

@antrrax
Copy link
Contributor

antrrax commented Jan 24, 2022

Can you show the error you get when translating the title?

Dialog titles are in the class initializer definition.

file: ..../ttkbootstrap/dialogs/dialogs.py
line 882:
def __init__(self, title="Font Selector", parent=None):

wrong way to try to translate the title:
def __init__(self, title=MessageCatalog.translate("Font Selector"), parent=None):


file: ..../ttkbootstrap/dialogs/colorchooser.py
line 512:
def __init__(self, parent=None, title="Color Chooser", initialcolor=None):

@antrrax
Copy link
Contributor

antrrax commented Jan 24, 2022

This is why you may see a repeated term with different capitalization applied

In the new README file that is on github, all repeated terms are identical.

the term 'Family' is repeated, and is identical: it has the same letters and case.

@israel-dryer
Copy link
Owner

This is why you may see a repeated term with different capitalization applied

In the new README file that is on github, all repeated terms are identical.

the term 'Family' is repeated, and is identical: it has the same letters and case.

Ok. Then it must is have been an oversight on my part, copying and pasting.

@israel-dryer
Copy link
Owner

Can you show the error you get when translating the title?

Dialog titles are in the class initializer definition.

file: ..../ttkbootstrap/dialogs/dialogs.py
line 882:
def __init__(self, title="Font Selector", parent=None):

wrong way to try to translate the title:
def __init__(self, title=MessageCatalog.translate("Font Selector"), parent=None):


file: ..../ttkbootstrap/dialogs/colorchooser.py
line 512:
def __init__(self, parent=None, title="Color Chooser", initialcolor=None):

You can translate the term above the super() and then pass the translated term into the call to super()

@antrrax
Copy link
Contributor

antrrax commented Jan 24, 2022

With this modification it worked:

from ttkbootstrap.localization import MessageCatalog


     def __init__(self, title="Font Selector", parent=None):
         title = MessageCatalog.translate(title)
         super().__init__(parent=parent, title=title)

@antrrax
Copy link
Contributor

antrrax commented Jan 24, 2022

I did the translation of the terms.

In ColorChooserDialog
Cancel button, cut translated string


In DateEntry, I didn't find a way to translate the name of the months and the abbreviation of the days of the week.
It would be interesting to add this option


FontDialog all ok


In the tableview there are many symbols next to the names, at first I chose to include the symbols in the translation. But the symbol "🞨" of the "Delete column" and "Delete selected rows" did not accept the translation. So I would have to format these strings in another way.
How do you prefer this formatting, can it be f-string with three single quotes? (to allow using single/double quotes in the English string content):

f'''🞨 {MessageCatalog.translate("Delete selected rows")}'''


See the files as they were after this initial modification, once you decide on which string formatting pattern I will redo:
https://www.mediafire.com/file/objrhl68zwt01rw/ttkbootstrap_src.zip/file


00

01

02

04

03

@israel-dryer
Copy link
Owner

  • We probably need to remove the fixed size of the buttons on the Color Chooser and let the geometry manager decide. That should fix the cut off text. I'll have to check the other dialogs to make sure this is setup consistently, especially now that the button text will vary in size.

  • There is probably a date localization in the datetime module that we can explore for localized dates, months, and week names, etc.

  • I think the f strings are perfect. This is not going to be running on anything less than Python 3.7 and I use f strings in many other places.

@israel-dryer
Copy link
Owner

Posting for reference on getting localized date info

https://stackoverflow.com/a/26927760

@antrrax
Copy link
Contributor

antrrax commented Jan 25, 2022

Using the tip from the link above, I changed the dialogs file to display the month name in the default language of the user's system.

I tested it here on linux on the real machine, and on win 10 on a virtual machine in the pt_br language and it worked. I don't know how it would behave in other languages.

See if you agree with the resolution:

line 11:
import locale

line 609:
locale.setlocale(locale.LC_ALL, locale.setlocale(locale.LC_TIME,''))

line 746

    def _set_title(self):
        _titledate = f'{self.date.strftime("%B %Y")}'
        self.titlevar.set(value=_titledate.capitalize())

View the modified file:
dialogs.py.zip
01

@NewbieXvwu
Copy link
Contributor Author

@israel-dryer How can I translate the toast documation?

@israel-dryer
Copy link
Owner

@israel-dryer How can I translate the toast documation?

The API docs are tricky because the documentation is in the docstring. My best solution is to copy the docstring from the source document and then put it into this format using markdown. This version is live, so you can see what it looks like online. I was not able to replicate all of the look & feel of the original without resorting to HTML, which would be too tedious to maintain.

The markdown
https://github.com/israel-dryer/ttkbootstrap/blob/master/docs/api/toast.zh.md

What it looks like online
https://ttkbootstrap.readthedocs.io/en/latest/zh/api/toast/

@antrrax
Copy link
Contributor

antrrax commented Jan 28, 2022

@israel-dryer

On the documentation page, would it be possible to restrict the search to the selected language only?
As is now the search results appear duplicated (English and Chinese)

For example, search for the term:

utility module

@israel-dryer
Copy link
Owner

@israel-dryer

On the documentation page, would it be possible to restrict the search to the selected language only? As is now the search results appear duplicated (English and Chinese)

For example, search for the term:

utility module

Unfortunately, it doesn't look like that feature is supported yet. https://github.com/ultrabug/mkdocs-static-i18n#compatibility-with-the-search-plugin

However, once the documents are fully translated, it should not be an issue since the word 'Utility' will not be shown in English characters.

@NewbieXvwu
Copy link
Contributor Author

@israel-dryer Can I read another file according to the language selection when reading the string in the file?

@israel-dryer
Copy link
Owner

@israel-dryer Can I read another file according to the language selection when reading the string in the file?

I'm not sure what you mean. Can you give an example?

@NewbieXvwu
Copy link
Contributor Author

Can I store descriptions in two different languages in the source file and read them on demand?

@israel-dryer
Copy link
Owner

Can I store descriptions in two different languages in the source file and read them on demand?

Yes, this is possible, and believe it or not, very simple. Here's a minimal example. You just have to pass in the locale and a list of word pairs.

from ttkbootstrap.localization import MessageCatalog
from ttkbootstrap.dialogs import Messagebox

msgs = [
    'OK', 'Yep',
    'Cancel', 'Nope'
]

MessageCatalog.set_many('en_us', *msgs)
Messagebox.okcancel('Do you like this custom translation?')

This produces the following window
python_PDTuUDgcLS

When trying to figure out how to do this, I did find a bug in the function, so I'll push that update to github now, and I'll make sure it's part of 1.6.2.

@israel-dryer israel-dryer pinned this issue Feb 7, 2022
@NewbieXvwu
Copy link
Contributor Author

@israel-dryer You may not understand what I mean... I mean that I can't translate the contents of all "style guide" sections because they are rendered by reading data from py source files. Can I store text in two languages in py source files for translation?

@israel-dryer
Copy link
Owner

Oh. I'm not sure yet. Because we are talking about the contents of the python files, we might be better off approaching this with the pot/po files and the gettext module, or babel library. However, I'd have to do some research on that personally. I've not done large-scale translation projects before, and that will require some setup for it to work smoothly.

@NewbieXvwu
Copy link
Contributor Author

@israel-dryer Perhaps you can use a GitHub Action script to automatically generate a markdown file from the py file at each commit. I know a little bit about GitHub Action.

@antrrax
Copy link
Contributor

antrrax commented Feb 26, 2022

@NewbieXvwu
Copy link
Contributor Author

@antrrax Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
3 participants