Localization

The Dolby Conference Phone user interface supports 12 languages (not counting English). This document describes the process to add language support to a Dolby Conference Phone application. The basic approach is:

  • In the Servermain.qml file, add the UITranslationLoader component.
  • In the app source code, preface strings that require language translation with the qsTr function.
  • Generate translation source (TS) or, optionally, XML localization interchange (XLF) files from the source code.
  • Translate words and phrases in the TS or XLF files into other languages.
  • Convert the TS or XLF files into compiled language translation (QM) files.
  • Sign the app (the QM files need to be included in the signing process).
  • Download the app to the Dolby Conference Phone.
  • Change the Dolby Conference Phone's language settings.

The above steps can be done using the Dolby IDE. While a Qt language translator tool exists, 3rd party translators will likely use other translation software.

Add the qsTr function to the app source code

The qsTr function must be added to every line containing a UI string that needs to be translated.

Examples of qsTr usage:

text:  "This line does not require language translation."

text:  qsTr("Hello World!")

connectingScreenContext.title = qsTr("Starting the meeting");

roomLabel = qsTr("%1 (%2)").arg(roomLabel).arg(participants.count);

labelText: (context.conference.muted === true) ? qsTr("Unmute all") : qsTr("Mute all")

text: qsTr("The conference phone will restart in "+ countdown +" seconds");

Meta data tags such as //: can be used to add context to text requiring translation. See Adding Meta-Data to Strings

Some text will require special consideration, e.g., automatically-generated numbers, dates, etc. Refer to the Writing Source Code for Translation Qt documentation.

File generation and conversion tools

The localization process consists of a series of file generation and conversion steps. While these can be done using drop-down menus in the Qt Creator application, the assumption is that developers will automate this process using scripts.

csaf-linguist is a script that calls Qt linguist programs. This script provides more granular control than the Qt Creator drop-down menu functions. The following table shows the script's four functions:

Function NameDescription
lupdateCreate TS files
lconvert-ts-xlfConvert TS files to XLF files
lconvert-xlf-tsConvert XLF files to TS files
lreleaseCreate QM files

The csaf-linguist help info:

[root@dcp-sdk hello-world]# /usr/lib64/qt4/bin/csaf-linguist -h
Usage: /usr/lib64/qt4/bin/csaf-linguist <tool> [-i srcdir] [-o outdir]

Options:
    <tool>
        lupdate, lrelease, lconvert-ts-xlf, or lconvert-xlf-ts
    -i srcdir
        Input directory. Defaults to the current directory,
        $PWD/resources/ts, or $PWD/resources/xlf depending
        on the value of <tool>.
    -o outdir
        Output directory. Defaults to $PWD/resources/ts,
        $PWD/resources/qm, or $PWD/resources/xlf depending
        on the value of <tool>.
    -p prefix
        Prefix of translation filenames. Defaults to 'app_'.
    -h
        Display this help.
[root@dcp-sdk localization]#

Note: To make the language file names easier to recognize, append an underscore after the -p option string.

To run these functions via the Qt Creator application, open a project in Qt Creator and then use the Tools > External > Linguist drop-down menu to list the conversion functions. Of the six listed, only use:

  • Update CSAF App Translations (lupdate)
  • Release CSAF App Translations (lrelease)
  • Convert Translations (TS to XLIFF)
  • Convert Translations (XLIFF to TS)

The following screenshot shows the Qt Creator drop-down menu options:

Generate TS or XLF files

A TS, or translation source file, contains the original English strings from the app source code along with placeholder fields for the substitute language translations. One TS file is created for each different language. The following command is used to parse the app source code files and generate the TS files:

# csaf-linguist lupdate -i appFileDirectory -o tsFileDirectory -p DolbyConfPhoneApp_

The translations are often done by 3rd party vendors who use language editing tools to automate the translation process. The input files for these tools can be either TS or XLF files. XLF files can be generated from TS files with this command:

# csaf-linguist lconvert-ts-xlf -i tsFileDirectory -o xlfFileDirectory -p DolbyConfPhoneApp_

The TS or XLF files are then provided to the translator vendor or consultant.

Add text translations to the TS or XLF files

The translator vendor or consultant performs the translations, i.e., the translated words and phrases are inserted into the TS or XLF placeholder fields.

While translators likely rely on different tools, the Qt Linguist application can also be used to translate qsTr-tagged strings. Here is one way to start the tool:

# linquist-qt4 &

The following two screenshots show the Qt Linguist application.

Convert TS or XLF files into QM files

The vendor or consultant returns the translated TS or XLF files to the developer.

The XLF files must be converted to TS files:

# csaf-linguist lconvert-xlf-ts -i xlfFileDirectory -o tsFileDirectory -p DolbyConfPhoneApp_

QM files are binary files that contain the language translation lookup information. The QM files are downloaded with the app to the Dolby Conference Phone. Because of this, the QM files need to be copied into (or created in) an app development subfolder so that they can be included when signing the app.

The QM files are generated using the TS files:

# csaf-linguist lrelease -i tsFileDirectory -o qmFileDirectory -p DolbyConfPhonApp_

The app needs to be signed before it can be downloaded to the Dolby Conference Phone.

Set the Dolby Conference Phone language

The Dolby Conference Phone's language setting can be set three ways:

  • Via configuration parameter: Preferences.Localization.Language
  • Using the web interface: Settings > User Preferences > Localization > Language
  • Using the Dolby Conference Phone interface: Settings icon > Preferences > Language

See section "6.3.6 Setting the language" in the Dolby Conference Phone Administrator's Guide. This document is on the Dolby web site.

Example using the hello-world project

This section uses the hello-world IDE sample project to show the steps involved in translating one string from English to Spanish. The following shows the project directory path and the directory's contents.

[root@dcp-sdk hello-world]# pwd
/usr/share/nginx/html/apps/hello-world


[root@dcp-sdk hello-world]# ls -al
total 24
drwxr-xr-x. 2 root root 4096 Jul 11 19:12 .
drwxr-xr-x. 8 root root 4096 Jul 11 19:09 ..
-rw-r--r--. 1 root root  123 Jul 11 19:09 .app.cfg
-rw-r--r--. 1 root root  794 Jul 11 19:09 hello-world.qmlproject
-rw-r--r--. 1 root root   30 Jul 11 19:09 qmldir
-rw-r--r--. 1 root root 1281 Jul 11 19:12 Servermain.qml
[root@dcp-sdk hello-world]#

Add the UITranslationLoader component to the beginning of Servermain.qml:

import QtQuick 1.1
import com.dolby.dcp.components 1.0
import com.dolby.dcp.engine 1.0

UIApplication {
    // Run this app immediately once it is loaded.
    autoLaunchAfterLoad: true

    UITranslationLoader {
        id: loader

        // Based on the configuration.language.value setting (e.g., "es"),
        // create a path and load the QM translation file.
        //
        // The "null" logic is a workaround to avoid generating an error message if the language is set to English
        // (when no English file needs to be loaded).

        source: (configuration.language.value !== 'en') ? "languageFiles/qm/hello-world_" + configuration.language.value + ".qm" : ""
    }

    Component
    {
        // Identifier for helloworld page.
        id: helloWorld
        .
        .
        .

Add the qsTr function to the line with the string in Servermain.qml.

//  text: "Hello, world!"    //  Original line
text: qsTr("Hello, world!")  //  Added translator function

Instead of using the default resources subdirectory, create a different one along with a folder for the TS files.

[root@dcp-sdk hello-world]# mkdir languageFiles
[root@dcp-sdk hello-world]# mkdir languageFiles/ts

Generate the TS files. Add an underscore after the hello-world project name to make the TS files easier to identify.

[root@dcp-sdk hello-world]# /usr/lib64/qt4/bin/csaf-linguist lupdate -o $PWD/languageFiles/ts -p hello-world_
Updating 'languageFiles/ts/hello-world_ar.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_de.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_es.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_fr.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_he.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_it.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_ja.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_ko.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_pt.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_pt_BR.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_zh-Hans.ts'...
    Found 1 source text(s) (1 new and 0 already existing)
Updating 'languageFiles/ts/hello-world_zh-Hant.ts'...
    Found 1 source text(s) (1 new and 0 already existing)

The TS files are created in the languageFiles/ts directory.

[root@dcp-sdk hello-world]# ls languageFiles/ts
hello-world_ar.ts  hello-world_es.ts  hello-world_he.ts  hello-world_ja.ts  hello-world_pt_BR.ts  hello-world_zh-Hans.ts
hello-world_de.ts  hello-world_fr.ts  hello-world_it.ts  hello-world_ko.ts  hello-world_pt.ts     hello-world_zh-Hant.ts
[root@dcp-sdk hello-world]#

If XLF files are required, create them using this command (first, create the XLF subdirectory). Add an underscore after the hello-world project name to make the XLF files easier to identify.

[root@dcp-sdk hello-world]# mkdir languageFiles/xlf

[root@dcp-sdk hello-world]# /usr/lib64/qt4/bin/csaf-linguist lconvert-ts-xlf -i $PWD/languageFiles/ts -o $PWD/languageFiles/xlf -p hello-world_
lconvert hello-world_ar.ts hello-world_ar.xlf
lconvert hello-world_de.ts hello-world_de.xlf
lconvert hello-world_es.ts hello-world_es.xlf
lconvert hello-world_fr.ts hello-world_fr.xlf
lconvert hello-world_he.ts hello-world_he.xlf
lconvert hello-world_it.ts hello-world_it.xlf
lconvert hello-world_ja.ts hello-world_ja.xlf
lconvert hello-world_ko.ts hello-world_ko.xlf
lconvert hello-world_pt.ts hello-world_pt.xlf
lconvert hello-world_pt_BR.ts hello-world_pt_BR.xlf
lconvert hello-world_zh-Hans.ts hello-world_zh-Hans.xlf
lconvert hello-world_zh-Hant.ts hello-world_zh-Hant.xlf
[root@dcp-sdk hello-world]#

The resulting XLF files:

[root@dcp-sdk hello-world]# ls languageFiles/xlf
hello-world_ar.xlf  hello-world_fr.xlf  hello-world_ja.xlf     hello-world_pt.xlf
hello-world_de.xlf  hello-world_he.xlf  hello-world_ko.xlf     hello-world_zh-Hans.xlf
hello-world_es.xlf  hello-world_it.xlf  hello-world_pt_BR.xlf  hello-world_zh-Hant.xlf
[root@dcp-sdk hello-world]#

Translate the Spanish language XLF file by adding "Hola mundo!" in the line with target xml. This is the unedited XML file:

[root@dcp-sdk hello-world]# cat languageFiles/xlf/hello-world_es.xlf
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:trolltech="urn:trolltech:names:ts:document:1.0">
  <file original="../../Servermain.qml" datatype="plaintext" source-language="en" target-language="es-ES"><body>
    <group restype="x-trolltech-linguist-context" resname="Servermain">
      <trans-unit id="_msg1">
        <source xml:space="preserve">Hello, world!</source>
        <target xml:space="preserve"></target>
        <context-group purpose="location"><context context-type="linenumber">23</context></context-group>
      </trans-unit>
    </group>
  </body></file>
</xliff>
[root@dcp-sdk hello-world]#

Edit the line to add the translation:

<target xml:space="preserve">Hola mundo!</target>

The original Spanish language TS file does not yet have the translated field in the translation type line:

[root@dcp-sdk hello-world]# cat languageFiles/ts/hello-world_es.ts
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="es_ES">
<context>
    <name>Servermain</name>
    <message>
        <location filename="../../Servermain.qml" line="23"/>
        <source>Hello, world!</source>
        <translation type="unfinished"></translation>
    </message>
</context>
</TS>
[root@dcp-sdk hello-world]#

Convert the XLF files back to TS files.

[root@dcp-sdk hello-world]# /usr/lib64/qt4/bin/csaf-linguist lconvert-xlf-ts -i $PWD/languageFiles/xlf -o $PWD/languageFiles/ts -p hello-world_
lconvert hello-world_ar.xlf hello-world_ar.ts
lconvert hello-world_de.xlf hello-world_de.ts
lconvert hello-world_es.xlf hello-world_es.ts
lconvert hello-world_fr.xlf hello-world_fr.ts
lconvert hello-world_he.xlf hello-world_he.ts
lconvert hello-world_it.xlf hello-world_it.ts
lconvert hello-world_ja.xlf hello-world_ja.ts
lconvert hello-world_ko.xlf hello-world_ko.ts
lconvert hello-world_pt.xlf hello-world_pt.ts
lconvert hello-world_pt_BR.xlf hello-world_pt_BR.ts
lconvert hello-world_zh-Hans.xlf hello-world_zh-Hans.ts
lconvert hello-world_zh-Hant.xlf hello-world_zh-Hant.ts
[root@dcp-sdk hello-world]#

The following shows the addition of the "Hola mundo!" text in the converted TS file.

[root@dcp-sdk hello-world]# cat languageFiles/ts/hello-world_es.ts
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="es_ES">
<context>
    <name>Servermain</name>
    <message>
        <location filename="../../Servermain.qml" line="23"/>
        <source>Hello, world!</source>
        <translation type="unfinished">Hola mundo!</translation>
    </message>
</context>
</TS>
[root@dcp-sdk hello-world]#

Create a directory for the final set of language translation files; then generate the QM files. Note that since only the Spanish language file was modified, it is the only one that is generated (see arrow on right).

[root@dcp-sdk hello-world]# mkdir languageFiles/qm

[root@dcp-sdk hello-world]# /usr/lib64/qt4/bin/csaf-linguist  lrelease -i languageFiles/ts/ -o languageFiles/qm/ -p hello-world_
Updating 'languageFiles/qm//hello-world_ar.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_de.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_es.qm'...
    Generated 1 translation(s) (0 finished and 1 unfinished)     < < < <
Updating 'languageFiles/qm//hello-world_fr.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_he.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_it.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_ja.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_ko.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_pt.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_pt_BR.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_zh-Hans.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
Updating 'languageFiles/qm//hello-world_zh-Hant.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 1 untranslated source text(s)
[root@dcp-sdk hello-world]#

Here are the QM files:

[root@dcp-sdk hello-world]# ls languageFiles/qm
hello-world_ar.qm  hello-world_es.qm  hello-world_he.qm  hello-world_ja.qm  hello-world_pt_BR.qm  hello-world_zh-Hans.qm
hello-world_de.qm  hello-world_fr.qm  hello-world_it.qm  hello-world_ko.qm  hello-world_pt.qm     hello-world_zh-Hant.qm
[root@dcp-sdk hello-world]#

Modify the .app.cfg file and sign the app.

Use the Load and run the app instructions to configure a Dolby Conference Phone to download the hello-world app. After changing the language setting to Spanish, you should see the following displayed on the Dolby Conference Phone.