本地化和国际化

看来Gambas如何处理本地化和国际化还不是很清楚,所以这里有一篇关于这个的小文章......

如果您从未听说过 本地化 和 国际化 ,我建议您先看一下 维基百科文章。

语言环境变量

国际程序的行为必须根据以下条件进行调整:
  • 用户所在的国家/地区。

  • 用户的语言。

在 Gambas 中,这两条信息是从以下两个系统环境变量中提取的: $LC_ALL, 或 $LANG

仅当 $LC_ALL'环境变量未定义时 $LANG' 才使用 。从现在起 $LANG 只会在我们本文档中使用。

$LANG 的语法如下:
xx_YY.ZZZZ

  • xx 是一个小写的两个字符串,代表用户语言。

  • YY 是一个大写的两个字符串,代表用户所在国家。

  • ZZZZ 通常是系统字符集。

Gambas 会忽略字符串 xx_YY 后面的所有字符。

要在不同的本地化环境下运行程序,您可以执行以下操作:
$ cd /path/to/my/project
$ LANG=fr_FR gbx3

或者您可以在项目属性对话框的 Environment 选项卡中定义 LANG 变量。

在某些系统(例如 Mandriva)上,您必须定义 $LANG 变量以及 $LANGUAGE 具有所需本地化的变量。否则字符串将不会被翻译。

$ cd /path/to/my/project
$ LANGUAGE=fr_FR LANG=fr_FR gbx3

字符串翻译

在您的项目中,您有两种不同类型的字符串:
  • 用户看到的字符串(标签文本、消息...),因此必须进行翻译。

  • 内部字符串(集合键、字段名称、程序设置...),并且不得翻译。

您必须明确告诉 Gambas 哪些字符串必须翻译,哪些字符串不能翻译。

要翻译的字符串必须括在大括号内:

PRINT "A string that must not be translated"
PRINT ("A string that must be translated")

请注意,所有文本控件属性都会自动标记为可翻译。

Gambas内部使用GNU翻译系统:翻译后的字符串存储在 xx_YY.mo 文件中,其中 xx和YY具有与上面相同的定义。

如果 xx_YY 找不到该语言的特定翻译文件,则尝试会'xx.mo' 更通用的翻译文件。 例如,如果 fr_CA fr_CA(魁北克法语)翻译文件不存在,则将 fr 使用(通用法语)语言。

如果 GNU 翻译函数出于任何原因无法切换到存储在环境变量中的语言,则不会翻译字符串,并且可能不会遵守日期和数字本地化设置。

在这种情况下,Gambas 解释器将在控制台上打印警告:

gbx3: warning: cannot switch to language 'en_EN.UTF-8': No such file or directory. Did you install the corresponding locale packages?

字符串操作

Gambas 有两组字符串操作函数:一组仅处理 ASCII,一组可以处理 UTF-8 字符串。

每次您必须操作必须翻译的字符串时,您都必须使用 UTF-8 函数。这些函数都是静态 String 类的成员。

否则,我建议您始终使用 ASCII 字符和 ASCII 本机函数,因为它们更快。

ASCII 本机函数是: Asc, Chr$, InStr, RInStr, LCase$, Left$, Right$, Mid$, Len, LTrim$, RTrim$, Trim$... See 字符串函数 for all of them.

字符串转换

您经常需要将 Gambas 数字或日期转换为字符串,反之亦然。

然后,您必须知道用户是否会看到表示数值或日期的字符串。因为在这种情况下,必须根据用户国家/地区和语言本地化设置来翻译数值或日期。 因此,您必须使用使用本地化设置的Gambas 函数。

这些函数是: 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!

日期转换

To print a date/time using the current localization, you have to use the Format$ function with one of the date/time pre-defined formats.

If none of the pre-defined formats fit your needs, then you have to create your own by:

1) Determining the order of date and time components by analysing the formatting of a cleverly chosen date with gb.ShortDate and gb.ShortTime.

2) Using the "/" and ":" formatting characters in the format string.

Example

' Return a custom localized date format
' Doing the same thing for a time format is similar

Private Sub GetMyDateFormat() As String

  Dim aFormat As String[] = ["dd", "mmmm", "yyyy"]
  Dim sFormat As String
  Dim sDate As String
  Dim sChar As String
  Dim I, J As Integer

  sDate = Format(Date(3333, 22, 11), gb.ShortDate)

  For I = 1 To Len(sDate)
  
    sChar = Mid$(sDate, I ,1)
    If IsDigit(sChar) Then
      J = Asc(sChar) - Asc("1")
      If J < 0 Or If J > 2 Or If Not aFormat[J] Then Continue
      If sFormat Then sFormat &= "/"
      sFormat &= aFormat[J]
      aFormat[J] = ""
    Endif
  
  Next

  Return sFormat

End

图形用户界面本地化

本地化的困难来自从右到左的书面语言:阿拉伯语、波斯语、希伯来语。用户界面必须反转其某些组件以遵循书写方向。

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:

See also