Localization: Re-implement localization as a class, GrampsLocale
GrampsLocale is effectively a singleton: An instance is created in const.py and retrieved everywhere. Translations are provided via Translations classes, which are derived from GNUTranslations and NullTranslations to provide extra functions like sgettext. svn: r21143
This commit is contained in:
parent
eecf57a0f6
commit
d3c2a8a490
@ -42,8 +42,6 @@ import uuid
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from .ggettext import sgettext as _
|
||||
from .svn_revision import get_svn_revision
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -94,6 +92,12 @@ APP_GRAMPS_PKG = "application/x-gramps-package"
|
||||
APP_GENEWEB = "application/x-geneweb"
|
||||
APP_VCARD = ["text/x-vcard", "text/x-vcalendar"]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# system paths
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
LOCALE_DIR = "@LOCALE_DIR@"
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Platforms
|
||||
@ -213,6 +217,15 @@ LOGO = os.path.join(IMAGE_DIR, "logo.png")
|
||||
SPLASH = os.path.join(IMAGE_DIR, "splash.jpg")
|
||||
|
||||
LICENSE_FILE = os.path.join(DOC_DIR, 'COPYING')
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Init Localization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from .utils.grampslocale import GrampsLocale
|
||||
GRAMPS_LOCALE = GrampsLocale()
|
||||
from .ggettext import sgettext as _
|
||||
>>>>>>> GrampsLocale: Replace use of the GNU Gettext API with the Gettext Class API
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -326,6 +339,7 @@ SHORTOPTS = "O:C:i:e:f:a:p:d:c:lLhuv?s"
|
||||
|
||||
GRAMPS_UUID = uuid.UUID('516cd010-5a41-470f-99f8-eb22f1098ad6')
|
||||
|
||||
<<<<<<< HEAD
|
||||
def need_to_update_const():
|
||||
""" Check to see if this file is older than
|
||||
setup.py or const.py.in """
|
||||
@ -353,4 +367,9 @@ if need_to_update_const():
|
||||
print("Outdated gramps.gen.const; please run 'python setup.py build'")
|
||||
|
||||
GRAMPS_LOCALE = 0
|
||||
from .utils.grampslocale import GrampsLocale
|
||||
GRAMPS_LOCALE = GrampsLocale()
|
||||
|
||||
|
||||
=======
|
||||
>>>>>>> GrampsLocale: Replace use of the GNU Gettext API with the Gettext Class API
|
||||
|
@ -30,65 +30,17 @@ This module ("Gramps Gettext") is an extension to the Python gettext module.
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gettext as pgettext
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] < 3:
|
||||
cuni = unicode
|
||||
else:
|
||||
cuni = str
|
||||
|
||||
def gettext(msgid):
|
||||
"""
|
||||
Obtain translation of gettext, return a unicode object
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:returns: Translation or the original.
|
||||
:rtype: unicode
|
||||
"""
|
||||
# If msgid =="" then gettext will return po file header
|
||||
# and that's not what we want.
|
||||
if len(msgid.strip()) == 0:
|
||||
return msgid
|
||||
return cuni(pgettext.gettext(msgid))
|
||||
|
||||
def ngettext(singular, plural, n):
|
||||
"""
|
||||
The translation of singular/plural is returned unless the translation is
|
||||
not available and the singular contains the separator. In that case,
|
||||
the returned value is the singular.
|
||||
|
||||
:param singular: The singular form of the string to be translated.
|
||||
may contain a context seperator
|
||||
:type singular: unicode
|
||||
:param plural: The plural form of the string to be translated.
|
||||
:type plural: unicode
|
||||
:param n: the amount for which to decide the translation
|
||||
:type n: int
|
||||
:returns: Translation or the original.
|
||||
:rtype: unicode
|
||||
"""
|
||||
return cuni(pgettext.ngettext(singular, plural, n))
|
||||
|
||||
def sgettext(msgid, sep='|'):
|
||||
"""
|
||||
Strip the context used for resolving translation ambiguities.
|
||||
|
||||
The translation of msgid is returned unless the translation is
|
||||
not available and the msgid contains the separator. In that case,
|
||||
the returned value is the portion of msgid following the last
|
||||
separator. Default separator is '|'.
|
||||
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:param sep: The separator marking the context.
|
||||
:type sep: unicode
|
||||
:returns: Translation or the original with context stripped.
|
||||
:rtype: unicode
|
||||
|
||||
"""
|
||||
msgval = pgettext.gettext(msgid)
|
||||
if msgval == msgid:
|
||||
sep_idx = msgid.rfind(sep)
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return cuni(msgval)
|
||||
from gramps.gen.const import GRAMPS_LOCALE as _gl
|
||||
_tl = _gl.get_translation()
|
||||
gettext = _tl.gettext
|
||||
# When in the 'C' locale, get_translation returns a NULLTranslation
|
||||
# which doesn't provide sgettext. This traps that case and uses
|
||||
# gettext instead -- which is fine, because there's no translation
|
||||
# file involved and it's just going to return the msgid anyeay.
|
||||
sgettext = None
|
||||
try:
|
||||
_tl.__getattr__(sgettext)
|
||||
sgettext = _tl.sgettext
|
||||
except AttributeError:
|
||||
sgettext = _tl.gettext
|
||||
ngettext = _tl.ngettext
|
||||
|
@ -42,9 +42,8 @@ import traceback
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ..const import VERSION as GRAMPSVERSION, VERSION_TUPLE
|
||||
from ..const import VERSION as GRAMPSVERSION, VERSION_TUPLE, GRAMPS_LOCALE as glocale
|
||||
from ..const import IMAGE_DIR
|
||||
from ..utils.grampslocale import get_addon_translator
|
||||
from ..ggettext import gettext as _
|
||||
from ..constfunc import STRTYPE
|
||||
|
||||
@ -836,8 +835,9 @@ class PluginData(object):
|
||||
def _set_gramplet_title(self, gramplet_title):
|
||||
if not self._ptype == GRAMPLET:
|
||||
raise ValueError('gramplet_title may only be set for GRAMPLET plugins')
|
||||
if not isinstance(gramplet_title, str):
|
||||
raise ValueError('Plugin must have a string as gramplet_title')
|
||||
if not (sys.version_info[0] < 3 and isinstance(gramplet_title, unicode)
|
||||
or isinstance(gramplet_title, str)):
|
||||
raise ValueError('gramplet_title is type %s, string or unicode required' % type(gramplet_title))
|
||||
self._gramplet_title = gramplet_title
|
||||
|
||||
def _get_gramplet_title(self):
|
||||
@ -1091,7 +1091,7 @@ class PluginRegister(object):
|
||||
full_filename = os.path.join(dir, filename)
|
||||
if sys.version_info[0] < 3:
|
||||
full_filename = full_filename.encode(sys.getfilesystemencoding())
|
||||
local_gettext = get_addon_translator(full_filename).gettext
|
||||
local_gettext = glocale.get_addon_translator(full_filename).gettext
|
||||
try:
|
||||
#execfile(full_filename,
|
||||
exec(compile(open(full_filename).read(), full_filename, 'exec'),
|
||||
|
@ -170,7 +170,7 @@ def get_unicode_path_from_env_var(path):
|
||||
"""
|
||||
# make only unicode of path of type 'str'
|
||||
if not (isinstance(path, str)):
|
||||
return path
|
||||
raise TypeError("path %s isn't a str" % str(path))
|
||||
|
||||
if win():
|
||||
# In Windows path/filename returned from a environment variable is in filesystemencoding
|
||||
|
@ -37,109 +37,45 @@ import logging
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ..const import ROOT_DIR
|
||||
from ..constfunc import mac, UNITYPE
|
||||
from ..const import LOCALE_DIR
|
||||
from ..constfunc import mac, win, UNITYPE
|
||||
|
||||
class GrampsLocale(locale):
|
||||
"""
|
||||
Encapsulate a locale
|
||||
"""
|
||||
def __init__(self):
|
||||
def _get_prefix(self):
|
||||
"""
|
||||
Find the root path for share/locale
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
if sys.prefix == os.path.dirname(os.getcwd()):
|
||||
return sys.prefix
|
||||
else:
|
||||
return os.path.join(os.path.dirname(__file__), os.pardir)
|
||||
elif sys.platform == "darwin" and sys.prefix != sys.exec_prefix:
|
||||
return sys.prefix
|
||||
else:
|
||||
return os.path.join(os.path.dirname(__file__), os.pardir)
|
||||
|
||||
def _init_gettext(self):
|
||||
"""
|
||||
Set up the gettext domain
|
||||
"""
|
||||
#the order in which bindtextdomain on gettext and on locale is called
|
||||
#appears important, so we refrain from doing first all gettext.
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#setup_gettext()
|
||||
gettext.bindtextdomain(self.localedomain, self.localedir)
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL,'')
|
||||
except:
|
||||
logging.warning(_("WARNING: Setting locale failed. Please fix"
|
||||
" the LC_* and/or the LANG environment "
|
||||
"variables to prevent this error"))
|
||||
try:
|
||||
# It is probably not necessary to set the locale to 'C'
|
||||
# because the locale will just stay at whatever it was,
|
||||
# which at startup is "C".
|
||||
# however this is done here just to make sure that the locale
|
||||
# functions are working
|
||||
locale.setlocale(locale.LC_ALL,'C')
|
||||
except:
|
||||
logging.warning(_("ERROR: Setting the 'C' locale didn't "
|
||||
"work either"))
|
||||
# FIXME: This should propagate the exception,
|
||||
# if that doesn't break Gramps under Windows
|
||||
raise
|
||||
|
||||
gettext.textdomain(slef.localedomain)
|
||||
if sys.version_info[0] < 3:
|
||||
gettext.install(self.localedomain, localedir=None, unicode=1) #None is sys default locale
|
||||
else:
|
||||
gettext.install(self.localedomain, localedir=None) #None is sys default locale
|
||||
|
||||
if hasattr(os, "uname"):
|
||||
operating_system = os.uname()[0]
|
||||
else:
|
||||
operating_system = sys.platform
|
||||
|
||||
if win(): # Windows
|
||||
setup_windows_gettext()
|
||||
elif operating_system == 'FreeBSD':
|
||||
try:
|
||||
gettext.bindtextdomain(self.localedomain, self.localedir)
|
||||
except locale.Error:
|
||||
logging.warning('No translation in some Gtk.Builder strings, ')
|
||||
elif operating_system == 'OpenBSD':
|
||||
pass
|
||||
else: # normal case
|
||||
try:
|
||||
locale.bindtextdomain(self.localedomain, self.localedir)
|
||||
#locale.textdomain(self.localedomain)
|
||||
except locale.Error:
|
||||
logging.warning('No translation in some Gtk.Builder strings, ')
|
||||
|
||||
prefixdir = self._get_prefix()
|
||||
if "GRAMPSI18N" in os.environ:
|
||||
if os.path.exists(os.environ["GRAMPSI18N"]):
|
||||
self.localedir = os.environ["GRAMPSI18N"]
|
||||
else:
|
||||
self.localedir = None
|
||||
elif os.path.exists( os.path.join(ROOT_DIR, "lang") ):
|
||||
self.localedir = os.path.join(ROOT_DIR, "lang")
|
||||
elif os.path.exists(os.path.join(prefixdir, "share/locale")):
|
||||
self.localedir = os.path.join(prefixdir, "share/locale")
|
||||
else:
|
||||
self.lang = os.environ.get('LANG', 'en')
|
||||
if self.lang and self.lang[:2] == 'en':
|
||||
pass # No need to display warning, we're in English
|
||||
else:
|
||||
logging.warning('Locale dir does not exist at ' +
|
||||
os.path.join(prefixdir, "share/locale"))
|
||||
logging.warning('Running python setup.py install --prefix=YourPrefixDir might fix the problem')
|
||||
# GrampsLocale Class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class GrampsLocale(object):
|
||||
"""
|
||||
Encapsulate a locale
|
||||
"""
|
||||
def __init__(self):
|
||||
self.localedir = None
|
||||
self.lang = None
|
||||
self.language = []
|
||||
if ("GRAMPSI18N" in os.environ
|
||||
and os.path.exists(os.environ["GRAMPSI18N"])):
|
||||
self.localedir = os.environ["GRAMPSI18N"]
|
||||
elif os.path.exists(LOCALE_DIR):
|
||||
self.localedir = LOCALE_DIR
|
||||
elif os.path.exists(os.path.join(sys.prefix, "share", "locale")):
|
||||
self.localedir = os.path.join(sys.prefix, "share", "locale")
|
||||
else:
|
||||
lang = os.environ.get('LANG', 'en')
|
||||
if lang and lang[:2] == 'en':
|
||||
pass # No need to display warning, we're in English
|
||||
else:
|
||||
logging.warning('Locale dir does not exist at %s', LOCALE_DIR)
|
||||
logging.warning('Running python setup.py install --prefix=YourPrefixDir might fix the problem')
|
||||
|
||||
if not self.localedir:
|
||||
#No localization files, no point in continuing
|
||||
return
|
||||
self.localedomain = 'gramps'
|
||||
|
||||
if mac():
|
||||
from . import maclocale
|
||||
maclocale.mac_setup_localization(self.localedir, self.localedomain)
|
||||
(self.lang, self.language) = maclocale.mac_setup_localization(self)
|
||||
else:
|
||||
self.lang = ' '
|
||||
try:
|
||||
@ -151,25 +87,142 @@ Encapsulate a locale
|
||||
self.lang = locale.getdefaultlocale()[0] + '.UTF-8'
|
||||
except TypeError:
|
||||
logging.warning('Unable to determine your Locale, using English')
|
||||
self.lang = 'en.UTF-8'
|
||||
self.lang = 'C.UTF-8'
|
||||
|
||||
os.environ["LANG"] = self.lang
|
||||
os.environ["LANGUAGE"] = self.lang
|
||||
self._init_gettext()
|
||||
if "LANGUAGE" in os.environ:
|
||||
language = [l for l in os.environ["LANGUAGE"].split(":")
|
||||
if l in self.get_available_translations()]
|
||||
self.language = language
|
||||
else:
|
||||
self.language = [self.lang[0:2]]
|
||||
|
||||
#GtkBuilder depends on reading Glade files as UTF-8 and crashes if it
|
||||
#doesn't, so set $LANG to have a UTF-8 locale. NB: This does *not*
|
||||
#affect locale.getpreferredencoding() or sys.getfilesystemencoding()
|
||||
#which are set by python long before we get here.
|
||||
check_lang = self.lang.split('.')
|
||||
if len(check_lang) < 2 or check_lang[1] not in ["utf-8", "UTF-8"]:
|
||||
self.lang = '.'.join((check_lang[0], 'UTF-8'))
|
||||
os.environ["LANG"] = self.lang
|
||||
# Set Gramps's translations
|
||||
self.translation = self._get_translation(self.localedomain, self.localedir, self.language)
|
||||
# Now set the locale for everything besides translations.
|
||||
|
||||
try:
|
||||
# First try the environment to preserve individual variables
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
try:
|
||||
#Then set LC_MESSAGES to self.lang
|
||||
locale.setlocale(locale.LC_MESSAGES, self.lang)
|
||||
except locale.Error:
|
||||
logging.warning("Unable to set translations to %s, locale not found.", self.lang)
|
||||
except locale.Error:
|
||||
# That's not a valid locale -- on Linux, probably not installed.
|
||||
try:
|
||||
# First fallback is self.lang
|
||||
locale.setlocale(locale.LC_ALL, self.lang)
|
||||
logging.warning("Setting locale to individual LC_ variables failed, falling back to %s.", self.lang)
|
||||
|
||||
except locale.Error:
|
||||
# No good, set the default encoding to C.UTF-8. Don't
|
||||
# mess with anything else.
|
||||
locale.setlocale(locale.LC_ALL, 'C.UTF-8')
|
||||
logging.error("Failed to set locale %s, falling back to English", self.lang)
|
||||
# $LANGUAGE is what sets the Gtk+ translations
|
||||
os.environ["LANGUAGE"] = ':'.join(self.language)
|
||||
# GtkBuilder uses GLib's g_dgettext wrapper, which oddly is bound
|
||||
# with locale instead of gettext.
|
||||
locale.bindtextdomain(self.localedomain, self.localedir)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Public Functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
|
||||
def get_localedomain(self):
|
||||
"""
|
||||
Get the LOCALEDOMAIN used for the Gramps application.
|
||||
Required by gui/glade.py to pass to Gtk.Builder
|
||||
"""
|
||||
return self.localedomain
|
||||
|
||||
def get_addon_translator(self, filename=None, domain="addon",
|
||||
def _get_translation(self, domain = None,
|
||||
localedir = None,
|
||||
languages=None):
|
||||
"""
|
||||
Get a translation of one of our classes. Doesn't return the
|
||||
singleton so that it can be used by get_addon_translation()
|
||||
"""
|
||||
if not domain:
|
||||
domain = self.localedomain
|
||||
if not languages:
|
||||
languages = self.language
|
||||
if not localedir:
|
||||
localedir = self.localedir
|
||||
|
||||
if gettext.find(domain, localedir, languages):
|
||||
return gettext.translation(domain, localedir,
|
||||
languages,
|
||||
class_ = GrampsTranslations)
|
||||
else:
|
||||
logging.debug("Unable to find translations for %s and %s in %s"
|
||||
, domain, languages, localedir)
|
||||
return GrampsNullTranslations()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Public Functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def get_localedomain(self):
|
||||
"""
|
||||
Get the LOCALEDOMAIN used for the Gramps application.
|
||||
Required by gui/glade.py to pass to Gtk.Builder
|
||||
"""
|
||||
return self.localedomain
|
||||
|
||||
def get_language_list(self):
|
||||
"""
|
||||
Return the list of configured languages. Used by
|
||||
ViewManager.check_for_updates to select the language for the
|
||||
addons descriptions.
|
||||
"""
|
||||
return self.language
|
||||
|
||||
def get_translation(self, domain = None, languages = None):
|
||||
"""
|
||||
Get a translation object for a particular language.
|
||||
See the gettext documentation for the available functions
|
||||
>>> glocale = GrampsLocale()
|
||||
>>> _ = glocale.get_translation('foo', 'French')
|
||||
>>> _ = tr.gettext
|
||||
"""
|
||||
|
||||
if ((domain and not domain == self.localedomain)
|
||||
or (languages and not languages == self.language)):
|
||||
if not domain:
|
||||
domain = self.localedomain
|
||||
if not languages:
|
||||
languages = self.language
|
||||
fallback = False
|
||||
if "en" in languages:
|
||||
fallback = True
|
||||
try:
|
||||
# Don't use _get_translation because we want to fall
|
||||
# back on the singleton rather than a NullTranslation
|
||||
return gettext.translation(domain, self.localedir,
|
||||
languages,
|
||||
class_ = GrampsTranslations,
|
||||
fallback = fallback)
|
||||
except IOError:
|
||||
logging.warning("None of the requested languages (%s) were available, using %s instead", ', '.join(languages), self.lang)
|
||||
return self.translation
|
||||
else:
|
||||
return self.translation
|
||||
|
||||
def get_addon_translator(self, filename, domain="addon",
|
||||
languages=None):
|
||||
"""
|
||||
Get a translator for an addon.
|
||||
@ -181,43 +234,32 @@ Encapsulate a locale
|
||||
returns - a gettext.translation object
|
||||
|
||||
Example:
|
||||
_ = get_addon_translator(languages=["fr_BE.utf8"]).gettext
|
||||
|
||||
The return object has the following properties and methods:
|
||||
.gettext
|
||||
.info
|
||||
.lgettext
|
||||
.lngettext
|
||||
.ngettext
|
||||
.output_charset
|
||||
.plural
|
||||
.set_output_charset
|
||||
.ugettext
|
||||
.ungettext
|
||||
_ = glocale.get_addon_translator(languages=["fr_BE.utf8"]).gettext
|
||||
|
||||
See the python gettext documentation.
|
||||
Assumes path/filename
|
||||
path/locale/LANG/LC_MESSAGES/addon.mo.
|
||||
"""
|
||||
if filename is None:
|
||||
filename = sys._getframe(1).f_code.co_filename
|
||||
gramps_translator = gettext.translation(LOCALEDOMAIN, LOCALEDIR,
|
||||
fallback=True)
|
||||
path = os.path.dirname(os.path.abspath(filename))
|
||||
path = self.localedir
|
||||
# If get the path of the calling module's uncompiled file. This seems a remarkably bad idea.
|
||||
# if filename is None:
|
||||
# filename = sys._getframe(1).f_code.co_filename
|
||||
|
||||
gramps_translator = self._get_translation()
|
||||
|
||||
path = os.path.dirname(os.path.abspath(filename))
|
||||
# Check if path is of type str. Do import and conversion if so.
|
||||
# The import cannot be done at the top as that will conflict with the translation system.
|
||||
|
||||
if not isinstance(path, UNITYPE) == str:
|
||||
from .file import get_unicode_path_from_env_var
|
||||
path = get_unicode_path_from_env_var(path)
|
||||
if languages:
|
||||
addon_translator = gettext.translation(domain,
|
||||
os.path.join(path, "locale"),
|
||||
languages=languages,
|
||||
fallback=True)
|
||||
else:
|
||||
addon_translator = gettext.translation(domain,
|
||||
os.path.join(path, "locale"),
|
||||
fallback=True)
|
||||
path = get_unicode_path_from_env_var(path)
|
||||
if languages:
|
||||
addon_translator = self._get_translation(domain,
|
||||
path,
|
||||
languages=languages)
|
||||
else:
|
||||
addon_translator = self._get_translation(domain, path)
|
||||
gramps_translator.add_fallback(addon_translator)
|
||||
return gramps_translator # with a language fallback
|
||||
|
||||
@ -231,12 +273,13 @@ Encapsulate a locale
|
||||
"""
|
||||
languages = ["en"]
|
||||
|
||||
if slef.localedir is None:
|
||||
if self.localedir is None:
|
||||
return languages
|
||||
|
||||
for langdir in os.listdir(self.localedir):
|
||||
mofilename = os.path.join(self.localedir, langdir,
|
||||
"LC_MESSAGES", "%s.mo" % self.localedomain )
|
||||
mofilename = os.path.join(self.localedir, langdir,
|
||||
"LC_MESSAGES",
|
||||
"%s.mo" % self.localedomain )
|
||||
if os.path.exists(mofilename):
|
||||
languages.append(langdir)
|
||||
|
||||
@ -249,7 +292,7 @@ Encapsulate a locale
|
||||
Translates objclass_str into "... %s", where objclass_str
|
||||
is 'Person', 'person', 'Family', 'family', etc.
|
||||
"""
|
||||
from ..ggettext import gettext as _
|
||||
_ = self.translation.gettext
|
||||
objclass = objclass_str.lower()
|
||||
if objclass == "person":
|
||||
return _("the person")
|
||||
@ -271,3 +314,184 @@ Encapsulate a locale
|
||||
return _("the filter")
|
||||
else:
|
||||
return _("See details")
|
||||
|
||||
def getfilesystemencoding(self):
|
||||
"""
|
||||
If the locale isn't configured correctly, this will return
|
||||
'ascii' or 'ANSI_X3.4-1968' or some other unfortunate
|
||||
result. Current unix systems all encode filenames in utf-8,
|
||||
and Microsoft Windows uses utf-16 (which they call mbcs). Make
|
||||
sure we return the right value.
|
||||
"""
|
||||
encoding = sys.getfilesystemencoding()
|
||||
|
||||
if encoding in ("utf-8", "UTF-8", "utf8", "UTF8", "mbcs", "MBCS"):
|
||||
return encoding
|
||||
|
||||
return "utf-8"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GrampsTranslation Class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class GrampsTranslations(gettext.GNUTranslations):
|
||||
"""
|
||||
Overrides and extends gettext.GNUTranslations. See the Python gettext
|
||||
"Class API" documentation for how to use this.
|
||||
"""
|
||||
def language(self):
|
||||
"""
|
||||
Return the target languge of this translations object.
|
||||
"""
|
||||
return self.info()["language"]
|
||||
|
||||
def gettext(self, msgid):
|
||||
"""
|
||||
Obtain translation of gettext, return a unicode object
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:returns: Translation or the original.
|
||||
:rtype: unicode
|
||||
"""
|
||||
# If msgid =="" then gettext will return po file header
|
||||
# and that's not what we want.
|
||||
if len(msgid.strip()) == 0:
|
||||
return msgid
|
||||
if sys.version_info[0] < 3:
|
||||
return gettext.GNUTranslations.ugettext(self, msgid)
|
||||
else:
|
||||
return gettext.GNUTranslations.gettext(self, msgid)
|
||||
|
||||
def ngettext(self, singular, plural, num):
|
||||
"""
|
||||
The translation of singular/plural is returned unless the translation is
|
||||
not available and the singular contains the separator. In that case,
|
||||
the returned value is the singular.
|
||||
|
||||
:param singular: The singular form of the string to be translated.
|
||||
may contain a context seperator
|
||||
:type singular: unicode
|
||||
:param plural: The plural form of the string to be translated.
|
||||
:type plural: unicode
|
||||
:param num: the amount for which to decide the translation
|
||||
:type num: int
|
||||
:returns: Translation or the original.
|
||||
:rtype: unicode
|
||||
"""
|
||||
if sys.version_info[0] < 3:
|
||||
return gettext.GNUTranslations.ungettext(self, singular,
|
||||
plural, num)
|
||||
else:
|
||||
return gettext.GNUTranslations.ngettext(self, singular,
|
||||
plural, num)
|
||||
|
||||
def sgettext(self, msgid, sep='|'):
|
||||
"""
|
||||
Even with a null translator we need to filter out the translator hint.
|
||||
"""
|
||||
msgval = self.gettext(msgid)
|
||||
if msgval == msgid:
|
||||
sep_idx = msgid.rfind(sep)
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return msgval
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Translations Classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class GrampsTranslations(gettext.GNUTranslations):
|
||||
"""
|
||||
Overrides and extends gettext.GNUTranslations. See the Python gettext
|
||||
"Class API" documentation for how to use this.
|
||||
"""
|
||||
def language(self):
|
||||
"""
|
||||
Return the target languge of this translations object.
|
||||
"""
|
||||
return self.info()["language"]
|
||||
|
||||
def gettext(self, msgid):
|
||||
"""
|
||||
Obtain translation of gettext, return a unicode object
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:returns: Translation or the original.
|
||||
:rtype: unicode
|
||||
"""
|
||||
# If msgid =="" then gettext will return po file header
|
||||
# and that's not what we want.
|
||||
if len(msgid.strip()) == 0:
|
||||
return msgid
|
||||
if sys.version_info[0] < 3:
|
||||
return gettext.GNUTranslations.ugettext(self, msgid)
|
||||
else:
|
||||
return gettext.GNUTranslations.gettext(self, msgid)
|
||||
|
||||
def ngettext(self, singular, plural, num):
|
||||
"""
|
||||
The translation of singular/plural is returned unless the translation is
|
||||
not available and the singular contains the separator. In that case,
|
||||
the returned value is the singular.
|
||||
|
||||
:param singular: The singular form of the string to be translated.
|
||||
may contain a context seperator
|
||||
:type singular: unicode
|
||||
:param plural: The plural form of the string to be translated.
|
||||
:type plural: unicode
|
||||
:param num: the amount for which to decide the translation
|
||||
:type num: int
|
||||
:returns: Translation or the original.
|
||||
:rtype: unicode
|
||||
"""
|
||||
if sys.version_info[0] < 3:
|
||||
return gettext.GNUTranslations.ungettext(self, singular,
|
||||
plural, num)
|
||||
else:
|
||||
return gettext.GNUTranslations.ngettext(self, singular,
|
||||
plural, num)
|
||||
|
||||
def sgettext(self, msgid, sep='|'):
|
||||
"""
|
||||
Strip the context used for resolving translation ambiguities.
|
||||
|
||||
The translation of msgid is returned unless the translation is
|
||||
not available and the msgid contains the separator. In that case,
|
||||
the returned value is the portion of msgid following the last
|
||||
separator. Default separator is '|'.
|
||||
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:param sep: The separator marking the context.
|
||||
:type sep: unicode
|
||||
:returns: Translation or the original with context stripped.
|
||||
:rtype: unicode
|
||||
"""
|
||||
msgval = self.gettext(msgid)
|
||||
if msgval == msgid:
|
||||
sep_idx = msgid.rfind(sep)
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return msgval
|
||||
|
||||
|
||||
class GrampsNullTranslations(gettext.NullTranslations):
|
||||
"""
|
||||
Extends gettext.NullTranslations to provide the sgettext method.
|
||||
|
||||
Note that it's necessary for msgid to be unicode. If it's not,
|
||||
neither will be the returned string.
|
||||
"""
|
||||
def sgettext(self, msgid):
|
||||
msgval = self.gettext(msgid)
|
||||
if msgval == msgid:
|
||||
sep_idx = msgid.rfind(sep)
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return msgval
|
||||
|
||||
def language(self):
|
||||
"""
|
||||
The null translation returns the raw msgids, which are in English
|
||||
"""
|
||||
return "en"
|
||||
|
@ -50,8 +50,8 @@ Keyword translation interface
|
||||
# 'n' : nickname = nick name
|
||||
# 'g' : familynick = family nick name
|
||||
|
||||
import gettext
|
||||
_ = gettext.gettext
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.get_translation().gettext
|
||||
|
||||
KEYWORDS = [("title", "t", _("Person|Title"), _("Person|TITLE")),
|
||||
("given", "f", _("Given"), _("GIVEN")),
|
||||
|
@ -73,36 +73,23 @@ locale, leaving $LANGUAGE unset (which is the same as setting it to
|
||||
|
||||
import sys, os, subprocess
|
||||
|
||||
def get_available_translations(dir, domain):
|
||||
def mac_setup_localization(glocale):
|
||||
"""
|
||||
Get a list of available translations.
|
||||
|
||||
:returns: A list of translation languages.
|
||||
:rtype: unicode[]
|
||||
|
||||
Set up the localization parameters from OSX's "defaults" system,
|
||||
permitting environment variables to override the settings.
|
||||
"""
|
||||
languages = ["en"]
|
||||
|
||||
if dir is None:
|
||||
return languages
|
||||
|
||||
for langdir in os.listdir(dir):
|
||||
mofilename = os.path.join( dir, langdir,
|
||||
"LC_MESSAGES", "%s.mo" % domain )
|
||||
if os.path.exists(mofilename):
|
||||
languages.append(langdir)
|
||||
|
||||
languages.sort()
|
||||
|
||||
return languages
|
||||
|
||||
def mac_setup_localization(dir, domain):
|
||||
defaults = "/usr/bin/defaults"
|
||||
find = "/usr/bin/find"
|
||||
locale_dir = "/usr/share/locale"
|
||||
available = get_available_translations(dir, domain)
|
||||
if glocale:
|
||||
available = glocale.get_available_translations()
|
||||
else:
|
||||
available = ['en']
|
||||
|
||||
def mac_language_list():
|
||||
"""
|
||||
Extract the languages list from defaults.
|
||||
"""
|
||||
languages = []
|
||||
try:
|
||||
languages = subprocess.Popen(
|
||||
@ -140,6 +127,9 @@ def mac_setup_localization(dir, domain):
|
||||
return usable
|
||||
|
||||
def mac_get_locale():
|
||||
"""
|
||||
Get the locale and specifiers from defaults.
|
||||
"""
|
||||
locale = ""
|
||||
calendar = ""
|
||||
currency = ""
|
||||
@ -177,6 +167,9 @@ def mac_setup_localization(dir, domain):
|
||||
return (locale, calendar, currency)
|
||||
|
||||
def mac_get_collation():
|
||||
"""
|
||||
Extract the collation (sort order) locale from the defaults string.
|
||||
"""
|
||||
collation = ""
|
||||
try:
|
||||
collation = subprocess.Popen(
|
||||
@ -196,11 +189,13 @@ def mac_setup_localization(dir, domain):
|
||||
|
||||
return collation
|
||||
|
||||
# Locale.setlocale() will throw if any LC_* environment variable isn't
|
||||
# a fully qualified one present in
|
||||
# /usr/share/locale. mac_resolve_locale ensures that a locale meets
|
||||
# that requirement.
|
||||
def mac_resolve_locale(loc):
|
||||
"""
|
||||
Locale.setlocale() will throw if any LC_* environment variable
|
||||
isn't a fully qualified one present in
|
||||
/usr/share/locale. mac_resolve_locale ensures that a locale
|
||||
meets that requirement.
|
||||
"""
|
||||
if len(loc) < 2:
|
||||
return None
|
||||
if len(loc) >= 5 and os.path.exists(os.path.join(locale_dir, loc[:5])):
|
||||
@ -214,11 +209,10 @@ def mac_setup_localization(dir, domain):
|
||||
else:
|
||||
# OK, no, look through the translation list, but that's not likely
|
||||
# to be 5 letters long either
|
||||
for l in translations:
|
||||
if (l.startswith(loc) and len(l) >= 5
|
||||
and os.path.exists(os.path.join(locale_dir, l[:5]))):
|
||||
return l[:5]
|
||||
break
|
||||
for _la in translations:
|
||||
if (_la.startswith(loc) and len(_la) >= 5
|
||||
and os.path.exists(os.path.join(locale_dir, _la[:5]))):
|
||||
return _la[:5]
|
||||
|
||||
else:
|
||||
# so as a last resort, pick the first one for that language.
|
||||
@ -237,20 +231,22 @@ def mac_setup_localization(dir, domain):
|
||||
collation = mac_get_collation()
|
||||
translations = mac_language_list()
|
||||
|
||||
if "LANGUAGE" not in os.environ:
|
||||
if len(translations) > 0:
|
||||
if "MULTI_TRANSLATION" in os.environ:
|
||||
os.environ["LANGUAGE"] = ":".join(translations)
|
||||
else:
|
||||
os.environ["LANGUAGE"] = translations[0]
|
||||
elif (len(loc) > 0 and loc in available
|
||||
and not locale.starts_with("en")):
|
||||
os.environ["LANGUAGE"] = locale
|
||||
elif (len(collation) > 0 and collation in available
|
||||
and not collation.starts_with("en")):
|
||||
os.environ["LANGUAGE"] = collation
|
||||
if currency and "LC_MONETARY" not in os.environ:
|
||||
os.environ["LC_MONETARY"] = currency
|
||||
|
||||
if "LANG" not in os.environ:
|
||||
if calendar and "LC_TIME" not in os.environ:
|
||||
os.environ["LC_TIME"] = calendar
|
||||
|
||||
if currency and "LC_MONETARY" not in os.environ:
|
||||
os.environ["LC_MONETARY"] = currency
|
||||
|
||||
|
||||
if calendar and "LC_TIME" not in os.environ:
|
||||
os.environ["LC_TIME"] = calendar
|
||||
|
||||
if "LANG" in os.environ:
|
||||
lang = os.environ["LANG"]
|
||||
else:
|
||||
lang = "en_US"
|
||||
loc = mac_resolve_locale(loc)
|
||||
if loc != None:
|
||||
@ -261,6 +257,20 @@ def mac_setup_localization(dir, domain):
|
||||
|
||||
elif len(collation) > 0:
|
||||
lang = mac_resolve_locale(collation)
|
||||
if lang != None:
|
||||
os.environ["LANG"] = lang
|
||||
os.environ["LC_CTYPE"] = lang + ".UTF-8"
|
||||
|
||||
if "LANGUAGE" in os.environ:
|
||||
language = [l for l in os.environ["LANGUAGE"].split(":")
|
||||
if l in available]
|
||||
elif "LANG" in os.environ:
|
||||
language = [lang[0:2]]
|
||||
else:
|
||||
if len(translations) > 0:
|
||||
language = translations
|
||||
elif (len(loc) > 0 and loc in available
|
||||
and not loc.startswith("en")):
|
||||
language = [loc]
|
||||
elif (len(collation) > 0 and collation in available
|
||||
and not collation.startswith("en")):
|
||||
language = [collation]
|
||||
|
||||
return (lang, language)
|
||||
|
@ -39,8 +39,7 @@ if sys.version_info[0] < 3:
|
||||
##
|
||||
import os
|
||||
import signal
|
||||
import gettext
|
||||
_ = gettext.gettext
|
||||
|
||||
import locale
|
||||
import logging
|
||||
|
||||
@ -53,8 +52,9 @@ from subprocess import Popen, PIPE
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from .gen.const import APP_GRAMPS, USER_DIRLIST, HOME_DIR, VERSION_TUPLE, GRAMPS_LOCALE
|
||||
from .gen.const import APP_GRAMPS, USER_DIRLIST, HOME_DIR, VERSION_TUPLE
|
||||
from .gen.constfunc import win
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Setup logging
|
||||
@ -113,14 +113,15 @@ def exc_hook(type, value, tb):
|
||||
sys.excepthook = exc_hook
|
||||
|
||||
from .gen.mime import mime_type_is_defined
|
||||
from .gen.utils.grampslocale import GrampsLocale
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Load internationalization setup
|
||||
# Instantiate Localization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
const.GRAMPS_LOCALE = GrampsLocale()
|
||||
from .gen.const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.get_translation().gettext
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -50,14 +50,13 @@ from gi.repository import GdkPixbuf
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import IMAGE_DIR, URL_MANUAL_PAGE
|
||||
from gramps.gen.const import IMAGE_DIR, URL_MANUAL_PAGE, GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.lib import NoteType
|
||||
from gramps.gen.datehandler import get_date
|
||||
from .display import display_help
|
||||
from .managedwindow import ManagedWindow
|
||||
from gramps.gen.ggettext import sgettext as _
|
||||
from gramps.gen.utils.grampslocale import trans_objclass
|
||||
from gramps.gen.constfunc import mac
|
||||
from .glade import Glade
|
||||
from .ddtargets import DdTargets
|
||||
@ -1470,13 +1469,13 @@ class MultiTreeView(Gtk.TreeView):
|
||||
objclass, handle = None, None
|
||||
if objclass in ['Person', 'Event', 'Media', 'Source',
|
||||
'Repository', 'Family', 'Note', 'Place']:
|
||||
menu_item = Gtk.MenuItem(label=_("the object|See %s details") % trans_objclass(objclass))
|
||||
menu_item = Gtk.MenuItem(label=_("the object|See %s details") % glocale.trans_objclass(objclass))
|
||||
menu_item.connect("activate",
|
||||
lambda widget: self.edit_obj(objclass, handle))
|
||||
popup.append(menu_item)
|
||||
menu_item.show()
|
||||
# ---------------------------
|
||||
menu_item = Gtk.MenuItem(label=_("the object|Make %s active") % trans_objclass(objclass))
|
||||
menu_item = Gtk.MenuItem(label=_("the object|Make %s active") % glocale.trans_objclass(objclass))
|
||||
menu_item.connect("activate",
|
||||
lambda widget: self.uistate.set_active(handle, objclass))
|
||||
popup.append(menu_item)
|
||||
@ -1492,7 +1491,7 @@ class MultiTreeView(Gtk.TreeView):
|
||||
obj = self.dbstate.db.get_table_metadata(objclass)["handle_func"](my_handle)
|
||||
if obj:
|
||||
gids.add(obj.gramps_id)
|
||||
menu_item = Gtk.MenuItem(label=_("the object|Create Filter from %s selected...") % trans_objclass(objclass))
|
||||
menu_item = Gtk.MenuItem(label=_("the object|Create Filter from %s selected...") % glocale.trans_objclass(objclass))
|
||||
menu_item.connect("activate",
|
||||
lambda widget: make_filter(self.dbstate, self.uistate,
|
||||
objclass, gids, title=self.title))
|
||||
|
@ -48,8 +48,7 @@ from gi.repository import Gtk
|
||||
# gramps modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.const import GLADE_DIR
|
||||
from gramps.gen.utils.grampslocale import LOCALEDOMAIN
|
||||
from gramps.gen.const import GLADE_DIR, GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.constfunc import STRTYPE
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -82,7 +81,7 @@ class Glade(Gtk.Builder):
|
||||
:returns: reference to the newly-created Glade instance
|
||||
"""
|
||||
GObject.GObject.__init__(self)
|
||||
self.set_translation_domain(LOCALEDOMAIN)
|
||||
self.set_translation_domain(glocale.get_localedomain())
|
||||
|
||||
filename_given = filename is not None
|
||||
dirname_given = dirname is not None
|
||||
|
@ -52,9 +52,9 @@ from gi.repository import Gtk
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.ggettext import sgettext as _
|
||||
from gramps.gen.simple import SimpleTable
|
||||
from gramps.gen.utils.grampslocale import trans_objclass
|
||||
from gramps.gen.errors import WindowActiveError
|
||||
from ...widgets.multitreeview import MultiTreeView
|
||||
from ...ddtargets import DdTargets
|
||||
@ -127,7 +127,7 @@ class QuickTable(SimpleTable):
|
||||
if (index is not None and self._link[index]):
|
||||
# See details (edit, etc):
|
||||
objclass, handle = self._link[index]
|
||||
menu_item = Gtk.MenuItem(label=_("the object|See %s details") % trans_objclass(objclass))
|
||||
menu_item = Gtk.MenuItem(label=_("the object|See %s details") % glocale.trans_objclass(objclass))
|
||||
menu_item.connect("activate",
|
||||
lambda widget: self.on_table_doubleclick(treeview))
|
||||
popup.append(menu_item)
|
||||
@ -137,7 +137,7 @@ class QuickTable(SimpleTable):
|
||||
(index is not None and self._link[index])):
|
||||
objclass, handle = self._link[index]
|
||||
if objclass == 'Person':
|
||||
menu_item = Gtk.MenuItem(label=_("the object|Make %s active") % trans_objclass('Person'))
|
||||
menu_item = Gtk.MenuItem(label=_("the object|Make %s active") % glocale.trans_objclass('Person'))
|
||||
menu_item.connect("activate",
|
||||
lambda widget: self.on_table_click(treeview))
|
||||
popup.append(menu_item)
|
||||
|
@ -8,7 +8,7 @@
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
@ -29,15 +29,15 @@ Translator class for use by plugins.
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gettext
|
||||
_ = gettext.gettext
|
||||
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.ggettext import gettext as _
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.utils.grampslocale import get_localedomain
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.datehandler import displayer, LANG_TO_DISPLAY
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.lib.grampstype import GrampsType
|
||||
@ -97,15 +97,15 @@ _COUNTRY_MAP = {
|
||||
#------------------------------------------------------------------------
|
||||
def get_language_string(lang_code):
|
||||
"""
|
||||
Given a language code of the form "lang_region", return a text string
|
||||
Given a language code of the form "lang_region", return a text string
|
||||
representing that language.
|
||||
"""
|
||||
code_parts = lang_code.rsplit("_")
|
||||
|
||||
|
||||
lang = code_parts[0]
|
||||
if lang in _LANG_MAP:
|
||||
lang = _LANG_MAP[lang]
|
||||
|
||||
|
||||
if len(code_parts) > 1:
|
||||
country = code_parts[1]
|
||||
if country in _COUNTRY_MAP:
|
||||
@ -114,7 +114,7 @@ def get_language_string(lang_code):
|
||||
{ 'language' : lang, 'country' : country }
|
||||
else:
|
||||
retstr = lang
|
||||
|
||||
|
||||
return retstr
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -122,62 +122,57 @@ def get_language_string(lang_code):
|
||||
# Translator
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Translator:
|
||||
class Translator(object):
|
||||
"""
|
||||
This class provides translated strings for the configured language.
|
||||
"""
|
||||
DEFAULT_TRANSLATION_STR = "default"
|
||||
|
||||
|
||||
def __init__(self, lang=DEFAULT_TRANSLATION_STR):
|
||||
"""
|
||||
:param lang: The language to translate to.
|
||||
:param lang: The language to translate to.
|
||||
The language can be:
|
||||
* The name of any installed .mo file
|
||||
* "en" to use the message strings in the code
|
||||
* "default" to use the default translation being used by gettext.
|
||||
:type lang: string
|
||||
:return: nothing
|
||||
|
||||
|
||||
"""
|
||||
if lang == Translator.DEFAULT_TRANSLATION_STR:
|
||||
self.__trans = None
|
||||
self.__trans = glocale.get_translation()
|
||||
self.__dd = displayer
|
||||
else:
|
||||
# fallback=True will cause the translator to use English if
|
||||
# lang = "en" or if something goes wrong.
|
||||
self.__trans = gettext.translation(get_localedomain(),
|
||||
languages=[lang],
|
||||
fallback=True)
|
||||
# If lang isn't supported, this will fallback to the
|
||||
# current global language
|
||||
self.__trans = glocale.get_translation(languages=[lang])
|
||||
val = config.get('preferences.date-format')
|
||||
if lang in LANG_TO_DISPLAY:
|
||||
self.__dd = LANG_TO_DISPLAY[lang](val)
|
||||
else:
|
||||
self.__dd = displayer
|
||||
|
||||
|
||||
def gettext(self, message):
|
||||
"""
|
||||
Return the unicode translated string.
|
||||
|
||||
|
||||
:param message: The message to be translated.
|
||||
:type message: string
|
||||
:returns: The translated message
|
||||
:rtype: unicode
|
||||
|
||||
|
||||
"""
|
||||
if self.__trans is None:
|
||||
return cuni(gettext.gettext(message))
|
||||
else:
|
||||
return self.__trans.ugettext(message)
|
||||
|
||||
return self.__trans.gettext(message)
|
||||
|
||||
def ngettext(self, singular, plural, n):
|
||||
"""
|
||||
Return the unicode translated singular/plural string.
|
||||
|
||||
|
||||
The translation of singular/plural is returned unless the translation is
|
||||
not available and the singular contains the separator. In that case,
|
||||
the returned value is the portion of singular following the last
|
||||
separator. Default separator is '|'.
|
||||
|
||||
|
||||
:param singular: The singular form of the string to be translated.
|
||||
may contain a context separator
|
||||
:type singular: unicode
|
||||
@ -187,53 +182,49 @@ class Translator:
|
||||
:type n: int
|
||||
:returns: The translated singular/plural message
|
||||
:rtype: unicode
|
||||
|
||||
|
||||
"""
|
||||
if self.__trans is None:
|
||||
return cuni(gettext.ngettext(singular, plural, n))
|
||||
else:
|
||||
return self.__trans.ungettext(singular, plural, n)
|
||||
|
||||
return self.__trans.ngettext(singular, plural, n)
|
||||
|
||||
def sgettext(self, msgid, sep='|'):
|
||||
"""
|
||||
Strip the context used for resolving translation ambiguities.
|
||||
|
||||
|
||||
The translation of msgid is returned unless the translation is
|
||||
not available and the msgid contains the separator. In that case,
|
||||
the returned value is the portion of msgid following the last
|
||||
separator. Default separator is '|'.
|
||||
|
||||
|
||||
:param msgid: The string to translated.
|
||||
:type msgid: unicode
|
||||
:param sep: The separator marking the context.
|
||||
:type sep: unicode
|
||||
:returns: Translation or the original with context stripped.
|
||||
:rtype: unicode
|
||||
|
||||
|
||||
"""
|
||||
msgval = self.gettext(msgid)
|
||||
if msgval == msgid:
|
||||
sep_idx = msgid.rfind(sep)
|
||||
msgval = msgid[sep_idx+1:]
|
||||
return cuni(msgval)
|
||||
|
||||
try:
|
||||
return self.__trans.sgettext(msgid)
|
||||
except AttributeError:
|
||||
return self.__trans.gettext(msgid)
|
||||
|
||||
def get_date(self, date):
|
||||
"""
|
||||
Return a string representing the date appropriate for the language being
|
||||
translated.
|
||||
|
||||
|
||||
:param date: The date to be represented.
|
||||
:type date: :class:`~gen.lib.date.Date`
|
||||
:returns: The date as text in the proper language.
|
||||
:rtype: unicode
|
||||
"""
|
||||
return self.__dd.display(date)
|
||||
|
||||
|
||||
def get_type(self, name):
|
||||
"""
|
||||
Return a string representing the name appropriate for the language being
|
||||
translated.
|
||||
|
||||
|
||||
:param name: The name type to be represented.
|
||||
:returns: The name as text in the proper language.
|
||||
:rtype: unicode
|
||||
|
@ -39,6 +39,7 @@ from gramps.gen.ggettext import gettext as _
|
||||
# gramps modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.display.name import displayer as global_name_display
|
||||
from gramps.gen.errors import ReportError
|
||||
from gramps.gen.lib import ChildRefType
|
||||
@ -50,7 +51,6 @@ from gramps.gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle,
|
||||
from gramps.gen.plug.report import Report
|
||||
from gramps.gen.plug.report import utils as ReportUtils
|
||||
from gramps.gen.plug.report import MenuReportOptions
|
||||
from gramps.gen.utils.grampslocale import get_available_translations
|
||||
from gramps.plugins.lib.libnarrate import Narrator
|
||||
from gramps.plugins.lib.libtranslate import Translator, get_language_string
|
||||
|
||||
@ -299,7 +299,7 @@ class AncestorOptions(MenuReportOptions):
|
||||
trans = EnumeratedListOption(_("Translation"),
|
||||
Translator.DEFAULT_TRANSLATION_STR)
|
||||
trans.add_item(Translator.DEFAULT_TRANSLATION_STR, _("Default"))
|
||||
for language in get_available_translations():
|
||||
for language in glocale.get_available_translations():
|
||||
trans.add_item(language, get_language_string(language))
|
||||
trans.set_help(_("The translation to be used for the report."))
|
||||
menu.add_option(category_name, "trans", trans)
|
||||
|
@ -42,6 +42,7 @@ from gramps.gen.ggettext import gettext as _
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.display.name import displayer as global_name_display
|
||||
from gramps.gen.errors import ReportError
|
||||
from gramps.gen.lib import EventType, FamilyRelType, Person, NoteType
|
||||
@ -54,7 +55,6 @@ from gramps.gen.plug.report import endnotes
|
||||
from gramps.gen.plug.report import utils as ReportUtils
|
||||
from gramps.gen.plug.report import MenuReportOptions
|
||||
from gramps.plugins.lib.libnarrate import Narrator
|
||||
from gramps.gen.utils.grampslocale import get_available_translations
|
||||
from gramps.plugins.lib.libtranslate import Translator, get_language_string
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -753,7 +753,7 @@ class DetAncestorOptions(MenuReportOptions):
|
||||
trans = EnumeratedListOption(_("Translation"),
|
||||
Translator.DEFAULT_TRANSLATION_STR)
|
||||
trans.add_item(Translator.DEFAULT_TRANSLATION_STR, _("Default"))
|
||||
for language in get_available_translations():
|
||||
for language in glocale.get_available_translations():
|
||||
trans.add_item(language, get_language_string(language))
|
||||
trans.set_help(_("The translation to be used for the report."))
|
||||
addopt("trans", trans)
|
||||
|
@ -45,6 +45,7 @@ from functools import partial
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
from gramps.gen.display.name import displayer as global_name_display
|
||||
from gramps.gen.errors import ReportError
|
||||
from gramps.gen.lib import FamilyRelType, Person, NoteType
|
||||
@ -58,7 +59,6 @@ from gramps.gen.plug.report import endnotes
|
||||
from gramps.gen.plug.report import utils as ReportUtils
|
||||
from gramps.gen.plug.report import MenuReportOptions
|
||||
from gramps.plugins.lib.libnarrate import Narrator
|
||||
from gramps.gen.utils.grampslocale import get_available_translations
|
||||
from gramps.plugins.lib.libtranslate import Translator, get_language_string
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -928,7 +928,7 @@ class DetDescendantOptions(MenuReportOptions):
|
||||
trans = EnumeratedListOption(_("Translation"),
|
||||
Translator.DEFAULT_TRANSLATION_STR)
|
||||
trans.add_item(Translator.DEFAULT_TRANSLATION_STR, _("Default"))
|
||||
for language in get_available_translations():
|
||||
for language in glocale.get_available_translations():
|
||||
trans.add_item(language, get_language_string(language))
|
||||
trans.set_help(_("The translation to be used for the report."))
|
||||
add_option("trans", trans)
|
||||
|
Loading…
Reference in New Issue
Block a user