Meego Wiki
Views

QtInternationalization

From MeeGo wiki
Revision as of 20:49, 25 August 2010 by Jketreno (Talk | contribs)
Jump to: navigation, search

This page is a draft work in progress and not complete; mainly a stream of consciousness...

Contents

Overview

MeeGo applications are are to be internationalized by the application developer. For information on how to write internationalized code, see the MeeGo Touch Framework: i18n documentation. In its simplest form, the developer should use qtTrId() to wrap all of the user visible strings. If the application uses any type of concatenation, make sure it uses the argument version of QString(). For example:

//% "Displayed contact name %1 is first name.  %2 is last name"
QString name = qtTrId("%1 %2").arg(contact.firstName()).arg(contact.lastName());

Make sure you provide a contextual comment describing the string before its usage (as is done in the above example) This facilitates the translation process. The string comment is also used when generating the "engineering English" which is displayed when no translation exist.

Engineering English

The engineering English strings are prefixed with '!!' to ensure they are visibly identifiable as having not been officially translated.

The base application projects do not provide localized translations. Language packages will be installed which provide the various language translations. Lacking a translation, the translation ID will be shown by the system if a translation is not found.

Application packages should install the engineering English translation file into the system. See the section Packaging engineering English.

The following attempts to describe the general process used by MeeGo to create localized language packs.

Supported locales

The locales which must be enabled, per http://bugs.meego.com, are: American English (en_US), British English (en_GB), French (fr), Spanish (es), German (de), Italian (it), Polish (pl), Dutch (nl), Russian (ru), Swedish (sv), Finnish (fi), Brazilian-Portuguese (pt_BR), Canadian-French (fr_CA), Portuguese (pt), Japanese (ja), Korean (ko), Chinese Simplified (zh_CN), Chinese Traditional (zh_TW)

Step-by-Step

For this example, we will create the language package project for the meego-handset-sms application.

The naming convention used is that the GIT tree and OBS package for a translation project are named based on the application GIT tree + -translations. In this case meego-handset-sms-translations.

At the end of this sample, you will have the following directories:

${BASE}/meego-handset-sms                   <---- application .git project
${BASE}/meego-handset-sms-translations      <---- translation .git project for application
${BASE}/obs/meego-handset-sms-translations  <---- OBS project for translation package

The following exports are used throughout these script snippets; you can export them once to your shell and then paste the other script components. If you later come back to run an individual step, make sure you set these variables back up.

export BASE=~                               # Root directory for the various projects
export APP_PACKAGE=meego-handset-sms        # Name of the application project
export APP_BINARY=sms                       # TARGET binary created by application project
export SOURCE_SUBDIR=/src                   # Subdirectory under ${APP_PACKAGE} which contains the package source files
export PACKAGE=${APP_PACKAGE}-translations
export LANGUAGES="en en_US en_GB fr es de it pl nl ru sv fi pt_BR fr_CA pt ja ko zh_CN zh_TW"

BOLD items are the ones you need to change for your project.

Checkout the application .git project

The first step is to obtain the application project that we'll be creating the translation project for.

cd ${BASE}
git clone git://gitorious.org/meego-handset-ux/${APP_PACKAGE}

Look in the meego-handset-sms directory and you will notice that all of the sources are in the src/ directory. Look at the project files for meego-handset-sms -- notice that while the project is called meego-handset-sms, the binary it installs is called sms.

You can typically tell the binary name by looking for the TARGET= line in the source's .pro file.

Knowing the location of the source is important when we define the SOURCES variable in the translations.pro file, which is used to derive the translation files from the sources. Knowing the binary installed is important when we define the APP_BINARY value.

The name of the binary is important as it is used by Qt to find the translation file. The translation file used can be overridden by passing a 3rd parameter to MApplication(). The compiled translation files (.qm) are installed using the binary name as their filename base.

Create the initial translations .git project

The following snippet will create a blank translations .git repository for you:

cd ${BASE}
[ ! -d ${PACKAGE} ] && mkdir ${PACKAGE}
cd ${PACKAGE}
cat << EOF >> translations.pro
LANGUAGES = ${LANGUAGES}
CATALOGNAME = ${APP_BINARY}
SOURCEDIR = \$\$PWD/../${APP_PACKAGE}${SOURCE_SUBDIR}
TRANSLATIONDIR = \$\$PWD
include(\$\$[QT_INSTALL_DATA]/mkspecs/features/meegotouch_defines.prf)
include(\$\$[QT_INSTALL_DATA]/mkspecs/features/meegotouch_translations.prf)
EOF
git init
git add *
git commit -s -a -m "Initial translation package commit for ${APP_PACKAGE}"
qmake
make updatets
git add *.ts Makefile
git commit -s -a -m "Initial .ts files generated from ${APP_PACKAGE}"

NOTE: Do not check in the '.qm' files. Those are generated during package build time and should not be managed in GIT.

What is the license for the translation package?

Translation files (.ts) are derived from the source package. The original author of the source package therefore holds a copyright interest in the derived translation package. In order to comply with the license terms of the source application package, typically the translation package must use the same license as the base source package.

Once you know the license which applies to the translation package, place a copy of that license in the file LICENSE and add it to the git tree:

git add LICENSE
git commit -s -a -m "Added LICENSE terms"

Changing the set of supported locales

To add additional translations, you would add the translation name to LANGUAGES in translations.pro:

export LANGUAGES="en fi cz dk he"
cd ${BASE}/${PACKAGE}
sed -i -e "s,^LANGUAGES[ /t]*=.*$,LANGUAGES = ${LANGUAGES},g" translations.pro
qmake
make updatets
git add *ts
git commit -s -a -m "Updated languages to support '${LANGUAGES}' based on ${APP_PACKAGE} commit-id '${REVISION}'"

Updating the .ts files to match latest source package

cd ${BASE}/${PACKAGE}
export REVISION=$(git --git-dir=../${APP_PACKAGE}/.git log --pretty=format:"%h" HEAD^..HEAD)
make ${APP_BINARY}.ts
make updatets
git commit -s -a -m "Updated .ts files to package ${APP_PACKAGE} commit-id '${REVISION}'"

NOTE: You only need to run make updatets periodically when new application releases are made. It should not be run when translations are being updated. Translators should never need to run the make updatets script.

Packaging the translations

Language packs should be provided as one RPM per locale. Typically, multiple packages would be built from a single OBS package.

Creating the tar ball

The first step of packaging is to create a tar file. In the following example, we set the version to 0.0.1. That version string should be updated to match the version of ${APP_PACKAGE} that is in OBS (the VERSION string is used for required dependency checking during package installation)

export VERSION=0.0.1

To create the tar file in ${BASE}/obs/${PACKAGE}/:

cd ${BASE}
[ ! -d ${BASE}/obs/${PACKAGE} ] && mkdir -p ${BASE}/obs/${PACKAGE}
tar cvjf ${BASE}/obs/${PACKAGE}/${PACKAGE}-${VERSION}.tar.bz2 ${PACKAGE} --exclude=.git

That above tar file would contain:

Makefile
sms-en.ts
sms-fi.ts
sms-de.ts
translations.pro

Creating the OBS project

The contents of the meego-handset-sms-translations OBS project for this example needs to consist of:

meego-handset-sms-translations-0.0.1.tar.bz2
meego-handset-sms-translations.yaml
meego-handset-sms-translations.spec

To create the .yaml file you can use the following script. This assumes the directory .tar.bz2 file was created and exists in ${BASE}/obs/${PACKAGE}:

cd ${BASE}/obs/${PACKAGE}
cat << EOF > ${PACKAGE}.yaml
Name: ${PACKAGE}
Summary: Translation files for ${APP_PACKAGE}
Version: ${VERSION}
Release: 1
Group:  System/GUI/Other
License: Apache   
URL: http://gitorious.org/meego-handset-ux/${PACKAGE}
Sources:
     - "%{name}-%{version}.tar.bz2"
Description: Translation files for ${APP_PACKAGE}
Requires: 
     - ${APP_PACKAGE} >= %{version}

PkgConfigBR:
    - QtCore >= 4.6.0
Configure: none
Builder: qmake
NoFiles: yes
EOF
for locale in $(tar xf ${PACKAGE}-${VERSION}.tar.bz2 ${PACKAGE}/translations.pro -O | sed -ne 's,^LANGUAGES[ \t]*=[ \t]*\(.*\),\1,p'); do
cat << EOF >> ${PACKAGE}.yaml
SubPackages:
     - Name: ${locale}
       Summary: ${locale} translation file for ${APP_PACKAGE}
       Group: Base/System
       Description: ${locale} translation file for ${APP_PACKAGE}
       Files:
          - "%lang(${locale}) %{_datadir}/l10n/meegotouch/%{name}-${locale}.qm"
     

EOF
done

See the sample .yaml file at the end of this page for an example of what the above script generates (the sample has additional comments that the above script does not add)

Once you have the .yaml file, you can create the .spec file via spectacle.

spectacle ${PACKAGE}.yaml

Updating the OBS package

Create a new translations package tar ball named meego-handset-sms-translations-${VERSION}.tar.bz2

${VERSION} value for the tar ball must correspond to the 'Version:' string in the yaml file:

sed -i -e 's,^Version:[ \t]*\(.*\)$,${VERSION},p' meego-handset-translations.yaml

Sample yaml file

#
# Use application package name + "-translations"
Name: meego-handset-sms-translations
Summary: Translation files for meego-handset-sms
#
# Keep version # in sync with the application package
Version: 0.0.1
Release: 1
Group: System/GUI/Other
#
# Use application package license; .ts files are derived works from application application
License: Apache   
# Use GIT url for translations project on gitorious
URL: http://gitorious.org/meego-handset/meego-handset-sms-translations
Sources:
    - "%{name}-%{version}.tar.bz2"
Description: Translation files for meego-handset-sms
# Require the application package - tie these 
Requires: 
    - meego-handset-sms >= %{version}

PkgConfigBR:
    - QtCore >= 4.6.0
Configure: none
Builder: qmake
NoFiles: yes
SubPackages:
    - Name: en
      Summary: en translation for meego-handset-sms
      Group: System/GUI/Other
      Description: en translation for meego-handset-sms
      Files:
        - "%lang(en) %{_datadir}/l10n/meegotouch/sms-en.qm"
      

    - Name: fi
      Summary: fi translation for meego-handset-sms
      Group: System/GUI/Other
      Description: fi translation for meego-handset-sms
      Files:
        - "%lang(fi) %{_datadir}/l10n/meegotouch/sms-fi.qm"
      

    - Name: de
      Summary: de translation for meego-handset-sms
      Group: System/GUI/Other
      Description: de translation for meego-handset-sms
      Files:
        - "%lang(de) %{_datadir}/l10n/meegotouch/sms-de.qm"

Packaging engineering English

cd ${BASE}/${APP_PACKAGE}
[ ! -e translations ] && mkdir translations
cd translations
cat << EOF >> translations.pro
LANGUAGES =  # We only create engineering English in the application package
CATALOGNAME = ${APP_BINARY}
SOURCEDIR = ../${SOURCE_SUBDIR}
TRANSLATIONDIR = \$\$PWD
include(\$\$[QT_INSTALL_DATA]/mkspecs/features/meegotouch_defines.prf)
include(\$\$[QT_INSTALL_DATA]/mkspecs/features/meegotouch_translations.prf)
EOF
qmake
make ${APP_BINARY}.ts
git add translations.pro
git commit -s -a -m "Engineering English translation project generated"

Now you need to add translations to the SUBDIRS in the top level project file (sms.pro in this example):

sed -i -e 's,\(SUBDIRS = .*\),\1 translations,g' *.pro

You don't need to commit the .ts file to GIT. It will be extracted from the source code each time the build is run. This ensures the engineering English always provides all of the non-translated strings. Official English translation should be installed via the ${APP_PACKAGE}-translations-en package.

After you have done the above you can cut a new release, build, install, and test. All of the displayed strings should now be prefixed with "!!" until a translation package is provided.

Personal tools