Localizing your UI

Cascades uses the standard Qt mechanism for string localization. To translate your application for the international market, you must identify what needs to be translated and translate it.

Configure your app for translation

If you use a Cascades template in the Momentics IDE for BlackBerry for your Cascades application, your project folder is automatically configured for translation. By default, a translations folder is created in your project folder and it adds a .pro file.

An application's .pro file typically contains SOURCES and HEADERS variables that provide the paths to C++ resources. Most .pro files also have an lupdate_inclusion block. You must include paths to all QML resources so that the lupdate string extraction utility extracts UI strings from all QML resources. For example:

lupdate_inclusion {
    SOURCES += ../assets/*.qml
    SOURCES += ../assets/settings/*.qml
    SOURCES += ../assets/whatever/*.qml
}

The bar-descriptor.xml file

The locale support section of the bar-descriptor.xml file includes the location of your translation folder and the name of your .qm file. For example:

    <!-- Locale support -->
    <asset path="translations" dest="qm">
        <include name="*.qm"/>
    </asset>

If you change the location of your .qm file, you must specify the new location so that all your compiled translation resources are available when you build your application.

Translator

A translator reads the .qm file and replaces the strings that are identified for translation with the translated ones. A translator is loaded typically at the beginning of an application in the constructor of the ApplicationUI. If you use one of the provided templates to create your application, a translator is already added to the applicationui.cpp file.

Here's an example of a translator:

QTranslator translator;
    QString locale_string = QLocale().name();
    QString filename = QString( "sample_%1" ).arg( locale_string );
    if (translator.load(filename, "app/native/qm")) {
        app.installTranslator( &translator );
    }

For more information on configuring the constructor for localization, see Display language.

Identify text for translation

You can identify text for translation by using Qt translate functions.

Identifying text in functions and Qt objects

You can identify the text to be translated in QML by using the qsTr() function. For example:

Label {
	text: qsTr ("Hello world")
}

Identifying text for translation in C++

To identify the strings you want to translate, you must wrap the strings with the tr() method in C++. The tr()function allows you to identify the text, the context of the text (optional), and the plurality of the text. The tr() method is defined as follows:

QString QObject::tr(const char * sourceText, 
    const char *disambiguation = 0, int n=-1)

In the above definition, the sourceText identifies the text to be translated, disambiguation allows for you to optionally provide context about the text to be translated, and n allows for specifying plurality of the text.

You have 1 new message
You have 2 new message(s)

The above example can be localized as the following text:

You have 1 new message
You have 2 new messages
int n = messages.count();
bb::system::LocaleHandler region( bb::system::LocaleType::Region );
msg = tr("You have %1 new message(s).", "", n).arg(region.locale().toString(n));

The tr() function not only identifies the text that needs to be collected into a translation file, it also reads the translation files and replaces the source text with the translated text, if it is available.

Identifying text outside of functions

When you need to translate text outside of functions or QObjects, you can use the following two macros:

QT_TR_NOOP( "sourceText" )

QT_TRANSLATE_NOOP( "context", "sourceText" )

These two macros mark the string for extraction to the .ts file. They don't cause the application to perform any translation tasks at runtime unlike the tr() function. To translate the text, it must run through the tr() function. Here's an example:

static const char *baseNames = {
    QT_TR_NOOP("adenine"),
    QT_TR_NOOP("cytosine"),
    QT_TR_NOOP("guanine"),
    QT_TR_NOOP("thymine")
};

QString base(int num) {
    return tr(baseNames[num]);
}

Create translation files

When you have identified the strings that need to be translated, you can use the lupdate command-line tool to produce .ts translation files. The lupdate command collects all the identified strings into a group of XML files (one for each language). If you are using any of the Cascades templates in the Momentics IDE, this process is automatically configured for you so that each time you build your application the translation files are created in the translation folder.

The following is a sample .ts file that shows one string from a C++ file and another from a QML file. It provides the location of the string, and the number line. It also provides the source text and the content.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en_GB">
<context>
    <name>main</name>
    <message>
        <location filename="../assets/app.cpp" line="6"/>
        <source>My String</source>
	<comment>My Context</comment>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../assets/main.qml" line="12"/>
        <source>Hello world</source>
        <translation type="unfinished"></translation>
    </message>
</context>
</TS>

In a typical application development process, when the .ts files are generated, they are sent for translation. Here's an example of a .ts file which has been translated from English to Spanish:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="es_ES">
<context>
    <name>main</name>
    <message>
        <location filename="../assets/app.cpp" line="6"/>
        <source>My String</source>
	<comment>My Context</comment>
        <translation>Mi cadena</translation>
    </message>
    <message>
        <location filename="../assets/main.qml" line="12"/>
        <source>Hello world</source>
        <translation>Hola, mundo</translation>
    </message>
</context>
</TS>

Subsequent builds automatically update the .ts files with additional strings, however the current translations aren't lost. The build process also calls the lrelease function for each build. This process converts the .ts files into binary .qm files. These .qm files are copied as assets to the device and are used as the source for the tr() and qsTr() functions.

Last modified: 2014-09-30



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus