Aplicação Multi Idiomas com TLang no Delphi 10 Seattle

Veja nesta postagem como adicionar o recurso de multi idiomas as suas aplicações mobile desenvolvidas com Delphi 10 Seattle utilizando o componente TLang.

Com a alta do dólar desenvolver uma aplicação contando com o suporte a mais de um idioma passa a ser uma boa estratégia para os desenvolvedores que pretende lançar seus produtos em novos mercados.

Carlos Henrique Agnes - Tatu
Carlos Henrique Agnes – Tatu

Em abril de 2013, o MVP da Embarcadero Carlos Henrique Agnes, O Tatu, escrevia sobre suas impressões sobre uma das versões betas do RAD Studio na postagem: Delphi for iOS, nela Tatu abordava rapidamente o componente TLang, que ainda existe e acaba passando desapercebido pela maioria dos desenvolvedores Delphi.

TLang

TLang: um pouco sobre o componente

Presente no RAD Studio desde a versão XE2, o  TLang é um componente não visual pertencente à biblioteca do FireMonkey, e não está acessível à VCL.

FireMonkey - FMX
Nota 1 : FireMonkey - O FMX framework é a plataforma de desenvolvimento de aplicações e tempo de execução por trás do RAD Studio (Delphi e C++ Builder). FMX foi desenhada para equipes que estejam construindo aplicações multidispositivos verdadeiramente nativas para Windows, Mac, Android e iOS, levando-as a lojas de aplicações e corporações de modo acelerado.

Basicamente o TLang funciona fazendo a conversão de strings para outros idiomas previamente configurados no Language Designer.

Algumas propriedades do TLang merecem ser destacadas para um melhor entendimento e futura utilização, vamos a elas:

  • Lang –> Utilizada para informar o idioma atualmente utilizado no TLang, consequentemente a ser passado para a aplicação.
  • StoreInForm –> Informa se as definições aplicadas ao TLang serão armazenadas no formulário. Quando “false”, as definições deve ser carregadas através do método LoadFromFile.
  • FileName –> Determina se o TLang deve selecionar automaticamente o valor a partir da lista de idiomas e aplicá-lo.

Criando nossa aplicação Multi Idiomas

Vamos iniciar o Delphi 10 Seattle e criar uma nova aplicação Multi Dispositivo, como já fizemos várias vezes em File->New->Muli Device Application – Delphi.

Em nosso formulário principal vamos atribuir alguns componentes: 3 Label, 2 Edit, 1 Memo, 3 Button e configurá-los como descrito abaixo:

  • Label 1.Text -> ‘Idioma do Dispositivo’;
  • Labe2.Text -> ‘Nome’;
  • Label3.Text->‘Conteúdo do Memo’;
  • Edit2.Text -> ‘Insira seu nome’;
  • Button1.Text  -> ‘Botão Erro’;
  • Button2.Text -> ‘Português’;
  • Button3.Text -> ‘Inglês’;

Lembre-se também de alterar em todos os Labels a propriedade AutoSize para True, isso fará com que o conteúdo da propriedade text não seja “cortado”.

Vou inserir também uma imagem, com a propriedade align setada como Botton e Wrap Mode como stretch, apenas para dar uma cara apresentável a nossa aplicação.

Adicionando o ingrediente Principal: TLang

Vamos inserir no nosso aplicação um TLang, na paleta Standard, para facilitar a compreensão vou alterar sua propriedade Name para Tradutor.

TLang na paleta de componentes do Delphi 10 Seattle

[Off]: Há poucos dias tive o desprazer de descobrir que havia um indivíduo copiando as minhas postagens aqui e publicando no seu site como se eu fosse um escritor de seu portal.  Saiba quais "ramos" você vai seguir na sua vida, existem uns picaretas por aí.

Para garantir, vou inserir no formulário mais um Image agora com align Top e Wrap Mode também como Stretch. Com isso, a aparência de nossa aplicação será próxima à imagem abaixo:

Aparência Aplicação Multi idiomas

Salve sua aplicação, no meu caso chamei o Form de frmPrincipal e sua Unit de frmPrincipalUnt, o Projeto salvei como MultiIdiomas.

Preparando o TLang: Language Designer

Selecione na tela o componente TLang, e no Object Inspector vá até sua propriedade Lang e clique sobre o botão “…”.

Propriedade Lang do TLang

Isso fará com que seja aberto o Language Designer. Ele é a interface de configuração para inserirmos os idiomas no TLang. Note que ao abrir o Language Designer já carrega as strings que ele encontrou na aplicação, confira na imagem abaixo algumas considerações sobre o Language Designer:

Language Designer

Na prática lidar com o Language Designer é extremamente simples, vamos fazer isso a partir de agora.

Na caixa “two letter language code:” vamos inserir “BR”, em alusão a Brasil, poderia ser qualquer sequência de 2 letras,  em seguida clicar sobre o botão Add, isso fará com que nosso idioma BR seja inserido no TLang nos possibilitando agora configurar os valores para cada uma das strings informadas no Language Designer. Veja que já preenchi alguns valores.

Inserindo Idioma no Language Designer

Assim sendo as strings da esquerda quando o idioma selecionado estiver em uso serão substituídas pelos seus respectivos valores à direita.

Agora que você já se familiarizou um pouco, vamos preparar a tradução de outras strings como o conteúdo do Edit2 e do Memo, este último passaremos em tempo de execução. Clique sobre o botão “+” ele abrirá espaço para digitarmos uma nova string a ser traduzida na caixa superior “New original text“, com isso vamos inserir o mesmo conteúdo que passamos anteriormente para a propriedade Text do Edit2” ‘Insira seu nome’ , clique sobre o botão Add para confirmar a inclusão da string e altere o seu valor para tradução insira: Seu nome de usuário.  Vamos repetir o procedimento criando um novo valor original: ” ‘Linha 1′  que será traduzido para Observação 1.

No caso do Idioma BR, ficamos com a seguinte configuração:

  • Idioma do Dispositivo ->”Idioma do aparelho”
  • Nome -> “Nome de Usuário”
  • Conteúdo do Memo -> “Observação”
  • Botão Erro ->”Gerar Exceção”
  • Português -> “Português BR”
  • Inglês -> “Inglês”
  • ‘Insira seu nome’ -> “Seu nome de usuário”
  • ‘Linha 1’ ->  “Observação 1”

Agora vamos fazer o mesmo processo inserindo o idioma inglês, que será representado na caixa “two letter language code:”  com a sequência “EN“.

Idioma Inglês - Language Designer

Sua tradução para Inglês, “EN”, deve ficar como especificado abaixo:

  • Idioma do Dispositivo ->”Device Language”
  • Nome -> “User Name”
  • Conteúdo do Memo -> “Observation”
  • Botão Erro ->”Error Button”
  • Português -> “Portuguese”
  • Inglês -> “English”
  • ‘Insira seu nome’ -> “Your user name”
  • ‘Linha 1’ ->  “Line 1”
Atenção: Repare que onde são strings passadas em componentes que não possuem a propriedade AutoTranslate, estas strings devem ser passadas entre aspas simples (' '). Para os demais casos, basta certificar-se de que o valor para AutoTranslate é true.

Trabalhoso, mas extremamente simples… vamos aos códigos!

Codificando a aplicação

Antes de tudo vamos inserir na cláusula uses da seção implementation as Units / Namesspaces necessárias para o funcionamento do código:

implementation

{$R *.fmx}
uses
  FMX.Platform,
  System.IOUtils;

A documentação do Delphi para o TLang recomenda que a mudança de idioma em tempo de execução não se dê através de TLang.Lang e sim através de TLang.LanStr[].

//Lang1.Lang := 'en'; // do not use this
LoadLangFromStrings(Lang1.LangStr['en']); // use this instead

Então, partindo da documentação disposta na Embarcadero DocWiki para o TLang , o evento OnClick do Button2, “Português”, terá o seguinte código:

procedure TfrmPrincipal.Button2Click(Sender: TObject);
begin
 LoadLangFromStrings(Tradutor.LangStr['BR']);
end;

Já o evento OnClick do Button3, “Inglês”, seguindo a mesma linha será como abaixo:

procedure TfrmPrincipal.Button3Click(Sender: TObject);
begin
  LoadLangFromStrings(Tradutor.LangStr['EN']);
end;
Nota: LoadLangFromStrings está declarada Unit / Namespace  FMX.Types, é importante notar que a função faz sua busca de forma CaseSensitive, ou seja, diferenciando maiúsculo e minúsculo.

Com isso nossa aplicação já está funcional… caso você a execute, clicando sobre cada um dos botões codificados, ela já será capaz de traduzir as strings em tela, pode testar aí se quiser, mas já adianto que vamos mais além…

Codificando para Tempo de Execução

Essa postagem já deveria ter sido publicada há tempos, mas nosso amigo Tatu, resolveu no mesmo dia que eu ia escrever fazer uma pergunta sobre o TLang que me deixou extremamente intrigado: Como seria a utilização do TLang em run time? E nas mensagens de Exceção, num bloco try exception, por exemplo?

Pois bem, após alguns testes cheguei ao seguinte… passando uma string, previamente configurada no Language Designer, em tempo de execução à função Translate() a mesma será traduzida pelo TLang. Assim sendo vamos exemplificar na codificação do Button1, “Botão Erro”,  logo abaixo, passando a mensagem através da função Translate():

procedure TfrmPrincipal.Button1Click(Sender: TObject);
begin
  raise Exception.Create(Translate('Erro do botão 1'));
end;
Nota: Translate() retorna uma string especificada com sua tradução correspondente no idioma atual, quando não encontrada a própria string é retornada.

Vamos voltar ao Language Designer e inserir a string Original ” ‘Erro do Botão 1’ “, devendo neste caso, ser o valor passado entre aspas simples (‘ ‘), com a tradução Button One Error para o idioma “EN”, e para o “BR” vamos traduzir como Deu ruim 1.

Por se tratar de conteúdo passado em uma mensagem e estarmos forçando a tradução, já que não há a propriedade AutoTranslate, devemos aqui também passar o valor original dentro de aspas simples (‘ ‘).

Ao final do projeto nosso Language Designer deve estar como nas imagens abaixo:


Execute a aplicação, clique sobre o botão 1 e altere o idioma e execute clique sobre o botão 1 novamente. Teoricamente a aplicação já está pronta… note porém que ao iniciarmos a mesma ela ainda “não sabe” qual idioma está sendo executado, para isso vamos agora capturar o idioma do dispositivo, aquele mesmo setado nas configurações.

Capturando o Idioma Configurado no Dispositivo Android

Mantendo a linha, embora todo o processo até aqui se aplique à plataforma FireMonkey, eu estou utilizando especificamente o Delphi Android, portanto daqui pra frente, os códigos descritos se aplicam ao desenvolvimento específico para dispositivos Android.

Vamos adicionar no evento OnActivate do formulário o seguinte código:

procedure TfrmPrincipal.FormActivate(Sender: TObject);
var
  Local : IFMXLocaleService;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService, Local) then
    begin
      // Atribuimos o Valor do ID do Idioma do Dispositvo ao TLang
      // Como o resultado é minúsculo, convertemos para maiúsculo, como usuado
      // nos idiomas em nosso TLang
      Tradutor.Lang := UpperCase(Local.GetCurrentLangID);
    end;

  //Veja que o valor do Edit1 agora contém o idioma retornado do Dispositivo
  Edit1.Text := Local.GetCurrentLangID;

  if Tradutor.Lang = 'PO' then
    // Quando o idioma for Português no dispositivo vamos usar o BR de nosso TLang
    LoadLangFromStrings(Tradutor.LangStr['BR']);

  //Forçamos a tradução do conteúdo do Edit2
  Edit2.Text := Translate(Edit2.Text);
  Memo1.Lines.Clear;
  //Forçamos a tradução do conteúdo do Memo
  Memo1.Lines.Add(Translate('Linha 1'));

end;

Resultado final

Este é resultado final do projeto…

Confira esse vídeo que fiz demonstrando o funcionamento da aplicação:

É isso, embora pareça mais longo e complexo é muito simples… você pode forçar sempre a passagem das strings utilizando a função Translate(), isso vai garantir o funcionamento da aplicação nos idiomas que você configurou no TLang.

Espero que seja útil, até a próxima!

4 respostas para “Aplicação Multi Idiomas com TLang no Delphi 10 Seattle”

    1. Meu nobre Conde… Vou tentar montar um repositório com os fontes dos post que eu ainda tiver aqui… no começo eu era meio contra, devido a querer dar o “trabalho” mínimo de digitar, mas estou tentando organizar uma parada aqui para atender a sua solicitação e as demais.
      Conseguindo evoluir eu posto.

      Obrigado por sua participação e desculpe pela demora na resposta, ainda não atendendo a sua demanda.

      Até a próxima.

      1. sem problemas, qdo eu estava estudando datasnap eu realmente fazia o q via no video, mas tem coisa q acaba n sendo vantajoso
        por sinal, seu post é muito bom, esqueci de elogiar! 🙂

        n encontrei documentacao em pt sobre como salvar sessao e vc sempre traz essas excelente dicas, se quiser trazer algo no nosso idioma, acredito q tds vao adorar
        https://github.com/spinettaro/DelphiDemos/tree/master/AutomateSaveState

        testei e de fato funciona mto bem! 😉

  1. Ola Anderson.
    Otimo teu material.
    Seguinte vou ter que fazer a tradução do meu sistema para Inglês e Chines.
    Bom pelo que vi não tem muito mistério.
    Estou utilizando a versão Seattle do Delphi.
    Quando entrei dentro da propriedade Lang, adionei os três idiomas, não me da opção de digitar no novo idioma que quero nas respectivas strings.
    Tem algum manha de conseguir digitar ali no lado direitos das strings originais.
    Desde já te agradeço muito.

Deixe uma resposta