Localization Howto

Introduction

ParaView comes with a localization system that handles the complete language introspection workflow, from translation searching in the source code to language selection in the settings.

The theoretical workflow for a single language runs as follows:

In practice, the process is slightly more complex since we use an official translation source repository that is updated by a translations CMS, for simplifying contributions.

Technologies used

Most of the steps are done using two of the Qt5's linguist utilities:

These utilities are invoked in the ParaView CMake build system and in the official ts repository respectively.

What is translated

Glossary

Writing translatable source code

All the source code in ParaView should ideally be translatable. A string is translatable if it can be found by lupdate.

Strings displayed in the ParaView client can come from three main sources:

Qt's UI files are automatically found by lupdate, so if a string shall not be translated (ie ParaView's name !) it has to have its translatable property disabled in Qt Designer.

In the ParaView Qt classes

An exhaustive guide to translatable source code using Qt5 can be found here.

For setting the translatable property of a string in the most common cases:

All these methods requires the include of QCoreApplication.

Some examples:

// When inside a class method with Q_OBJECT macro
class someClass : QObject
{
Q_OBJECT
QString someMethod();
};
QString someClass::someMethod()
{
return tr("Translated string");
}
// When inside a class without Q_OBJECT macro
class someNonQtClass
{
Q_DECLARE_TR_FUNCTIONS(someNonQtClass)
QString someMethod();
};
QString someNonQtClass::someMethod()
{
return tr("Translated string");
}
class someNonQtClass2
{
QString someMethod();
};
QString someNonQtClass2::someMethod()
{
return QCoreApplication::translate("someNonQtClass2", "Translated string");
}
// When outside of any method
QString someFunction()
{
return QT_TRANSLATE_NOOP("translationContext", "Translated string");
}

Making Proxy XML elements translatable

The XML format is not natively supported by lupdate. Therefore, CMake/XML_translations_header_generator.py was developed. It transforms proxy XMLs into C++ headers in order to be found by lupdate.

In a C++ code that displays text from the XML, it is now mandatory to use the context "ServerManagerXML" so that the translation can be found at runtime. E.g.: QCoreApplication::translate("ServerManagerXML", <translated XML element>));.

Currently translatable XML fields are:

This behavior can be extended by adding new elements or attributes to parse in the python utility.

Testing new translations

The plugin TranslationsTesting, bundled with ParaView, is built by default when enabling the PARAVIEW_BUILD_TRANSLATIONS option. It will search though the main window for untranslated strings and print a warning if found.

This plugin is meant to be run through ctest, with the TranslationsTesting test. It might be slow since it uses Regexes for its widget-ignore list (hopefully this list will be empty, otherwise, you will have the time to admire the improved version of ParaView).

Ignoring untranslated strings

Some source strings could not, or should not be translatable (ie ParaView's name !). ParaView translatability is tested on the ParaView's Gitlab CI, so if a string cannot be translated, the widget/action containing it has to be be added on the ignore list of the plugin.

The ignore list is located at Plugins/TranslationsTesting/pqTranslationsTesting.h. You can use either

Both lists take pairs of strings: the first element is the name of the widget and the second is the attribute to ignore or an empty string to ignore all attributes.

The tested Qt attributes are text, toolTip, windowTitle, placeholderText, text and label.

Translation workflow

Source files generation

When PARAVIEW_BUILD_TRANSLATIONS is enabled, translations source files are built in the given PARAVIEW_TRANSLATIONS_DIRECTORY. A specific build target localization can be used separatly from the ALL target to build them.

Source files filling

There is an official paraview-translations repository containing up-to-date source files.

The target files_update will complete all ts files of all languages with the source strings. A single language can also be updated using the special target <locale>_update.

After this step, translators can fill ts files with translations using Qt Linguist or any other tool supporting ts files.

Source file compilation

Source files can be compiled into qm files using the CMake process of the translations repository. Each locale with a folder in the translations repository is a valid target that will create a qm.

It is also possible to compile ts files manually using lrelease. The command is lrelease <input files> -qm <outputQm>.

Binary files loading

Qm files can be loaded from the general settings. If a qm is found by ParaView, the language it provides will be available in the Interface language Combobox. The selected language is saved in the settings, and a restart is required.

By default, ParaView searches for qms in the translations shared folder. The environment variable PV_TRANSLATIONS_DIR can provide other searching paths. When multiple qm files have the same language, the first qm found will be used, using the PV_TRANSLATIONS_DIR paths first, and the default path after.

The locale can also be forced using the PV_TRANSLATIONS_LOCALE environment variable.