Developer Translation Documentation
Mumble makes use of the Qt framework. This is also the case for translations. We follow the Qt tools and translation workflow.
Translators can translate our project in our Mumble Weblate project without a need for Git, Code, or programs other than their web browser.
.ts translation files are located in the Mumble repository in
We currently version a
mumble_en.ts as a reference file for translations, and individual files for each locale we support (which each holds the source strings too anyway).
Qt supports both an ID-based approach as well as a source + translated text approach. Weblate calls the ID based approach monolingual (a ts file does not contain the source text) and bilingual (a ts files contains both source and translated text).
We effectively work with the bilingual file approach, but have the Weblate project set up as if it were ID based. This is for historic reasons and should be changed in the future.
Adding a language
To add a new language the ts file is created with
lupdate, and a file reference is added to the
ts_files variable in
Creating translatable strings
In Qt translation strings have a context – a class context. The fallback is the QApplication context. But any
Q_OBJECT class introduces their own context. In the
ts file texts are grouped by context.
NOTE: To provide structure to the many translation strings,
tr should be called on the most reasonably specific class. (Calling it on the base
QObject will make it fall back to the generic
Classes not extending from QObject can also be extended with the
tr context functionality.
See also upstream documentation Using tr() for All Literal Text (and the context around it).
Numbers and Dates
Special care has to be taken for formatting date and time and numbers. The format of these differs by locale, and may be disassociated from the language a user uses too.
See also QLocale and other Qt classes for date, time and numbers.
- Using tr() to Localize Numbers (shows only one case/may not be the best approach)
Identical text in the same context can be disambiguated with an additional identifying string.
QLabel *senderLabel = new QLabel(tr("Name:", "sender")); QLabel *recipientLabel = new QLabel(tr("Name:", "recipient"));
Plurals have special handling in general and between languages. Depending on the locale/language, a plural (word) may differ between 0, 1, 2. And they may differ in different ways.
Numbered plurals are marked with a
(s) word postfix like
Notably this will not show up as
word(s) in the program, but as
words depending on the parameter value.
The translation files (ts files) may have any number of
<numerusform> elements as translations, rather than just one translation text.
<message numerus="yes"> <source>Ban List - %n Ban(s)</source> <translation> <numerusform>Bannliste - %n Bann</numerusform> <numerusform>Bannliste - %n Bann(s)</numerusform> </translation> </message>
Other languages may have three forms.
Numbered Arguments (Ordered)
The order of arguments within a string may change with a text translation. Numbering them and passing values with
arg() will allow translators to change the order as they see fit.
label.setText(tr("%1 of %2 files copied.\nCopying: %3") .arg(done) .arg(total) .arg(currentFile));
A translator comment may help them identify parameters if not obvious from the source text.
Programs typically show these while holding down ALT, and single characters can be used to activate controls allowing for keyboard-based usage of GUI applications. While ALT is pressed the mnemonic key is usually underlined.
The typical ampersand
& markers are used to define mnemonics on a control text.
E&xitwould lead to
xbeing the mnemonic
&Exitwould lead to
ebeing the mnemonic
In both cases, the displayed text on the control will be
QKeySequence to use keyboard shortcuts so they are translatable too.
exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit);
Translating text outside of classes
Classes provide code structure. Yet sometimes text may end up outside of classes and Qt classes, and reasonably so.
tr can be called as a public static method on an appropriate class the text belongs to. Or
QCoreApplication::translate can be called directly.
For text without context the
QT_TRANSLATE_NOOP macros can be used.
Translating text often requires context. It can be difficult to grasp a texts context from just the source string. Without the program or source code open and next to the source string, it can be impossible to grasp the context.
Translator comments can help provide context to a source string.
//: This name refers to a host name. hostNameLabel->setText(tr("Name:")); /*: This text refers to a C++ code example. */ QString example = tr("Example");
Additional metadata can be attached to translatable text for advanced behavior, also further down the line on translation platforms.
We make use of
qt5_create_translation. This will call
The ts translation files are stripped of unrelated, unused texts (they contain text for multiple platforms while the program is compiled for just one), and then packaged into the application (through the Qt resource system; qrc definition file).
Regarding Qt resources see The Qt Resource System.