~bzr-pqm/bzr/bzr.dev

5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
1
# -*- coding: utf-8 -*-
2
#
3
# Copyright (C) 2007 Lukáš Lalinský <lalinsky@gmail.com>
4
# Copyright (C) 2007,2009 Alexander Belchenko <bialix@ukr.net>
5
# Copyright (C) 2011 Canonical Ltd
6
#
5875.2.11 by Vincent Ladeuil
Slightly different wrapping of the GPL header broke test_source :-/
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
5875.2.11 by Vincent Ladeuil
Slightly different wrapping of the GPL header broke test_source :-/
19
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
20
21
# This module is copied from Bazaar Explorer and modified for bzr.
22
23
"""i18n and l10n support for Bazaar."""
24
25
import gettext as _gettext
26
import os
27
import sys
28
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
29
_translations = None
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
30
31
5875.2.7 by INADA Naoki
Change order of functions.
32
def gettext(message):
33
    """Translate message. 
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
34
    
35
    :returns: translated message as unicode.
36
    """
6131.2.1 by Jonathan Riddell
install translations whenever they are used
37
    install()
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
38
    return _translations.ugettext(message)
5875.2.7 by INADA Naoki
Change order of functions.
39
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
40
5971.1.24 by Jonathan Riddell
fix translations for plural forms
41
def ngettext(singular, plural, number):
42
    """Translate message with plural forms based on `number`.
43
44
    :param singular: English language message in singular form
45
    :param plural: English language message in plural form
46
    :param number: the number this message should be translated for
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
47
48
    :returns: translated message as unicode.
49
    """
6131.2.1 by Jonathan Riddell
install translations whenever they are used
50
    install()
5971.1.77 by Jonathan Riddell
merge in trunk
51
    return _translations.ungettext(singular, plural, number)
5875.2.7 by INADA Naoki
Change order of functions.
52
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
53
5875.2.7 by INADA Naoki
Change order of functions.
54
def N_(msg):
55
    """Mark message for translation but don't translate it right away."""
56
    return msg
57
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
58
5875.2.7 by INADA Naoki
Change order of functions.
59
def gettext_per_paragraph(message):
60
    """Translate message per paragraph.
61
5875.2.9 by Vincent Ladeuil
Cleanup some PEP8 issues and move test code in test module, test_multiline still failing.
62
    :returns: concatenated translated message as unicode.
63
    """
6133.3.14 by Jonathan Riddell
install() translations for per_paragraph too
64
    install()
5875.2.7 by INADA Naoki
Change order of functions.
65
    paragraphs = message.split(u'\n\n')
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
66
    ugettext = _translations.ugettext
5875.2.7 by INADA Naoki
Change order of functions.
67
    # Be careful not to translate the empty string -- it holds the
68
    # meta data of the .po file.
69
    return u'\n\n'.join(ugettext(p) if p else u'' for p in paragraphs)
70
71
6131.2.3 by Jonathan Riddell
rename to disable_i18n() to follow convention
72
def disable_i18n():
6131.2.2 by Jonathan Riddell
add disableI18n() function so bzrlib users can chose not to use i18n
73
    """Do not allow i18n to be enabled.  Useful for third party users
74
    of bzrlib."""
6133.3.13 by Jonathan Riddell
vila sorts it out, fix disable_i18n() and use it in tests.__init__
75
    global _translations
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
76
    _translations = _gettext.NullTranslations()
6131.2.2 by Jonathan Riddell
add disableI18n() function so bzrlib users can chose not to use i18n
77
6133.3.13 by Jonathan Riddell
vila sorts it out, fix disable_i18n() and use it in tests.__init__
78
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
79
def installed():
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
80
    """Returns whether translations are in use or not."""
81
    return _translations is not None
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
82
83
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
84
def install(lang=None):
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
85
    """Enables gettext translations."""
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
86
    global _translations
6112.1.1 by Jonathan Riddell
check for installed i18n before doing install
87
    if installed():
88
        return
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
89
    if lang is None:
90
        lang = _get_current_locale()
6025.1.1 by Jelmer Vernooij
Fix i18n use when no environment variables are set.
91
    if lang is not None:
92
        languages = lang.split(':')
93
    else:
94
        languages = None
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
95
    _translations = _gettext.translation(
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
96
            'bzr',
97
            localedir=_get_locale_dir(),
6025.1.1 by Jelmer Vernooij
Fix i18n use when no environment variables are set.
98
            languages=languages,
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
99
            fallback=True)
100
5875.2.7 by INADA Naoki
Change order of functions.
101
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
102
def uninstall():
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
103
    """Disables gettext translations."""
5875.3.25 by Vincent Ladeuil
Fix test failures and make sure we don't rely on a default translation.
104
    global _translations
6133.3.10 by Jonathan Riddell
default _translations back to None so we can tell if it gets installed
105
    _translations = None
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
106
107
108
def _get_locale_dir():
109
    if hasattr(sys, 'frozen'):
110
        base = os.path.dirname(
111
                unicode(sys.executable, sys.getfilesystemencoding()))
112
        return os.path.join(base, u'locale')
113
    else:
114
        base = os.path.dirname(unicode(__file__, sys.getfilesystemencoding()))
5875.2.4 by INADA Naoki
Search '/usr/share/locale' when bzrlib/locale does not exist.
115
        dirpath = os.path.realpath(os.path.join(base, u'locale'))
116
        if os.path.exists(dirpath):
117
            return dirpath
118
        else:
119
            return '/usr/share/locale'
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
120
121
122
def _check_win32_locale():
123
    for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
124
        if os.environ.get(i):
125
            break
126
    else:
127
        lang = None
128
        import locale
129
        try:
130
            import ctypes
131
        except ImportError:
132
            # use only user's default locale
133
            lang = locale.getdefaultlocale()[0]
134
        else:
135
            # using ctypes to determine all locales
136
            lcid_user = ctypes.windll.kernel32.GetUserDefaultLCID()
137
            lcid_system = ctypes.windll.kernel32.GetSystemDefaultLCID()
138
            if lcid_user != lcid_system:
139
                lcid = [lcid_user, lcid_system]
140
            else:
141
                lcid = [lcid_user]
142
            lang = [locale.windows_locale.get(i) for i in lcid]
143
            lang = ':'.join([i for i in lang if i])
144
        # set lang code for gettext
145
        if lang:
146
            os.environ['LANGUAGE'] = lang
147
148
149
def _get_current_locale():
150
    if not os.environ.get('LANGUAGE'):
151
        from bzrlib import config
6056.2.3 by Vincent Ladeuil
Migrate language.
152
        lang = config.GlobalStack().get('language')
5875.2.1 by INADA Naoki
Add bzrlib.i18n module.
153
        if lang:
154
            os.environ['LANGUAGE'] = lang
155
            return lang
156
    if sys.platform == 'win32':
157
        _check_win32_locale()
158
    for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
159
        lang = os.environ.get(i)
160
        if lang:
161
            return lang
162
    return None