2013-11-27

Format settings:

← Older revision

Revision as of 23:23, 26 November 2013

(6 intermediate revisions by one user not shown)

Line 3:

Line 3:

 

Preparing applications for several languages has always been a bit of a mystery to me - until I finally tried. Then I found out that is is amazingly simple once I understood the first steps. I'd like to share this information with interested users of Lazarus.

 

Preparing applications for several languages has always been a bit of a mystery to me - until I finally tried. Then I found out that is is amazingly simple once I understood the first steps. I'd like to share this information with interested users of Lazarus.

 

 



You may jump right in. But it is maybe a good idea to learn something about the basic ideas behind that architecture. Therefore I'd urge you to read [[Translations_/_i18n_/_localizations_for_programs]] which
explains
the basic fundamentals behind the scene.

+

You may jump right in. But it is maybe a good idea to learn something about the basic ideas behind that architecture. Therefore I'd urge you to read
the wiki articles [[Localization]] and/or 
[[Translations_/_i18n_/_localizations_for_programs]] which
explain
the basic fundamentals behind the scene.

 

 

 

= Getting started =

 

= Getting started =

Line 68:

Line 68:

 

In its initialization code, <code>DefaultTranslator</code> seeks for the language setting of the currently used system. Therefore, if you work on a PC set up for German language the demo project will now be in German automatically. Detection of the default language and replacing the resource strings with those from the corresponding po file has been done by the translation system of Lazarus.

 

In its initialization code, <code>DefaultTranslator</code> seeks for the language setting of the currently used system. Therefore, if you work on a PC set up for German language the demo project will now be in German automatically. Detection of the default language and replacing the resource strings with those from the corresponding po file has been done by the translation system of Lazarus.

 

 



=
Changing
languages
at run-time
=

+

=
Switching
languages =

 

But what if your PC is not on German language? We can use the Lazarus translation system to switch languages at run-time.

 

But what if your PC is not on German language? We can use the Lazarus translation system to switch languages at run-time.

 

 



The
DefaultTranslator of Lazarus trunk or 1.2
contains
a procedure <code>SetDefaultLang</code>
which can be employed to switch
between languages upon user
interaction. Unfortunately, this is only a recent addition to Lazarus, it is not yet available in the current version 1.0.x
. (Of course, if you want to stick to 1.0.x you add this procedure to the source code of DefaultTranslator.pas -
it is built from
the
code running at
initialization of the unit -, and save the modified unit in your project folder.)

+

First of all, the <code>
DefaultTranslator
</code> unit provides commandline switches <code>--lang</code> or <code>-l</code> to override the automatic language detetion. For example,

 

+

<source>

 

+

    imgview.exe --lang de

 

+

</source>

 

+

opens the German translation
of
the program even on an English-speaking system.

 

+

 

 

+

Of course, changing languages at run-time would be even more favorable. Unfortunately this is not possible with Lazarus 1.0.x out of the box. But it is no problem with
Lazarus trunk or
the upcoming version
1.2
where <code>DefaultTranslator</code> provides
a procedure <code>SetDefaultLang</code>
for switching
between languages upon user
request
. (Of course, if you want to stick to 1.0.x you
can
add this procedure to the source code of
<code>
DefaultTranslator.pas
</code>
-
you find all the necessary building blocks in
the initialization
code
of the unit -, and save the modified unit in your project folder.)

 

 

 

At first, we need some control in the user interface to switch languages. What about a new menu item "Translation" and a submenu containing the available languages? In the menu designer of the main form add a new item "Translations" and an empty submenu. Then, for each language available, add the name of the corresponding language to the submenu. Of course you can also show a flag icon for each language - free flag icons are available from [http://www.famfamfam.com/lab/icons/flags/]. In the <code>OnClick</code> event handler call <code>SetDefaultLang</code> with the language code as a parameter, e.g.  

 

At first, we need some control in the user interface to switch languages. What about a new menu item "Translation" and a submenu containing the available languages? In the menu designer of the main form add a new item "Translations" and an empty submenu. Then, for each language available, add the name of the corresponding language to the submenu. Of course you can also show a flag icon for each language - free flag icons are available from [http://www.famfamfam.com/lab/icons/flags/]. In the <code>OnClick</code> event handler call <code>SetDefaultLang</code> with the language code as a parameter, e.g.  

Line 90:

Line 96:

 

 

 

Now you can click on a language menu item, and the application language switches to the selected language automatically!

 

Now you can click on a language menu item, and the application language switches to the selected language automatically!

 

+

 

+

As you may notice the new menu item "Translation" and its submenu items are not translated. This is because these are new strings missing from the translated po files. Simply open the translated files in <code>poedit</code> and add the translations of the new strings. All the previous translations are still there. Save, and you are all set.

 

 

 

= Strings defined by the LCL =

 

= Strings defined by the LCL =



Here is one idea for refinement: The strings setup up for error messages defined by the LCL or used in standard dialogs or message boxes are not yet translated. Their translation is extremely easy: their translation files can be found in the directory <code>lcl/languages</code> of your Lazarus installation, they are named <code>lclstrconsts.*.po</code>. Pick those translations used by your application and copy them to the <code>languages</code> folder of our project
; in our case, we copy <code>lclstrconsts.de.po</code> and <code>lclstrconsts.en.po</code>
.

+

Here is one idea for refinement: The strings setup up for error messages defined by the LCL or used in standard dialogs or message boxes are not yet translated. Their translation is extremely easy: their translation files can be found in the directory <code>lcl/languages</code> of your Lazarus installation, they are named <code>lclstrconsts.*.po</code>. Pick those translations used by your application and copy them to the <code>languages</code> folder of our project.

 

 

 

This works because, when translating, resourcestrings are look for in all language files found in the languages folder.

 

This works because, when translating, resourcestrings are look for in all language files found in the languages folder.

 

 

 

= Format settings =

 

= Format settings =



When creating multi-language applications translation of the strings is not the only task. Another issue is that format settings may change from country to country. Format settings - they define formatting of dates and times, the month and day names, the character to be used as decimal or thousands separator, etc.  

+

When creating multi-language applications translation of the strings is not the only task. Another issue is that format settings may change from country to country. Format settings - they define formatting of dates and times, the month and day names, the character to be used as decimal or thousands separator
, etc. In Lazarus, the record <code>TFormatSettings</code> collects all the possible data. The <code>DefaultSettings</code> are used by the standard format conversion routines, such as StrToDate, DateToStr, StrToFloat, or FloatToStr
, etc.

 

 



For Windows, there exists a procedure <code>GetLocaleFormatSettings</code> in the unit <code>sysutils</code> which returns
a
<code>TFormatSettings</code>
which is used when calling string conversion functions such as StrToDate, StrToFloat etc
. The
function result is determined by the
parameter <code>LCID</code>
. This is number specifying
the language code in Windows. Unfortunately I do not know of a convenient conversion between the LCID and the language codes ('de', 'en', etc) used by Lazarus. A conversion table can be found at [http://www.science.co.il/Language/Locale-codes.asp]. In this table, you see that "German" has the LCID $407, and "English" has the LCID $409. Therefore, we modify the OnClick event handler for the language selection menu items as follows:

+

For Windows, there exists a procedure <code>GetLocaleFormatSettings</code> in the unit <code>sysutils</code> which returns
the
<code>TFormatSettings</code>
for a given localization
. The parameter <code>LCID</code>
specifies
the language code in Windows. Unfortunately I do not know of a convenient conversion between the LCID and the language codes ('de', 'en', etc) used by Lazarus. A conversion table
for lookup
can be found at [http://www.science.co.il/Language/Locale-codes.asp]. In this table, you see that "German" has the LCID $407, and "English" has the LCID $409. Therefore, we modify the
<code>
OnClick
</code>
event handler for the language selection menu items as follows:

 

 

 

<source>

 

<source>

Line 115:

Line 123:

 

</source>

 

</source>

 

 



To demonstrate this effect
we add a status bar to our project and display the date when an image was created:

+

As a demonstration
we add a status bar to our project and display the date when an image was created:

 

 

 

<source>

 

<source>

Line 140:

Line 148:

 

</source>

 

</source>

 

 



When you recompile
the program
,
load some images
you
see that the date format changes when the language is switched and another image is selected.

+

Recompile
the program
and
load some images
. You'll
see that the date format changes when the language is switched and another image is selected.

 

 



Unfortunately, this solution is valid only for Windows. I don't know how this issue could be handled in Linux etc. Maybe somebody out there in the community?

+

Unfortunately, this solution is valid only for Windows. I don't know how this issue could be handled in Linux etc. Maybe somebody
does
out there in the community?

 

 



Anyway
, here is the final screenshot of this tutorial: it shows the
imgviewer
application translated to German.

+

Although some issues of localization (e.g. right-to-left mode, sorting order) have not been discussed I hope that this tutorial covered the most important aspects and is at least a good starting point for beginners.

 

+

 

 

+

In the end
, here is the final screenshot of this tutorial: it shows the
image viewer
application translated to German.

 

 

 

[[File:imgviewer_de.png]].

 

[[File:imgviewer_de.png]].

 

+

 

+

[[category:Tutorials]]

 

+

[[category:Localization]]

Show more