.. _dolc-i18n:

######################
  Internationalization
######################

The Camelot translation system is a very small wrapper around the Qt translation
system.  Internally, it uses the :meth:`QCoreApplication.translate` method to
do the actual translation.

On top of that, it adds the possibility for end users to change translations
theirselves.  Those translations are stored in the database.  This mechanism
can be used to adapt the vocabulary of an application to that of a specific 
company.

How to Specify Translation Strings
==================================

Translation strings specify “This text should be translated.”. It’s your responsibility 
to mark translatable strings; the system can only translate strings it knows about.

.. literalinclude:: ../../../../test/snippet/i18n/specify_translation_string.py

The above example translates the given string immediately.  This is not always desired,
since the message catalog might not yet be loaded at the time of execution.  Therefore
translation strings can be specified as lazy.  They will only get translated when they
are used in the GUI.

.. literalinclude:: ../../../../test/snippet/i18n/specify_lazy_translation_string.py

Translation strings in model definitions should always be specified as lazy translation
strings.  Only lazy translation strings can be translated by the end user in various
forms.

Translating Camelot itself
==========================

To extract translation files from the Camelot source code, 
`Babel <http://babel.edgewall.org/>`_ needs to be installed.

In the root folder of the Camelot source directory.

First update the translation template::

    python setup.py extract_messages
    
If your language directory does not yet exists in 'camelot/art/translations'::

    python setup.py init_catalog --locale nl
    
If it allready exists, update it from the translation template::

    python setup.py update_catalog
    
In the language subdirectory of 'camelot/art/translations', there is a 
subdirectory 'LC_MESSAGES' which contains the .po translation file. 
This translation file can then be translated with linguist ::

   linguist camelot.po
  
And edit it :  
  
  .. image:: ../_static/camelot_qt_linguist.png
  
Make sure to save them back as GNU gettext .po files.
  
Then the .po file should be converted to a .qm file to make it loadable
at run time::

    lrelease camelot.po
    
Don't forget to post your new .po file on the mailing list, so it can
be included in the next release.

For more background information, please have a look at the 
`Babel Documentation <http://babel.edgewall.org/wiki/Documentation/setup.html>`_
  
Where to put Translations
=========================

Translations can be put in 2 places :

  * in po files which have to be loaded at application startup
  
  * in the Translation table : this table is editable by the users via the Configuration
    menu.  This is the place to put translations that should be editable by the users.  At
    application startup, all records in this table related to the current language will be 
    put in memory.
    
Loading translations
====================

Translations are loaded when the application starts.  To enforce the loading
of the correct translation file, one should overwrite the 
:meth:`camelot.admin.application_admin.ApplicationAdmin.get_translator` method.  
This method should return the proper :obj:`QtCore.QTranslator` object.
  
End user translations
=====================

Often it is convenient to let the end user create or update the translations of an
application, this allows the end user to put a lot of domain knowledge into the application.

Therefore, all lazy translation strings can be translated by the end user.  When the user
right-clicks on a label in a form, he can select :guilabel:`Change translation` from the menu and
update the current translation (for the current language).  This effectively updates the
content of the **Translation** table.

After some time the developer can take a copy of this table and decide to put these translations
in po files.
