This guide will explain how to create internationalization support (ie: dictionaries files) and to use it to translate an application.
First of all you need to create a po
directory into your root application folder and POTFILES.in in it.
helloapp
|_ po
|_ POTFILES.in
|_ src
|_ main.cpp
|_ hello.cpp
|_ headers
|_ hello.h
Into the POTFILES.in you MUST add the relative path of all files you want to translate. For example, if you only have translation in hello.cpp, the POTFILES.in looks like:
$ cat po/POTFILES.in
src/hello.cpp
You need to add a translate
node into the qiproject.xml file.
This configuration is used by qilinguist
to generate translation files
and installation rules.
The qiproject.xml will look like:
<project name="helloApp">
<translate name="helloApp" domain="hello" linguas="fr_FR en_US" tr="gettext" />
</project>
name
: The name of the application or library.domain
: The name of the generated dictionary.linguas
: A list of all locales supported formatted as xx_XX (country and language code)tr
: Define if you use gettext or QT internationalization (value can be: “gettext” or “qt”).Dictionaries will be install into:
<sdk_path>/share/locale/<name>/<linguas>/LC_MESSAGES/<domain>.mo
Everything is ready to generate and edit dictionaries.
Warning
Some po configuration isn’t correct (example: jp_JP.po, fr_FR.po). You need to replace
"Content-Type: text/plain; charset=ASCII\n"
by
"Content-Type: text/plain; charset=UTF-8\n"
First of all you need to generate or update translatable files by using qilinguist update
. This will create files (into po
folder) you can edit using Linguist from the Qt SDK or poedit for instance.
Once you have translated those files, you need to compile them by using qilinguist release
.
You must add the qi_create_trad(projectname “po”) into the CMakeLists.txt root file.
cmake_minimum_required(VERSION 2.8)
project(yourProjectName)
qi_create_trad(yourProjectName "po")
You need to get a default qi::Translator, then you MUST set the default domain and current locale.
name
the name of the application or library.domain
the name of the generated dictionary.locale
the name of the default locale formatted as xx_XX (country and language code)Warning
The name
and domain
must be the same as those define into the qiproject.xml
Warning
The locale
must be a locale supported and define into the qiproject.xml, otherwise it will fallback to the default value.
You can add some domains by using qi::Translator::addDomain. This will allow qi::Translator to look it multiple dictionary.
You can change the locale you want to use by calling qi::Translator::setCurrentLocale. This function allows you to set and switch language at runtime.
All sentences will be parsed when calling qilinguist update, then generate translation files (ie: po/ts files). Then, at runtime qi::Translator::translate will look for translation regarding initialization done in the last paragraph.
You can use boost format to add variable that won’t be translate:
std::string name = "nao";
std::string msgTranlate = boost::format(qi::tr("Hello my name is %s") % name);
/*
* Copyright (c) 2013 Aldebaran Robotics. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the COPYING file.
*/
#include <iostream>
#include <qi/application.hpp>
#include <qi/os.hpp>
#include <qi/translator.hpp>
int main(int argc, char *argv[])
{
qi::Application app(argc, argv);
app.setName("qitranslate");
qi::Translator &tl = qi::defaultTranslator(app.name());
tl.setCurrentLocale("en_US");
tl.setDefaultDomain("translate");
std::cout << qi::tr("Hi, my name is NAO.") << std::endl;
std::cout << qi::tr("Where is Brian?") << std::endl;
std::cout << qi::tr("Brian is in the kitchen.") << std::endl;
tl.setCurrentLocale("fr_FR");
std::cout << qi::tr("Hi, my name is NAO.") << std::endl;
std::cout << qi::tr("Where is Brian?") << std::endl;
std::cout << qi::tr("Brian is in the kitchen.") << std::endl;
std::cout << qi::tr("Brian is in the kitchen.", "", "en_US") << std::endl;
std::cout << qi::tr("Brian is in the kitchen.", "", "fr_FR") << std::endl;
}