Translating a Qt application that contains tr() calls is a three-step process:
Steps 1 and 3 are performed by application developers. Step 2 is handled by translators. This cycle can be repeated as often as necessary during the application's development and lifetime.
As an example, we will show how to translate the Spreadsheet application of Chapter 3. The application already contains tr() calls around every user-visible string.
First, we must modify the application's .pro file slightly to specify which languages we want to support. For example, if we want to support German and French in addition to English, we would add the following TRANSLATIONS entry to spreadsheet.pro:
TRANSLATIONS = spreadsheet_de.ts spreadsheet_fr.ts
Here, we specify two translation files: one for German and one for French. These files will be created the first time we run lupdate, and are updated every time we subsequently run lupdate.
These files normally have a .ts extension. They are in a straightforwardXML format and are not as compact as the binary .qm files understood by QTranslator. It is lrelease's job to convert human-readable .ts files into machine-efficient .qm files. For the curious, .ts stands for "translation source" and .qm for "Qt message" file.
Assuming that we are located in the directory that contains the Spreadsheet application's source code, we can run lupdate on spreadsheet.pro from the command line as follows:
lupdate -verbose spreadsheet.pro
The -verbose argument is optional. It tells lupdate to provide more feedback than usual. Here's the expected output:
Updating 'spreadsheet_de.ts'... 0 known, 101 new and 0 obsoleted messages Updating 'spreadsheet_fr.ts'... 0 known, 101 new and 0 obsoleted messages
Every string that appears within a tr() call in the application's source code is stored in the .ts files, along with an empty translation. Strings that appear in the application's .ui files are also included.
The lupdate tool assumes by default that the arguments to tr() are Latin-1 strings. If this isn't the case, we must add a CODEC entry to the .pro file. For example:
CODEC = EUC-JP
This must be done in addition to calling QTextCodec::setCodecForTr() from the application's main() function.
Translations then need to be added to the spreadsheet_de.ts and spreadsheet_fr.ts files using Qt Linguist, a GUI tool for translating Qt applications.
To launch Qt Linguist, click Qt 3.2.x|Qt Linguist in the Start menu on Windows, type linguist on the command line on Unix, or double-click linguist in the Mac OS X Finder. To start adding translations to a .ts file, click File|Open and choose the file.
The left-hand side of Qt Linguist's main window shows the list of contexts for the application being translated. For the Spreadsheet application, the contexts are "FindDialog", "GoToCellDialog", "MainWindow", "SortDialog", and "Spreadsheet". The top-right area is the list of source texts for the current context. Each source text is shown along with with a translation and a Done flag. The middle-right area is where we can enter a translation for the current source item. The bottom-right area is a list of suggestions automatically provided by Qt Linguist.
Once we have a translated .ts file, we need to convert it to a binary .qm file for it to be understandable by QTranslator. To do this from within Qt Linguist, click File|Release. Typically, we would start by translating only a few strings and run the application with the .qm file to make sure that everything works.
Figure 15.2. Qt Linguist in action
If we want to regenerate the .qm files for all .ts files, we can use the lrelease command-line tool as follows:
lrelease -verbose spreadsheet.pro
Assuming that we translated 19 strings to French and clicked the Done flag for 17 of them, lrelease produces the following output:
Updating 'spreadsheet_de.qm'... 0 finished, 0 unfinished and 101 untranslated messages Updating 'spreadsheet_fr.qm'... 17 finished, 2 unfinished and 82 untranslated messages
Untranslated strings are shown in the original languages when running the application. The Done flag isn't used by lrelease; it can be used by translators to identify which translations are finished and which ones must be revisited.
When we modify the source code of the application, the translation files may become out of date. The solution is to run lupdate again, provide translations for the new strings, and regenerate the .qm files. Some development teams find it useful to run lupdate frequently, while others prefer to wait until just before a final product release.
The lupdate and Qt Linguist tools are quite smart. Translations that are no longer used are kept in the .ts files in case they are needed in later releases. When updating .ts files, lupdate uses an intelligent merging algorithm that can save translators considerable time with text that is the same or similar in different contexts.
For more information about Qt Linguist, lupdate, and lrelease, refer to the Qt Linguist manual at http://doc.trolltech.com/3.2/linguist-manual.html. The manual contains a full explanation of Qt Linguist's user interface and a step-by-step tutorial for programmers.