Localisation and Internationalization
It seems that how
Gambas deals with localisation and internationalization is not very clear,
so here is a little article about that...
 |
If you never heard about Localization and Internationalization, I suggest that you take a look at the
Wikipedia article first.
|
The Language Environment Variables
The behaviour of an international program must be adapted according to:
- The country of the user.
- The language of the user.
In
Gambas, these two pieces of information are extracted from the two following
system environment variables:
$LC_ALL, or
$LANG.
The
$LANG environment
variable is used only if
$LC_ALL is not defined. We will only use
$LANG from now in this document.
The syntax of
$LANG is the following:
- xx is a two characters string in lower case, and represents the user language.
- YY is a two characters string in upper case, and represents the user country.
- ZZZZ is usually the system charset.
All characters that follows the
xx_YY string are ignored by
Gambas.
To run a program under a different localization, you can do:
$ cd /path/to/my/project
$ LANG=fr_FR gbx2
Or you define the
LANG variable in the
Environment tab of the project
property ../../comp/gb.form/dialog.
 |
On some systems, like Mandriva, you must define the $LANG variable and the $LANGUAGE variable
with the wanted localization. Otherwise strings won't be translated.
$ cd /path/to/my/project
$ LANGUAGE=fr_FR LANG=fr_FR gbx2
|
String Translations
In your project, you have two different kinds of strings:
- Strings that are seen by the user (a label text, a message...), and so that must be translated.
- Strings that are internal (a collection key, a field name, a program setting...), and that must not be translated.
You must explicitely tell
Gambas which strings must be translated, and which strings must not.
Strings that are to be translated must be enclosed between braces:
PRINT "A string that must not be translated"
PRINT ("A string that must be translated")
 |
Note that all Text control properties are automatically marked as translatable.
|
Gambas internally uses the GNU translation system: the translated strings are stored in
xx_YY.mo files, where
xx and
YY have the same definition as above.
 |
If a specific translation file for the xx_YY language cannot be found, then a more general translation file
xx.mo is tried.
For example, if the fr_CA (Quebec French) translation file does not exist, then the fr
(Common French) language will be used.
|
 |
If the GNU translation functions cannot switch to the language stored in the environmental variables, for any reason,
then the strings won't be translated and the date and numeric localization settings may not be honored.
|
String Manipulations
Gambas have two sets of string manipulation functions: those that deals with
ASCII only, and those that can deal with
UTF-8 strings.
Each time you have to manipulate a string that must be translated, then you must use the
UTF-8 functions.
These functions are all members of the static
String class.
Otherwise, I suggest you always use
ASCII characters and
ASCII native functions, because they are faster.
The ASCII native functions are:
Asc,
Chr$,
InStr,
RInStr,
LCase$,
Left$,
Right$,
Mid$,
Len,
LTrim$,
RTrim$,
Trim$...
See
String Functions for all of them.
String Conversions
You often have to translate a
Gambas number or date to a string, and the contrary.
Then, you must know if the string that represents the numeric value or the date will be seen by the user.
Because in that case, the numeric value or the date must be translated according to the user country and language
localization settings. And so, you must use the
Gambas functions
that use localization settings.
These functions are:
Str$, and
Val.
Str$() convert any value to a localized string, whereas
Val() tries to convert any string to a specific value by
guessing the value datatype from the string contents: for example, if
Val() sees date separators or time separators,
according to the localization settings, it will assume that the string must be converted to a date.
Otherwise, if the string representation of the numeric value or the date will not be seen by the user
(an application settings stored in a text file for example), then you must use the
Gambas functions
that do not use
localization settings.
These functions are:
CBool,
CByte,
CDate,
CFloat,
CInt,
CLong,
CSingle,
CShort,
CStr.
 |
Actually, these functions use a default localization setting named "C", that is exactly the same as the "en_US", i.e.
the localization of the people living in the United States of America. That is the main reason for the confusion I think!
|
You will use
CStr() to convert to a string, and all other functions to convert from a string to a specific datatype.
The conversion should be fully bijective, i.e.
CStr(CXXX(anyString)) = anyString, and
CXXX(CStr(anyValue)) = anyValue.
Beware, there is no full guarantee!
GUI Localization
A localization difficulty comes from right-to-left written languages: Arabic, Farsi, Hebrew. The user interface must reverse
some of its components to follow the writing direction.
That should be automatic, as soon as you
always use layout containers like
HBox,
VBox,
HPanel and
VPanel, or containers that have
their Arrangement
property set.
The other part of the GUI (menus, labels, widget scrollbars...) should adapt, provided that
the underlying toolkit (
Qt or GTK+) behaves correctly.
To try a reversed GUI, you can set the
$GB_REVERSE environmental
variable before starting your program. Please tell if
something does not display correctly.
Example
Here is what you see if you run
LANG=fa LANGUAGE=fa gambas2 on my Mandriva: