Symbian has the capability of supporting resources in multiple languages, and letting the user decide which language to use at installation time. This article shows how to support this in your code.
This article is applies to all Symbian SDK that I know. I have tested it both in Series 60 (6.1, 7.0s), and UIQ, and with several European languages, as well as Chinese. However, I haven't tested it with RTL (Right-to-Left) languages.
The key to doing this is in the project's resource file. Basically, it gets compiled twice, once for each supported language, each time with different strings. Then at installation, when the user selects a language for the application, the device effectively copies the appropriate compiled resource file, which is then used as the application's resource file.
Any application can support this framework by following these steps.
Prepare the source code
First, you should make sure that you have no descriptors inside your code, and they're all in the your .RSS file.
Strings that are part of a resource (such as prompts in a dialog line, and such), are in the RSS file anyway. For literals, the simplest way to export a literal is to a TBUF. For example, if you have something like this:
_LIT(KMyLine,"Cheers, Mate");
// somewhere in the code ..
iLabel->SetTextL(KMyLine);
you should export the literal to the .RSS file:
// In MyApp.RSS
RESOURCE TBUF r_my_line { buf = "Cheers, Mate";}
and then use it in your code as follows:
HBufC * myLine = iEikonEnv->AllocReadResourceLC(R_MY_LINE);
iLabel->SetTextL(*myLine);
CleanupStack::PopAndDestroy(myLine);
Of course, if you use the string frequently, you may want to load it into a class member. You may also want to load the resource into a TBuf:
TBuf<12> myLine;
iEikonEnv->ReadResource(myLine,R_MY_LINE);
Export the strings to a seprate file
The second step is the simplest: You need to export all the strings in MyApp.RSS to a header file named by convention MyApp.LOC (or .RLS, it doesn't really matter), and then #include this file into your .RSS. The .loc file is a simple header file with #defines. This header file is commonly known as a localization file.
In the above example, we would replace the following line in MyApp.RSS
RESOURCE TBUF r_my_line { buf = "Cheers, Mate";}
with
#include "MyApp.loc"
...
RESOURCE TBUF r_my_line { buf = string_my_line;}
and add the following line to the .loc file
#define string_my_line "Cheers, Mate"
Create localization files
Now your program is prepared for localization. You should now take your .loc file and translate it to the other language you wish to support. In this example, I will assume it is Chinese.
First, you should determine what is the code of the language you're translating to. You can easily determine this by examining the TLanguage enum in <e32std.h>. The code for PRC Chinese is 31.
Now make a copy of MyLoc.loc and name it using the appropriate code for your language, for example: MyLoc.L31. Now you should translate all the strings to Chinese, e.g.
#define string_my_line "你好,朋友"
Now, since the file is not ASCII, you must write it in UTF-8 and put the following line in the beginning of the file:
CHARACTER_SET UTF8
Note: If you're using MS Visual Studio, you'll find out that introduces a problem here, since it only supports ANSI. You can easily edit the file in Notepad, which, (in Win2K & XP) lets you save the file as UTF-8. Unfortunately, notepad has the side effect of prefixing the file with the three bytes 0xEF, 0xBB, 0xBF, which make the file unreadable by the compiler. You can fix this by opening the file in Visual studio and deleting these characters.
Integrate the localized strings into the project
Ok, now that you have exported and translate all the strings, comes the heart of the process: Integrating the strings into your project. This is actually very simple. In your .mmp file, locate the line beginning with “LANG”. If there isn't any such line create one, doesn't matter where.
This line contains the language codes for all the supported languages:
LANG 31 SC
where SC is the default language (usually UK English), and 31 is the language code. You may put as many codes as you wish.
Then, in the .RSS file replace
#include "MyApp.loc"
with
#if (defined LANGUAGE_SC) // default (U.K. English)
#include "MyApp.lOC"
#elif defined LANGUAGE_31 // PRC Chinese
#include "MyApp.lZH"
#endif
If all works well, after the next compilation, you'll have two binary resource files: MyApp.RSC in English, and MyApp.R31, in Chinese.
What happens with this, is that the builder compiles the resource file once for each language code. On each compilation it defines a different preprocessor definition according of the following pattern: LANGUAGE_xx, where xx is the language code as specified in the .MMP file
[1].
Use the localized resources in installation
Now that you have localized resource files, you need to modify your .pkg file so that it will let the user install your application in his desired language
Again, you have to add language indication to the file. In the .PKG it looks like this:
&EN, ZH
EN and ZH are language codes for English and PRC Chinese. Here is the full list as it appears in the documentation under "Package file format .pkg". The list is identical for all the aforementioned SDKs.
| EN | UK English | SG | Swiss German |
| FR | French | PO | Portuguese |
| GE | German | TU | Turkish |
| SP | Spanish | IC | Icelandic |
| IT | Italian | RU | Russian |
| SW | Swedish | HU | Hungarian |
| DA | Danish | DU | Dutch |
| NO | Norwegian | BL | Belgian Flemish |
| FI | Finnish | AU | Australian English |
| AM | US English | BF | Belgian French |
| SF | Swiss French | AS | Austrian German |
| IF | International French | NZ | New Zealand |
| CS | Czech | SK | Slovak |
| PL | Polish | SL | Slovenian |
| TC | Taiwan Chinese | HK | Hong Kong Chinese |
| ZH | Prc Chinese | JA | Japanese |
| TH | Thai |
Now, locate the line in code that controls the copying of the .rsc file:
"\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.rsc"-"!:\system\apps\MyApp\MyApp.rsc"
and replace it with:
{"\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.rsc",
"\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.r31"}
-"!:\system\apps\MyApp\MyApp.rsc"
This format is used to specify a list of files, of which only one will be installed, depending on the language selected by the user during installation: If the user selects English, the first file will be copied; if he selects Chinese, the second file will be copied (and renamed MyApp.RSC). Again, you may put as many languages as you wish.
Unfortunately, the file format requires that you “translate” all the strings in your code to all the supported languages, i.e, all strings in the .pkg, must appear twice (or more, depending on the number of languages you support). This includes your application name:
#{"MyApp","MyApp"},(0x06812345),0,40,0
but also strings like:
(0x101F617B), 2, 0, 0, {"UIQ20ProductID","UIQ20ProductID"}
(0x100002c3), 1, 0, 14, {"Standard C Library","Standard C Library"}
or
(0x101F6F88), 0, 0, 0, {"Series60ProductID","Series60ProductID"}
Install
That's it! If all went well, when you install the application you will be given a choice of languages, and only the language you chose will be installed.
Enjoy!
[1] You may have noticed that the language code used to identify the language during the compilation doesn't really matter. This is true. Symbian is not really aware of the destination language, at least not until the installation phase. When compiling it simply uses the given code for declaring the LANGUGAGE_xx's, and naming the resulting .RSC files; so you may use any two characters to identify the language. However, using the TLanguage enum for the language code is the recommended convention. I also make use of this convention in my next article, which will cover changing the application's language at run-time
Hi
Thanks the article is great.
I did a localization for P800, and it works fine. On installation it gives me a list of languages to install - and whichever I choose works.
However, when localizing my app for 6600 this doesn't work quite the same the phone doesn't offer me the option to choose languages - it just installs the English version automatically. I thought maybe it detects your current language automatically, so I set the phone language to Hebrew (only options are English, Hebrew, Arabic!) - when I do this I get an error
- have you ever seen this? Do you know what it is?
Thanks
Kibi
Basically, the 6600 treats differently the language issue. If the device's default language is one of the options for the installation, it will install it automatically. If, however, none of the sis's languages matches the device exactly, the device will give you all the options it supports. For example, in the device I'm currently using, the default language is U.K. English, but if the sis doesn't have UK English, the device accepts _any_ other language, even languages for which it doesn't have fonts.
Your problem, however, stems for what seems to be the sad truth that Eurocom, the representative of Nokia in Israel, is very conservative about the languages is supports. In an application I wrote, for example, I tried to declare the English version as American English by writing AM instead of EN in the .pkg file. Surprisingly, it refused to install on Eurocom's Hebrew 6600 phones, so we had to change it to UK English. if you tried to localize your application to any language other than Hebrew or Arabic, then this is probably the problem you're facing.
hope this helps
Ariel, Giant Steps, Ltd.
Hi,
The resource file doesn't seem to compile because when I try to create the package, it says the .rsc file was not found.
Can you please help out?
Thanks, Rajat
A bit too late, I found out that much more languages are supported in the .PKG file than appear in the documentation. For your convenience, here's the full list:
AF - Afrikaans, SQ - Albanian, AH - Amharic, AR - Arabic, HY - Armenian, AU - Australian, AS - Austrian, BE - Belarussian, BN - Bengali, BG - Bulgarian, MY - Burmese, CA - Catalan, TC - Taiwan Chinese, HK - Hong Kong Chinese, ZH - PRC Chinese, HR - Croatian, CS - Czech, DA - Danish, DU - Dutch, EN - English, AM - American English, CE - Canadian English, IE - International English, SF - South African English, ET - Estonian, FA - Farsi, FI - Finnish, BL - Belgian Flemish, FR - French, BF - Belgian French, CF - Canadian French, IF - International French, SF - Swiss French, GD - Scots Gaelic, KA - Georgian, GE - German, SG - Swiss German, EL - Greek, GU - Gujarati, HE - Hebrew, HI - Hindi, HU - Hungarian, IC - Icelandic, IN - Indonesian, GA - Irish, IT - Italian, SZ - Swiss Italian, JA - Japanese, KN - Kannada, KK - Kazakh, KM - Khmer, KO - Korean, LO - Laothian, LV - Latvian, LT - Lithuanian, MK - Macedonian, MS - Malay, ML - Malayalam, MR - Marathi, MO - Moldovian, MN - Mongolian, NZ - New Zealand, NO - Norwegian, NN - Norwegian Nynorsk, PL - Polish, PO - Portuguese, BP - Brazilian Portuguese, PA - Punjabi, RO - Romanian, RU - Russian, SR - Serbian, SI - Sinhalese, SK - Slovak, SL - Slovenian, SO - Somali, SP - Spanish, OS - International Spanish LS - Latin American Spanish, SW - Swahili, SW - Swedish, FS - Finland Swedish, TL - Tagalog, TA - Tamil, TE - Telugu, TH - Thai, BO - Tibetan, TI - Tigrinya, TU - Turkish, CT - Cyprus Turkish, TK - Turkmen, UK - Ukrainian, UR - Urdu, VI - Vietnamese, CY - Welsh, ZU - Zulu
Ariel
"\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.rsc", "\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.r31"
"!:\system\apps\MyApp\MyApp.rsc"
should be:
"\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.rsc" "\Symbian\UIQ_70\Epoc32\data\z\system\apps\MyApp\MyApp.r31"
"!:\system\apps\MyApp\MyApp.rsc"
(comma deleted)
IT IS VERY GOOD TUTORIAL, IT HELPS ME VERY MUCH.
I AM USING URDU FONT (IT IS LIKE ARABIC SCRIPT)
I ALSO ADDED LANG UR IN MMP FILE FOR URDU LANGUAGE SUPPORT
CHARACTER_SET UTF8
RESOURCE TBUF r_example_text_Hello buf="urdu lANG اسدفاسدفا";
I AM USING CODEWARRIOR FOR DEVELOPMENT WITH UIQ 2.1 SDK, WHEN I AM GOING TO OPEN IT, IT DISPALY LIKE THIS
RESOURCE TBUF r_example_text_Hello buf="urdu lANG اسدÙÂاسدÙÂا";
IS THERE ANY FONT INSTALLATION REQUIRED. BCZ IT IS DISPLAYING BOX INSTEAD OF URDU AND ENGLISH TEST ON THE SCREEN
As I mentioned in the body of the tutorial, MS-VC 6.0 cannot read UTF-8 files properly. The same goes to Code Warrior (5.2). They're simply not aware of it. Therefore, you should not edit your resource file from inside CodeWarrior. Use notepad instead. See my comments in the body of the tutorial.
امن
Accually I am having the trouble shootig on this, but after reading this tutorial I found that my knowledge on using font in mobile is better. But I didn't understand about the code PRC, How can we get it and does it relate to Unicode?
Thanks for your kindly
Sochan.
Hi, good article. What I would like to find out is how to localize the application name itself. Ie. when the phone is set to English display Cheers Mate as the application name in the list and when set to Chinese display 你好 朋友
In the .rss file you can add language codes and application names in the caption_list:
CAPTION code=ELangEnglish; caption="Cheers Mate";
CAPTION code=ELangPrcChinese; caption="What to do here";
But again the tools won't let you save the file in any other encoding than ANSI. I tried using the code point notation like with the string literals in code:
CAPTION code=ELangPrcChinese; caption="\x4f60\x597d Mate";
This won't expand to anything, but is displayed just like above (ok, I only tried with the copyright mark or some accented European characters - I don't have a Chinese phone - but the same thing happened.
What can I do here if anything?
Hi, great article!
I have to localise some Symbian applications that are only available as .sis files.
How to do it? I know that it is possible.
Seriously, I appreciate your comments!
Ronny