Internationalizationg a program lazarus / 31-LCL ---------------------------------------------------------------------- dcelso · 2013-03-02 23:47 Hello to all, Im trying to internationalize an application, so I have activated internationalization in the option project. I have obtained the .po file, I have translated it to two languages, myproject.es.po, myproject.en.po But now, I dont know how use those files. I would like that the end user can change between the two languages manually. And by defaul, the aplication use the locale variable envirotmen  to select the initial language. ---------------------------------------------------------------------- Leledumbo · 2013-03-03 04:09 http://wiki.freepascal.org/Translations_/_i18n_/_localizations_for_pro grams#Translating_Forms.2C_Datamodules_and_Frames ---------------------------------------------------------------------- dcelso · 2013-03-03 11:55 Yes, I saw it before. Else why will i ask here? . I done an example to test it, and it continues without work,( I have lastest SVN lazarus compiled, in debian wheezy) I have activated internationalization, in projet, and I have two .po translated.  project.en.po, and project.es.po in the LANG directory of my appdir. The form ins the next Code: [Select]object Form1: TForm1   Left = 402   Height = 283   Top = 319   Width = 466   Caption = 'Form1'   ClientHeight = 254   ClientWidth = 466   Menu = MainMenu1   LCLVersion = '1.1'   object Button1: TButton     Left = 288     Height = 25     Top = 216     Width = 75     Caption = '&Acept'     OnClick = Button1Click     TabOrder = 0   end   object Button2: TButton     Left = 376     Height = 25     Top = 216     Width = 75     Caption = '&Cancel'     TabOrder = 1   end   object Edit1: TEdit     Left = 152     Height = 31     Top = 32     Width = 80     TabOrder = 2     Text = '2'   end   object Label1: TLabel     Left = 103     Height = 21     Top = 36     Width = 30     Caption = 'Age:'     ParentColor = False   end   object Label2: TLabel     Left = 103     Height = 21     Top = 83     Width = 47     Caption = 'Result:'     ParentColor = False   end   object Label3: TLabel     Left = 184     Height = 21     Top = 83     Width = 47     Caption = 'Is Even'     ParentColor = False   end   object MainMenu1: TMainMenu     left = 36     top = 27     object MenuItem1: TMenuItem       Caption = '&File'       object MenuItem2: TMenuItem         Caption = '&Open'       end       object MenuItem5: TMenuItem         Caption = '&Save'       end       object MenuItem3: TMenuItem         Caption = '&Exit'       end     end     object MenuItem4: TMenuItem       Caption = '&Help'       object MenuItem6: TMenuItem         Caption = '&About ..'       end     end   end end the .pas is the next Code: [Select]unit Unit1; {$mode objfpc}{$H+} interface uses   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,   StdCtrls, LResources, DefaultTranslator; type   { TForm1 }   TForm1 = class(TForm)     Button1: TButton;     Button2: TButton;     Edit1: TEdit;     Label1: TLabel;     Label2: TLabel;     Label3: TLabel;     MainMenu1: TMainMenu;     MenuItem1: TMenuItem;     MenuItem2: TMenuItem;     MenuItem3: TMenuItem;     MenuItem4: TMenuItem;     MenuItem5: TMenuItem;     MenuItem6: TMenuItem;     procedure Button1Click(Sender: TObject);   private     { private declarations }   public     { public declarations }   end; var   Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); var   value : Integer; begin   value := StrToInt(Edit1.Text);   if value mod 2 = 0 then      label3.Caption:='Is Even'   else      label3.Caption:='Is Odd'; end; initialization   LRSTranslator := TPoTranslator.Create('./LANG');  (* I tested with absoulte path, too*) end. In the lang directory i have project.en.po, and project.es.po My envirotment LANG var is equal to es_ES.utf8 But the program continues show the values of captions and texts made in the design time. I don't see what  I need more to do. ---------------------------------------------------------------------- Leledumbo · 2013-03-03 13:09 QuoteI have activated internationalization, in projet, and I have two .po translated.  project.en.po, and project.es.po in the LANG directory of my appdir.I think you misunderstand the article and miss the little explanation: LANG stands for the desired language I'll update the article so that people don't think it's literal LANG, but rather a variable. Anyway, test the attached project, with any way you know to change language (EnvVar LANG, --lang / -l switch, whatever), of course you have to add your desired language to languages directory. You should see the label caption changes. ---------------------------------------------------------------------- Blaazen · 2013-03-03 13:18 A few month ago I attached a TranslationDemo here: http://www.lazarus. freepascal.org/index.php/topic,18939.msg107377.html#msg107377 ---------------------------------------------------------------------- dcelso · 2013-03-03 23:56 Thanks to both, After of see the example of leledumbo, I was surprised seeing how easy is translate a lazarus application. You only need: * activate internationalization, selecting "language" directory (other name does not work direcly) in your options project. *translate the autogenerated language/projec1.so to a language and rename it with correct name for selected language. * Add to your project source uses section the unit defaultranslator (going to projet-view source project menu) * And run the application , configuring before LANG environment  variable with the language to test. Now I'll study the blazzen example to advanced options for translating appications. So thanks to both again. And other question, how can I add a new custom message (msgid, and msgsrt) in my .po files, and dont lose it at recompile the application? and how can I use it with gettext. I want do it to put translated messages in my application that they aren't on visual components properties. ---------------------------------------------------------------------- dcelso · 2013-03-04 00:18 , I can't test your example blaazen, when I open translatedemo.lpi, lazarus sais vinfo.pas does not found, and after of open it, at compile it sais  invalid x86_64 option, I change it to default option in option project, and to try to compile again it sais. duplicate identifier TRANSLATEDEMO in translatedemo.lpr 10,23 If I delete it of uses section, to try to compile again it sais, fatal error cannot find unit vinfo used by translatedemo of the project inspector. ---------------------------------------------------------------------- Blaazen · 2013-03-04 00:48 Try "transdemo.lpi" instead. The attached archive is messy, there's too many files. I made the this demo by reducing my other project and I wasn't proper. ---------------------------------------------------------------------- Leledumbo · 2013-03-04 13:37 Quote* activate internationalization, selecting "language" directory (other name does not work direcly) in your options project.The search logic is explained in the article. QuoteAnd other question, how can I add a new custom message (msgid, and msgsrt) in my .po files, and dont lose it at recompile the application? and how can I use it with gettext. I want do it to put translated messages in my application that they aren't on visual components properties.Use resourcestring, I don't know about gettext ---------------------------------------------------------------------- dcelso · 2013-03-04 21:39 Thanks blaazen. Those code works well. I'll study it. Thanks leledumbo,too.  Resourcestring is what im searching. Another thing that i have discovered is that i can change the language in runtime with setdefaultlang. Very useful. I have a related question more. How can i do that my appication uses the design string instead of translated strings. I thougth with setdefaultlang('') but i was wrong. Is there another function to do it? ---------------------------------------------------------------------- Leledumbo · 2013-03-05 15:55 What do you mean by design string? ---------------------------------------------------------------------- dcelso · 2013-03-05 17:21 strings written in object inspector (like caption, or text fields) while you was programmign the applications. ie, The values of  the strings of the application without internationalization activated, ie, The values of the msgids in the .po files instead of the msgstr value. ie, default values of strings. ---------------------------------------------------------------------- Leledumbo · 2013-03-05 17:51 As the last resort, DefaultTranslator will look the default .po (those with empty msgstr) in the same directory as the application binary. This should not translate your app. However, if you have ..po in the languages directory (or whatever known to DefaultTranslator), it will be preferred over the default .po. ---------------------------------------------------------------------- dcelso · 2013-03-06 12:02 , You does not understand me. May be with an example. I have designed an application in english language. If you open this project with lazarus you will see it in english. I have done internationalization to english and italian. If you run the application you can select four languages. Default: May be english, because is the programed language System: using locale system, getting LANG variable of system. Spanish; using .es.po Italian; using .es.it. The problem is the default language, it does nothing. It leaves the last selected language instead of change it with the strings designed values. ---------------------------------------------------------------------- Blaazen · 2013-03-06 13:32 Hi, I don't see the difference between "System" and "Default". In the demo I attached above, there is a choice "Default" which takes the language setting form system Code: [Select]{ If 'Default' then Get Language from Environment }   if (Result='') or (LowerCase(Result)=LowerCase(csDefault)) then     Result:=Copy(GetEnvironmentVariableUTF8('LANG'), 1, 5);or there is setting "No translation" and it keeps english (because the demo is developed in english). What do you expect from "Default" in your case? ---------------------------------------------------------------------- dcelso · 2013-03-06 17:57 Yes,you are right. System is for using the language defined in the system. And default is for using the strings values put in the lazarus IDE in developed time. In this case, I developed it in english. But when I select it in my demo. It does not do anything.  It leaves the language of before. I'm searching a method to use the written strings in the lazarus IDE instead of use .po file, when you select the defaul language. ---------------------------------------------------------------------- Blaazen · 2013-03-06 19:12 Well, you develop your app. in english, i.e. all button.captions labels, etc. are in english and in your source you have your own strings defined in section "resourcestrings". And you have several *.po files with translations. If you want to keep it in english, then simply do not do any translation. I don't know what translator you use but maybe that the translation is done in "initialization" section of that unit therefore you cannot keep it in english. ---------------------------------------------------------------------- dcelso · 2013-03-06 20:58 Exactly. That you sais work well. But i need do it in run time,ie, while the app is runnig. If you see the example application i'm using defaulttranslator unit given by lazarus. And when i change the language with the combobox it automatically changes the language. But i dont know how dissable translation in run time. I thought that using setdefaultlan('') i get it. ---------------------------------------------------------------------- taazz · 2013-03-06 21:13 warning I haven't used the build in translation support so I can only guess and only if I understand the problem correctly. Your problem is that when you select the default translation at run time the forms already open do not translate to the default language. The problem as far as I understand is that the translation process does not know or cares what is the default language it does not exists on any outside file so it can not load them and set them. Those strings are part of the applications resource table and are in a form that only the internal streaming functionality can access them correctly while the current translation environment uses property names and values to set them it does not know and can not load the data from resources. This is to be expected and until a different translation environment is used there is no way of doing that. The main problem is that a resource based translation creates owned objects as it reads them from the resource and does not try to find them in memory, this creates a lot of problems and conflicts with existing data. So for now I suggest to either 1) request a restart when the default language is chosen 2) create a default language external file and use that to translate the application when the default is chosen only and do not translate when the application starts. ---------------------------------------------------------------------- dcelso · 2013-03-06 21:27 , yeah. I understand. I didn't thougth it. Then I will use your second solution. Thanks.