OPL development pages - RSCEdit

Resource editor for OPL programmers (freeware)

What is RSCEdit?
RSCEdit is an application that allows you to create language resource files for use in OPL applications.
The reason I wrote RSCEdit is that, up until now, creating a multilingual application in OPL was a very cumbersome process. First you needed to install the entire S80 C++ SDK and then fiddle around with makefiles and resource script to generate the Symbian resource files.
With RSCEdit this becomes a lot easier. The entire process of creating a multilingual application can be done directly on your Communicator. RSCEdit maintains all the different languages you want to support (up to 15) in a single database and generates true Symbian resource files with the press of a button. RSCEdit will also automatically generate a file containing all the constants needed for using the resources in your OPL application.

Bugs or improvements
If you find any bugs or have further ideas for improvement, please let me know by sending an email to Arjen Broeze or by posting a message in the RSCEdit support forum.

How to use RSCEdit
The following is a complete tutorial describing all the steps you need to take to be able to create multilingual OPL applications. Please read it completely and follow the instructions step by step. In the examples I'm using a fictitious application called EggTimer. When you create your own multilanguage application, you need to replace this with the name of your own application.
I'm hoping that by reading through this tutorial,you'll get a good idea about what you need to do to create a multilingual OPL application. If you experience problems, if something is unclear or have suggestions for improving it, please let me know by sending me an email.

  1. Create a language database for your project
    After installing and starting RSCEdit, you need to create a database that will hold all the texts you are using in your application. To do this select "File"-"New" from the menu or press Ctrl-N. After you enter the name and location for the new database, it will be created immediately. The best location to put this database is in the same folder as where your OPL project is stored.

  2. Add languages
    After creating the database you need to add all the languages you want to support to it. You don't need to add all of them immediately, but before you can edit texts, you need to add at least one language to the database. You can add a language, by selecting "Language"-"Add language" from the menu or by pressing Ctrl-Shift-A. This will present a list with all language that are not in the database already.
    The easiest way of getting all the strings that you use in your application into the database, is by adding the language that you used developing your application to the database first and then going over the application line by line and copy and paste the literal texts into this language in RSCEdit. For example, if all the texts in your application are in English, the first thing you do is add the "English (UK)" or "English (US)" to the database.
    In a later version of RSCEdit I will add the ability to scan the OPL source code for literal texts and add them to the database automatically.

  3. Add/edit entries
    If there is at least one language present in the database, you can add (Ctrl-Shift-N, first CBA-key) and edit (Ctrl-Shift-E, second CBA-key) entries. Each entry consists of a constant ID and a text for each language. The constant ID is needed later on in your OPL application to retrieve the texts from the generated resource files. If you choose an approprate name for the constant ID, the resulting code will be easier to read. Some examples:

    Constant ID   English text   Dutch text   German text
    cbaBtnOK   OK   OK   OK
    cbaBtnCancel   Cancel   Annuleren   Schliessen
    cbaBtnClose   Close   Sluiten   Schliessen
    mnuFile   File   Bestand   Datei
    mnuFileNew   New   Nieuw   Neu
    mnuFileNewKey   n   n   n   ; Ctrl-N
    mnuFileOpen   Open   Openen   Vffnen
    mnuFileOpenKey   o   o   o   ; Ctrl-O
    etc.

    Please note that when entering text, the backslash character has a special meaning. It can be used to add line breaks and tabs in the text for example. If you want to use a backslash in your text, you have to double it (\\). The following table lists all the special characters:

    Text   Results in
    \\   Single backslash
    \r   Carriage return
    \n   Line feed
    \t   Tab
    \e   Ellipsis character (...)

  4. Generate the resource files
    When you're done adding/editing constant ID's and texts, you can generate the resources by selecting "File"-"Generate resources" or by Ctrl-G or the bottom CBA-button. This will bring up a dialog where you can specify how and where the resources should be generated.
    The first thing you need to do here is specify the name of the resource. The resource name is a string consisting of exactly four characters. This string is needed to identify the resource. For example, if the name of application is "EggTimer", a suitable resource name would be "EGTM".
    After specifying the resource name, press the "Other settings" button. This will bring up a dialog where you can set further resource generation options:

    1. Include file location.
      This is the folder where RSCEdit will store the file containing all the resource constants. By default the location for this file is same folder as where your database is stored (called the "Project folder"). If you want to change the location of this folder, press the "Include path" CBA-button.
    2. Resource files location
      This is the folder where RSCEdit will create the Symbian resource files. By default this is also the same as the project folder. If you want to change this location, press the "Resource path" CBA-button.
    3. Include file extension
      The extension for the file containing the constant IDs. The default is .tsg, but you can change this to any valid extension. The filename of the generated constant ID file will be the same as the filename of your project database, but with the extension specified here. For example, if your database name is "Eggtimer.lng" and the extension is not changed, the constant ID file will be named "Eggtimer.tsg". You don't need to specify the extension for the Symbian resource files, since the extension for these files is derived from the language code, for example "Eggtimer.rEN" for UK English, "Eggtimer.rAM" for American English, "EggTimer.rDU" for Dutch etc.
    4. Constant prefix
      The text to use before each constant name. OPL convention is to start each constant with a capital 'K', so this is the default value. You're of course free to modify this.
    5. Constant suffix
      The text to use after each constant name. There is no convention for this, but if you want all your resource constants to have the same ending, you can specify a value here. The final generated constant ID will be in the form
      CONST <prefix><constant ID><suffix>&=<value>
      After making the necessary changes, press "OK" to save them.

    Back in the "Generate resources dialog", you can now specify whether or not to generate the OPL-include file (containing the constant IDs) and which language resources to generate. RSCEdit keeps track of which things you changed, so if "Generate OPL include file" is set to "No" you don't need to create this file again (unless you accidently deleted it). After all settings are to your liking, press the "OK" button. Now the resources and optionally the OPL include file will be generated. After this is completed, you are presented with an overview dialog which states what was actually done.

  5. Use the resources in your application
    The first thing you need to do is copy a resource file to the same folder as where your application resides. Normally a Symbian application expects to find it's resource file in the same location as the application executable (.APP file). The extension of a resource file is .rsc, so the first thing you have to do is make a copy of one of the generated resources files and copy it to the folder where your application is stored. For example if your .APP file is stored in C:\System\Apps\EggTimer then copy EggTimer.rEN (UK English version) to C:\System\Apps\EggTimer and rename it to EggTimer.rsc.

    1. Specify a name for each language version of your application
      Normally when your application only supports one language, you have none or only one CAPTION statement between the APP and ENDA construct. If your application supports multiple languages, you can (but don't need to) specify a name for each language. For example:
      APP EggTimer,&10203040
          CAPTION "EggTimer",KLangAmerican%
          CAPTION "EggTimer",KLangEnglish%
          CAPTION "Eierwekker",KLangDutch%
          CAPTION "Eieruhr",KLangGerman%
          ICON "EggTimer.ico"
          ...
       ENDA
      Adding a CAPTION statement for each language you support, will ensure that the name of your application is displayed correctly in the different languages.

    2. Add multilanguage support to your OPL source-code
      Now you have to add a couple of routines and one global variable to your application that will allow you to open the resource and read values from it. You also need to include "SYSTEM.OXH" since all of the routines for reading resource files are inside "SYSTEM.OPX" (which is installed together with the OPL runtime). The routines you need to add are LoadResourceFile:, UnloadResourceFile:, R$: and R%: (the latter two are not necessary, but reduce the amount of typing you need to do).

      First, add this line as the first line of your OPL source file:

       INCLUDE "SYSTEM.OXH"
      Then, add the following code the end of your OPL source file:
      PROC LoadResourceFile:
      EXTERNAL RscFile&
      LOCAL Rscfile$(KMaxStringLen%),off%(6)

          REM Get the name of the application (CMD$(1)) and change the extension to rsc
          RscFile$=CMD$(1)
          PARSE$(RscFile$,RscFile$,off%())
          RscFile$=LEFT$(RscFile$,off%(5))+"rsc"

          IF EXIST(RscFile$)
              REM Open the RSC file for reading
              RscFile&=SyLoadRsc&:(RscFile$)
              IF RscFile&<=0
                  AFInformationDialog%:("Resource file error","An error occurred trying to open the resource file. Please try restarting the application. If this doesn't solve the problem, reinstall the application.")
                  STOP
              ENDIF
          ELSE
              REM RSC file does not exist
              OuInformationDialog%:("Resource file not found","Please reinstall the application")
              STOP
          ENDIF
      ENDP

      PROC UnloadResourceFile:
      EXTERNAL RscFile&
          SyUnLoadRsc:(RscFile&)
      ENDP

      PROC R$:(ID&)
          RETURN SyReadRsc$:(ID&)
      ENDP

      PROC R%:(ID&)
          RETURN ASC(LEFT$(SyReadRsc$:(ID&),1))
      ENDP
      After adding these routines you need to add the global variable RscFile& and the call to LoadResourceFile and UnloadResourceFile to the first routine of your application. If the first procedure in your OPL source file is called Main: for example, the modification would look like this:
      PROC Main:
      GLOBAL RscFile&
      <other variable declarations that were already there>

          LoadResourceFile:

          <original body of the Main procedure>

          UnloadResourceFile:
      ENDP
    3. Create the OPL include file for the constants
      Now your application is completely ready for reading the resources out of the resource file. The resource file is opened at the beginning and closed when the application ends. Now you need to actually read some texts from it. This is where the generated OPL include file comes in. Unfortunately RSCEdit doesn't write OPL files (yet) but text files. This means that the file containing all the resource IDs need to be converted to an OPL file. To do this, open the Program editor, and press Ctrl-N to create a new file. Place this file in the same directory as your OPL source file for your program, but give it the extension ".osg", for example "Eggtimer.osg".

      As soon as the new file is created, select "File" -"More"-"Import text" or press Ctrl+Shift+I. This will bring up the "Import file" dialog. First, press "Show all files" and then navigate to the file that was generated by RSCEdit. If you kept the same at .tsg, you should find this file immediately under the OPL source file. The icon looks like a tilted piece of white paper with some lines of text on it. When you've found the file, press "OK" and the text file be imported into the OPL file. If you move the cursor back to the beginning you should see something like this (the names of the constants will be different and the values too, but the first number always ends in 003):

      CONST KcbaBtnCancel = &2C16B003
      CONST KcbaBtnOk& = &2C16B004
      CONST KcbaBtnPrint& = &2C16B005
      etc.
      The values for the constants are derived from the Resource Name (as specified in the "Generate resource" dialog) and a sequence number (01 and 02 are reserved for a resource signature which is not accessible from OPL).

      If this is ok, save the file ("File"-"Save" or Ctrl-S)and reopen your the OPL source file for your application. In order to be able to use the constant IDs, you need to include the ".osg" file you just created in this file. Assuming the name is "Eggtimer.osg", you need to put the following line directly below the line 'INCLUDE "SYSTEM.OXH"':

      INCLUDE "EggTimer.osg"
    4. Read texts from the resource file
      Now you can replace all the literal strings in your application with strings from the resource file. This is where you can use the R$: and R%: functions. An example:

      Suppose your file menu looks like this:

      mCARD "File","New",%n,"Open",-%o,"Exit",%e
      and you've added the strings to the resource database like this:

      Constant ID   English text   Dutch text   German text
      cbaBtnOK   OK   OK   OK
      mnuFile   File   Bestand   Datei
      mnuFileNew   New   Nieuw   Neu
      mnuFileNewKey   n   n   n   
      mnuFileOpen   Open   Openen   Vffnen
      mnuFileOpenKey   o   o   o   
      mnuFileExit   Exit   Sluiten   Schliessen
      mnuFileExitKey   e   e   e   

      then, after generating the resources and creating the OSG file as described in the steps above, you can replace this with:

      mCARD R$:(KmnuFile&),R$:(KmnuFileNew&),R%:(KmnuFileNewKey&),R$:(KmnuFileOpen&),-R%:(KmnuFileOpenKey&),R$:(KmnuFileExit&),R%:(KmnuFileExitKey&)
      This will read the texts from the resource file instead of having them as literal texts stored in your OPL source code. Now, if you want to change the language of your application, the only thing you need to do is copy one of the other generated resource files (e.g. EggTimer.rAM, EggTimer.rDU, EggTimer.rGE) to C:\System\Apps\Eggtimer\EggTimer.rsc.

  6. Installing the resources (SIS-file)
    To use the resources in an installation file (.sis) so you can give the user the option which language to install, you need to make some changes to your application installation package (.pkg file). First of all, you need to modify the line which states in which languages your application is available. Most of the time, if an application only supports one language, this line looks something like:
    ; Languages
    &EN
    In this line you need to all the language codes of each language in your database. The language code can be found by looking at the last two characters of the generated Symbian resource files. For example, if your application supports US English, UK English, Dutch and German, the line should read as follows:
    ; Languages
    &AM,EN,DU,GE
    By changing this line, the user will now have the chance to select which language to install when he/she installs your application.
    The next step is change the line which contains the name of your application. Typically it looks something like this:
    ; Installation header
    #{"EggTimer"},(0x10203040),1,10,0,TYPE=SISAPP
    The text between quotes is the name of the application. But, since you are now installing multiple languages, the installer needs to know what the name is of the application for each language. That means that this line will look something like this:
    ; Installation header
    #{"EggTimer","EggTimer","Eierwekker","Eieruhr"},(0x10203040),1,10,0,TYPE=SISAPP
    The order of the names must be the same as specified in the languages statement. That means that if the language statement is "&AM,EN,DU,GE", the strings in the installation header must match this order. It is important to remember that you have to do this for all the literal strings that can be displayed by the installer, even if they are the same for every language. For example, if you want to make sure that your application can only be installed on a Nokia 9300/9500, you normally would add the following line to your PKG file:
    ; Rem only for 9300/9500
    (0x101F8ED2), 0, 0, 0, {"Series80ProductID"}
    If you have four different languages to install, this line needs to be changed to:
    ; Rem only for 9300/9500
    (0x101F8ED2), 0, 0, 0, {"Series80ProductID","Series80ProductID","Series80ProductID","Series80ProductID"}
    Now you need to add the resource files to the installation. You normally do this directly after installing the main application and the aif file. Again the resource file order must match the order specified in the language statement of the pkg file. For example:
    "EggTimer.aif"-"!:\System\Apps\EggTimer\EggTimer.aif",FF
    "EggTimer.app"-"!:\System\Apps\EggTimer\EggTimer.app",FF
    "EggTimer.mbm"-"!:\System\Apps\EggTimer\EggTimer.mbm",FF
    {
    "EggTimer.rAM"
    "EggTimer.rEN"
    "EggTimer.rDU"
    "EggTimer.rGE"
    }-"!:\System\Apps\EggTimer\EggTimer.rsc",FF
    The names of the files must be on separate lines or separated by spaces (one multiple lines is easier to read though) and should be enclosed by a pair of braces. This tells the installer that this is a language dependent file and that it should only install the one that corresponds to the chosen installation language.

    You can also use the same syntax if you want to show a readme file in different languages, like in the following example:

    ; Readme
    {
    "ReadmeEN.txt"
    "ReadmeEN.txt"
    "ReadmeDU.txt"
    "ReadmeGE.txt"
    }-"",FT,TC
    As you can see, in this example there is only one file for the English language (usually the difference between UK English and US English is not that big), so the same file is simply specified twice.

    After adding all this to the pkg file, you're ready to create an installation file from it and distribute your multilingual application!

Plans for next releases
If you have further ideas for improvement, please let me know by sending an email to arjen@allaboutsymbian.com.

For updates and support surf to http://opldev.broeze.com/index_RSCEdit.html

Download RSCEdit
You can download RSCEdit from the Downloads page.