Importing existing localization in a .NET project
Suppose that your project is already partly localized, using hand coded function calls to load resource strings, and that you already have translations in multiple languages stored in resource files. If you decide to start using the Multi-Language Add-In for .NET to localize your project, what will happen to the existing localization?
Starting with version 4.52.0003, the Add-In contains a special feature to import existing localization into the Add-In's project database.
This import performs two functions:
- it imports the existing resource strings into the project database and
- it replaces the existing function calls with calls to the function ml_string()
To identify the function calls which are used to load resource strings, you must define a regular expression. We will look at this later on with a couple of examples.
To access the import function, select "Import existing localization" from the tools menu. This will open the dialog shown below. The operation has two steps:
No changes are made to the project in step 1. |
|
|
At the top of the dialog are the two fields:
We'll look at the resource file first, because it is the easier one to understand. |
Selecting the resource file
If your project contains multiple resource files, then you must select the file containing the translations to be imported. You can select the resource file from a drop down list, which contains all of the neutral language resource files in your project.
The list does not contain any language specific resource files or the local resource files used for Forms or UserControls.
If you need to import strings from more than one resource file, then you must repeat the import operation for each file.
Defining the search pattern
The search pattern is defined using a regular expression. The syntax for regular expressions is defined in the Visual Studio Help, for the System.Text.RegularExpressions.RegEx class.
Matching the resource name
The regular expression must perform two tasks:
- it must match the complete function call, identifying the exact text which has to be replaced and
- it must match the parameter specifying the resource name, using a grouping construct.
The resource name must be matched using the named grouping construct with the name param. The syntax for this is
(?<param> ... )
where ... represents the search pattern for the parameter itself. If the resource name is in quotes, then the quotes should not be part of the captured parameter.
Let's look at some examples:
Example 1
In this example we want to detect the function calls to ResMgr.GetString() as shown below:
ListBox1.Items.Add ( ResMgr.GetString ( "Hallo" ) ) ListBox1.Items.Add ( ResMgr.GetString ( "Bye" ) ) ListBox1.Items.Add ( ResMgr.GetString ( "Not present" ) ) |
We can match these calls with the following regular expression
ResMgr\.GetString\s*\(\s*\"(?<param>.*)\"\s*\)
which contains the following elements:
ResMgr\.GetString | This matches the function name ResMgr.GetString. The escape sequence "\." is required to match the literal character ".". |
\s* | This matches any number of white space characters (0 or more). |
\( | This matches the opening bracket. |
\s* | This matches any number of white space characters (0 or more). |
\" | This matches the opening quote. |
(?<param>.*) | This matches any characters and stores the result in the named group "param". The group ends when the closing quote is detected. |
\" | This matches the closing quote. |
\s* | This matches any number of white space characters (0 or more). |
\) | This matches the closing bracket. |
After specifying the regular expression, you can start the search operation by clicking on the "Search" button. The results will be shown in the grid, as below:
The grid contains the following columns:
File | The name of the source code file. |
Text | The column contains complete match. This is the exact text string which will be replaced with the call to the function ml_string(). Make sure that it contains the full function name and parameters up to and including the closing bracket (if there is one - see example 2), but nothing more. |
Param | The text in the name group "param". This should correspond to the name of the resource string (without quotes). |
Exists | Indicates whether the resource string was actually found in the resource file. If the resource string was not found, then the row will have a grey background. The function call will not be converted. |
Resource Text | The resource text. This text has been read from the resource file. |
In the screenshot above, you can see that the three function calls were detected. For the third function call, the resource string was not found.
To actually import the resource strings and convert the function calls, click on the "Import" button. After the operation, the dialog is closed automatically.
The function calls are converted as follows:
ListBox1.Items.Add ( ml_string(6,"Good Morning") ) ListBox1.Items.Add ( ml_string(5,"Have a nice day") ) ListBox1.Items.Add ( ResMgr.GetString ( "Not present" ) ) |
The third call is not converted, because the resource string was not found.
The resource strings in all languages are imported into the Multi-Language Add-In's project database. If necessary, new languages are added to the project. The items will now appear in the source code grid as shown below.
Example 2
In this example we want to detect cases where named resource strings are loaded with the syntax ResourceFile.ResourceName.
ListBox1.Items.Add ( GlobalResources.Hallo ) ListBox1.Items.Add ( GlobalResources.Bye ) |
In this case we can use the regular expression
GlobalResources\.(?<param>[^ \)]*)
which contains the elements:
GlobalResources | This matches the name of the resource file. |
\. | This matches the "." character. |
(?<param>[^ \)]*) | This matches any characters except space or ")" and stores the result in the named group "param". |
After clicking on the search button, the results are shown in the grid:
As before, clicking on "Import" completes the operation. The matches are converted as follows:
ListBox1.Items.Add ( ml_string(8,"Good Morning") ) ListBox1.Items.Add ( ml_string(7,"Have a nice day") ) |
and the resource strings are imported into the Add-In's project database.
At the end of the operation, the dialog is closed automatically and the source code is rescanned in order to update the contents of the source code grid.