Dnia 2011-06-07, wto o godzinie 15:17 -0700, margie_foster pisze: > How developers of qml-based apps should be using comments for qsTr() / > tr().
Hello,
I would like to include some as-of-yet unused i18n features that would
enormously increase the quality (and speed) of our translations. I blame
lack of documentation on the subject for QML. Some of the things covered
I got directly from source code.
Problem
=======
The two most important i18n concepts that are currently unused in all
MeeGo QML code are:
1. context [1]
2. plural handling [2]
Ad. 1
=====
Each QML file has a separate context (the file name, without extension)
in terms of translation strings. That's all good in itself, but if there
are identical translatable strings in two different files in a project,
they need to get translated twice. Just as if you've used
disambiguation. As an example, some of the current UX apps one QML file
for portrait and one for landscape orientation or a separate file for
different views. Each of those file have multiple translation strings in
common, yet translators see several identical strings that they need to
translate multiple times.
Solution
========
> qsTranslate("context", "Translatable string")
where "context" is either of:
* an arbitrary string (e.g. "SomeApp")
* name of the main file where the strings are originally
translated (without extension, e.g. "main") - you can then use
simple qsTr() syntax in the main.qml file
This way, all the common strings will only need to be translated once
and your application's translations will be consistent.
There's also another way, sadly it will be available in Qt 4.8 [3] [4].
The following comment will change the translation context for all
subsequent calls to qsTr(). You could put that at the top of your qml
files and that's all that would be required to unify the translatable
strings.
> // TRANSLATOR MyApp
Ad. 2
=====
English is easy. "One computer", "Two computers". Just slap a "s" onto
the back of a computer and you have two or more. Others have to buy the
second one. In most languages, providing two strings: "One computer", "%
1 computers" is enough, but some have more forms depending on the number
of computers.
Solution
========
> qsTr("%n computer(s)", "disambiguation", n)
> qsTranslate("context", "%n computers(s)", "disambiguation", "CodecForTr", n)
where disambiguation is the optional "comment" Margie wrote about in the
previous e-mail (use empty string if not needed) and n is the count of
apples. "CodecForTr" is the encoding used, see [5].
Translators for English will then provide:
* "%n computer" or - even better - "one computer" for n == 1,
* "%n computers" for n >= 1
Translators for Polish will provide:
* "%n komputer" or "jeden komputer" for n == 1,
* "%n komputery" for... there's a bunch of cases, see e.g. [6]
* "%n komputerów" for some other cases
* "%n komputera" for all the rest
Qt will then take care of the rest. It will display:
* "one computer" / "jeden komputer"
* "2 computers" / "2 komputery"
* "5 computers" / "5 komputerów"
* "0.5 computers" / "0.5 komputera"
* etc.
It's a win-win situation - you, as a developer, only need to provide one
translatable string: "%n computer(s)", translators will provide all the
proper forms in their language, and the app will look great in all
languages. The only thing I'm not 100% sure of, is whether Transifex
supports plural forms from TS files. Dimitris? Diego?
NOOPs
=====
There are also two NOOP "macros":
> QT_TR_NOOP()
> QT_TRANSLATE_NOOP()
which have roughly the same meaning that qsTr() and qsTranslate() have,
respectively, except that they return the original, untranslated string
and don't handle plurals. Their purpose is to mark for translation
strings that are supposed to be translated dynamically. [7] [8]
Testing
=======
I'm attaching three QML files with which you can see all that I've
described above. Disambiguation and translator comments are tested, too.
Summary
=======
I recommend [9] as a reading exercise for everyone. Even though it talks
mostly Qt, not QML, the concepts are the same. It would be best if
someone converts this post into a proper wiki page. [10]
The complete argument list for the functions are:
> qsTr(string, disambiguation="", count=-1)
> QT_TR_NOOP(string, disambiguation="")
> qsTranslate(context, string, disambiguation="", encoding="CodecForTr",
> count=-1)
> QT_TRANSLATE_NOOP(context, string, disambiguation="")
Apologies
=========
Please forgive me this lengthy post, but the topics covered are dear to
me. You know, as the one that needs to buy his second computer. ;>
[1]
http://doc.qt.nokia.com/latest/i18n-source-translation.html#defining-a-translation-context
[2]
http://doc.qt.nokia.com/latest/i18n-source-translation.html#handling-plurals
[3] http://bugreports.qt.nokia.com/browse/QTBUG-15502
[4]
http://qt.gitorious.org/qt/qt/commit/9e06896a9a49685dc97eb2aafdf55eef33a75507
[5] http://doc.qt.nokia.com/latest/qcoreapplication.html#Encoding-enum
[6] http://www.gnu.org/s/hello/manual/gettext/Plural-forms.html
[7] http://doc.qt.nokia.com/4.7-snapshot/qtglobal.html#QT_TR_NOOP
[8] http://doc.qt.nokia.com/4.7-snapshot/qtglobal.html#QT_TRANSLATE_NOOP
[9] http://doc.qt.nokia.com/latest/i18n-source-translation.html
[10] http://wiki.meego.com/QML/Internationalisation
--
Michał (Saviq) Sawicz <[email protected]>
import QtQuick 1.0
Rectangle {
width: 360
height: 360
Text {
id: first
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: "Hello World"
}
Text {
id: second
anchors.top: first.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: standard translatable
text: qsTr("First translatable string")
}
Text {
id: third
anchors.top: second.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: translatable with disambiguation
text: qsTr("Second translatable string", "first")
}
Text {
id: fourth
anchors.top: third.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: second translatable with disambiguation
text: qsTr("Second translatable string", "second")
}
Text {
id: fifth
anchors.top: fourth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: translatable with plural forms
text: qsTr("%n plural(s)", "", 1)
}
Text {
id: sixth
anchors.top: fifth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: second comment here, unnecessary
text: qsTr("%n plural(s)", "", 2)
}
Text {
id: seventh
anchors.top: sixth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: qsTr("%n plural(s)", "", 5)
}
Text {
id: eighth
anchors.top: seventh.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: QT_TR_NOOP("First translatable string")
}
Text {
id: nineth
anchors.top: eighth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: QT_TR_NOOP("Second translatable string", "second")
}
}
import QtQuick 1.0
Rectangle {
width: 360
height: 360
Text {
id: first
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: "Hello World"
}
Text {
id: second
anchors.top: first.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: standard translatable
text: qsTranslate("i18n-test", "First translatable string")
}
Text {
id: third
anchors.top: second.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: translatable with disambiguation
text: qsTranslate("i18n-test", "Second translatable string", "first")
}
Text {
id: fourth
anchors.top: third.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: second translatable with disambiguation
text: qsTranslate("i18n-test", "Second translatable string", "second")
}
Text {
id: fifth
anchors.top: fourth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: translatable with plural forms
text: qsTranslate("i18n-test", "%n plural(s)", "", "CodecForTr", 1)
}
Text {
id: sixth
anchors.top: fifth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: second comment here, unnecessary
text: qsTranslate("i18n-test", "%n plural(s)", "", "CodecForTr", 2)
}
Text {
id: seventh
anchors.top: sixth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: qsTranslate("i18n-test", "%n plural(s)", "", "CodecForTr", 5)
}
Text {
id: eighth
anchors.top: seventh.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: qsTr("A single new string in i18n-test2")
}
Text {
id: nineth
anchors.top: eighth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: QT_TRANSLATE_NOOP("i18n-test", "First translatable string")
}
Text {
id: tenth
anchors.top: nineth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: QT_TRANSLATE_NOOP("i18n-test", "Second translatable string",
"second")
}
}
// TRANSLATOR i18n-test
import QtQuick 1.0
Rectangle {
width: 360
height: 360
Text {
id: first
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: "Hello World"
}
Text {
id: second
anchors.top: first.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: standard translatable
text: qsTr("First translatable string")
}
Text {
id: third
anchors.top: second.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: translatable with disambiguation
text: qsTr("Second translatable string", "first")
}
Text {
id: fourth
anchors.top: third.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: second translatable with disambiguation
text: qsTr("Second translatable string", "second")
}
Text {
id: fifth
anchors.top: fourth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: translatable with plural forms
text: qsTr("%n plural(s)", "", 1)
}
Text {
id: sixth
anchors.top: fifth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
//: second comment here, unnecessary
text: qsTr("%n plural(s)", "", 2)
}
Text {
id: seventh
anchors.top: sixth.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: qsTr("%n plural(s)", "", 5)
}
// TRANSLATOR i18n-test3
Text {
id: eight
anchors.top: seventh.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 5
text: qsTr("A single new string in i18n-test3", "", 5)
}
}
signature.asc
Description: This is a digitally signed message part
_______________________________________________ MeeGo-dev mailing list [email protected] http://lists.meego.com/listinfo/meego-dev http://wiki.meego.com/Mailing_list_guidelines
