enable translated output for this report

svn: r22156
This commit is contained in:
Paul Franklin
2013-05-04 02:07:51 +00:00
parent da72bfbafb
commit da7f594765

View File

@@ -6,7 +6,7 @@
# Copyright (C) 2007-2008 Brian G. Matherly # Copyright (C) 2007-2008 Brian G. Matherly
# Copyright (C) 2008 Peter Landgren # Copyright (C) 2008 Peter Landgren
# Copyright (C) 2010 Jakim Friant # Copyright (C) 2010 Jakim Friant
# Copyright (C) 2012 Paul Franklin # Copyright (C) 2012-2013 Paul Franklin
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -27,15 +27,13 @@
"""Reports/Graphical Reports/Statistics Report""" """Reports/Graphical Reports/Statistics Report"""
from __future__ import division
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# python modules # python modules
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from __future__ import division
import time import time
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from functools import partial from functools import partial
#------------------------------------------------------------------------ #------------------------------------------------------------------------
@@ -44,20 +42,24 @@ from functools import partial
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
# Person and relation types # Person and relation types
from gramps.gen.lib import Person, FamilyRelType, EventType, EventRoleType from gramps.gen.lib import Person, FamilyRelType, EventType, EventRoleType
from gramps.gen.lib.date import Date from gramps.gen.lib.date import Date
# gender and report type names # gender and report type names
from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle, from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle,
FONT_SANS_SERIF, FONT_SERIF, FONT_SANS_SERIF, FONT_SERIF,
PARA_ALIGN_CENTER, PARA_ALIGN_LEFT, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,
IndexMark, INDEX_TYPE_TOC) IndexMark, INDEX_TYPE_TOC)
from gramps.gen.plug.menu import (BooleanOption, NumberOption, EnumeratedListOption, from gramps.gen.plug.menu import (BooleanOption, BooleanListOption,
FilterOption, PersonOption) EnumeratedListOption, NumberOption,
FilterOption, PersonOption)
from gramps.gen.plug.report import Report from gramps.gen.plug.report import Report
from gramps.gen.plug.report import utils as ReportUtils from gramps.gen.plug.report import utils as ReportUtils
from gramps.gen.plug.report import MenuReportOptions from gramps.gen.plug.report import MenuReportOptions
from gramps.gen.datehandler import displayer, parser from gramps.gen.plug.report import stdoptions
from gramps.gen.datehandler import parser
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@@ -295,17 +297,20 @@ class _options:
SORT_VALUE = 0 SORT_VALUE = 0
SORT_KEY = 1 SORT_KEY = 1
sorts = [ opt_sorts = [
(SORT_VALUE, "Item count", _("Item count")), (SORT_VALUE, "Item count", _("Item count")),
(SORT_KEY, "Item name", _("Item name")) (SORT_KEY, "Item name", _("Item name"))
] ]
genders = [ opt_genders = [
(Person.UNKNOWN, "Both", _("Both")), (Person.UNKNOWN, "Both", _("Both")),
(Person.MALE, "Men", _("Men")), (Person.MALE, "Men", _("Men")),
(Person.FEMALE, "Women", _("Women")) (Person.FEMALE, "Women", _("Women"))
] ]
def _T_(value): # enable deferred translations (see Python docs 22.1.3.4)
return value
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# Data extraction methods from the database # Data extraction methods from the database
@@ -317,43 +322,43 @@ class Extract(object):
"""Methods for extracting statistical data from the database""" """Methods for extracting statistical data from the database"""
# key, non-localized name, localized name, type method, data method # key, non-localized name, localized name, type method, data method
self.extractors = { self.extractors = {
'data_title': ("Title", _("person|Title"), 'data_title': ("Title", _T_("person|Title"),
self.get_person, self.get_title), self.get_person, self.get_title),
'data_sname': ("Surname", _("Surname"), 'data_sname': ("Surname", _T_("Surname"),
self.get_person, self.get_surname), self.get_person, self.get_surname),
'data_fname': ("Forename", _("Forename"), 'data_fname': ("Forename", _T_("Forename"),
self.get_person, self.get_forename), self.get_person, self.get_forename),
'data_gender': ("Gender", _("Gender"), 'data_gender': ("Gender", _T_("Gender"),
self.get_person, self.get_gender), self.get_person, self.get_gender),
'data_byear': ("Birth year", _("Birth year"), 'data_byear': ("Birth year", _T_("Birth year"),
self.get_birth, self.get_year), self.get_birth, self.get_year),
'data_dyear': ("Death year", _("Death year"), 'data_dyear': ("Death year", _T_("Death year"),
self.get_death, self.get_year), self.get_death, self.get_year),
'data_bmonth': ("Birth month", _("Birth month"), 'data_bmonth': ("Birth month", _T_("Birth month"),
self.get_birth, self.get_month), self.get_birth, self.get_month),
'data_dmonth': ("Death month", _("Death month"), 'data_dmonth': ("Death month", _T_("Death month"),
self.get_death, self.get_month), self.get_death, self.get_month),
'data_bplace': ("Birth place", _("Birth place"), 'data_bplace': ("Birth place", _T_("Birth place"),
self.get_birth, self.get_place), self.get_birth, self.get_place),
'data_dplace': ("Death place", _("Death place"), 'data_dplace': ("Death place", _T_("Death place"),
self.get_death, self.get_place), self.get_death, self.get_place),
'data_mplace': ("Marriage place", _("Marriage place"), 'data_mplace': ("Marriage place", _T_("Marriage place"),
self.get_marriage_handles, self.get_places), self.get_marriage_handles, self.get_places),
'data_mcount': ("Number of relationships", _("Number of relationships"), 'data_mcount': ("Number of relationships", _T_("Number of relationships"),
self.get_family_handles, self.get_handle_count), self.get_family_handles, self.get_handle_count),
'data_fchild': ("Age when first child born", _("Age when first child born"), 'data_fchild': ("Age when first child born", _T_("Age when first child born"),
self.get_child_handles, self.get_first_child_age), self.get_child_handles, self.get_first_child_age),
'data_lchild': ("Age when last child born", _("Age when last child born"), 'data_lchild': ("Age when last child born", _T_("Age when last child born"),
self.get_child_handles, self.get_last_child_age), self.get_child_handles, self.get_last_child_age),
'data_ccount': ("Number of children", _("Number of children"), 'data_ccount': ("Number of children", _T_("Number of children"),
self.get_child_handles, self.get_handle_count), self.get_child_handles, self.get_handle_count),
'data_mage': ("Age at marriage", _("Age at marriage"), 'data_mage': ("Age at marriage", _T_("Age at marriage"),
self.get_marriage_handles, self.get_event_ages), self.get_marriage_handles, self.get_event_ages),
'data_dage': ("Age at death", _("Age at death"), 'data_dage': ("Age at death", _T_("Age at death"),
self.get_person, self.get_death_age), self.get_person, self.get_death_age),
'data_age': ("Age", _("Age"), 'data_age': ("Age", _T_("Age"),
self.get_person, self.get_person_age), self.get_person, self.get_person_age),
'data_etypes': ("Event type", _("Event type"), 'data_etypes': ("Event type", _T_("Event type"),
self.get_event_handles, self.get_event_type) self.get_event_handles, self.get_event_type)
} }
@@ -367,7 +372,7 @@ class Extract(object):
if title: if title:
return [title] return [title]
else: else:
return [_("(Preferred) title missing")] return [_T_("(Preferred) title missing")]
def get_forename(self, person): def get_forename(self, person):
"return forenames for given person" "return forenames for given person"
@@ -376,7 +381,7 @@ class Extract(object):
if firstnames: if firstnames:
return firstnames.split() return firstnames.split()
else: else:
return [_("(Preferred) forename missing")] return [_T_("(Preferred) forename missing")]
def get_surname(self, person): def get_surname(self, person):
"return surnames for given person" "return surnames for given person"
@@ -385,17 +390,17 @@ class Extract(object):
if surnames: if surnames:
return surnames.split() return surnames.split()
else: else:
return [_("(Preferred) surname missing")] return [_T_("(Preferred) surname missing")]
def get_gender(self, person): def get_gender(self, person):
"return gender for given person" "return gender for given person"
# TODO: why there's no Person.getGenderName? # TODO: why there's no Person.getGenderName?
# It could be used by getDisplayInfo & this... # It could be used by getDisplayInfo & this...
if person.gender == Person.MALE: if person.gender == Person.MALE:
return [_("Men")] return [_T_("Men")]
if person.gender == Person.FEMALE: if person.gender == Person.FEMALE:
return [_("Women")] return [_T_("Women")]
return [_("Gender unknown")] return [_T_("Gender unknown")]
def get_year(self, event): def get_year(self, event):
"return year for given event" "return year for given event"
@@ -404,7 +409,7 @@ class Extract(object):
year = date.get_year() year = date.get_year()
if year: if year:
return [str(year)] return [str(year)]
return [_("Date(s) missing")] return [_T_("Date(s) missing")]
def get_month(self, event): def get_month(self, event):
"return month for given event" "return month for given event"
@@ -412,8 +417,8 @@ class Extract(object):
if date: if date:
month = date.get_month() month = date.get_month()
if month: if month:
return [displayer.long_months[month]] return [self._locale.date_displayer.long_months[month]]
return [_("Date(s) missing")] return [_T_("Date(s) missing")]
def get_place(self, event): def get_place(self, event):
"return place for given event" "return place for given event"
@@ -422,7 +427,7 @@ class Extract(object):
place = self.db.get_place_from_handle(place_handle).get_title() place = self.db.get_place_from_handle(place_handle).get_title()
if place: if place:
return [place] return [place]
return [_("Place missing")] return [_T_("Place missing")]
def get_places(self, data): def get_places(self, data):
"return places for given (person,event_handles)" "return places for given (person,event_handles)"
@@ -436,7 +441,7 @@ class Extract(object):
if place: if place:
places.append(place) places.append(place)
else: else:
places.append(_("Place missing")) places.append(_T_("Place missing"))
return places return places
def get_person_age(self, person): def get_person_age(self, person):
@@ -444,14 +449,14 @@ class Extract(object):
death_ref = person.get_death_ref() death_ref = person.get_death_ref()
if not death_ref: if not death_ref:
return [self.estimate_age(person)] return [self.estimate_age(person)]
return [_("Already dead")] return [_T_("Already dead")]
def get_death_age(self, person): def get_death_age(self, person):
"return age at death for given person, if dead" "return age at death for given person, if dead"
death_ref = person.get_death_ref() death_ref = person.get_death_ref()
if death_ref: if death_ref:
return [self.estimate_age(person, death_ref.ref)] return [self.estimate_age(person, death_ref.ref)]
return [_("Still alive")] return [_T_("Still alive")]
def get_event_ages(self, data): def get_event_ages(self, data):
"return ages at given (person,event_handles)" "return ages at given (person,event_handles)"
@@ -459,7 +464,7 @@ class Extract(object):
ages = [self.estimate_age(person, h) for h in event_handles] ages = [self.estimate_age(person, h) for h in event_handles]
if ages: if ages:
return ages return ages
return [_("Events missing")] return [_T_("Events missing")]
def get_event_type(self, data): def get_event_type(self, data):
"return event types at given (person,event_handles)" "return event types at given (person,event_handles)"
@@ -467,11 +472,11 @@ class Extract(object):
person, event_handles = data person, event_handles = data
for event_handle in event_handles: for event_handle in event_handles:
event = self.db.get_event_from_handle(event_handle) event = self.db.get_event_from_handle(event_handle)
evtType = str(event.get_type()) evtType = self._(self._get_type(event.get_type()))
types.append(evtType) types.append(evtType)
if types: if types:
return types return types
return [_("Events missing")] return [_T_("Events missing")]
def get_first_child_age(self, data): def get_first_child_age(self, data):
"return age when first child in given (person,child_handles) was born" "return age when first child in given (person,child_handles) was born"
@@ -479,7 +484,7 @@ class Extract(object):
if ages: if ages:
errors.append(ages[0]) errors.append(ages[0])
return errors return errors
return [_("Children missing")] return [_T_("Children missing")]
def get_last_child_age(self, data): def get_last_child_age(self, data):
"return age when last child in given (person,child_handles) was born" "return age when last child in given (person,child_handles) was born"
@@ -487,7 +492,7 @@ class Extract(object):
if ages: if ages:
errors.append(ages[-1]) errors.append(ages[-1])
return errors return errors
return [_("Children missing")] return [_T_("Children missing")]
def get_handle_count(self, data): def get_handle_count(self, data):
"return number of handles in given (person, handle_list) used for child count, family count" "return number of handles in given (person, handle_list) used for child count, family count"
@@ -506,7 +511,7 @@ class Extract(object):
if birth_ref: if birth_ref:
ages.append(self.estimate_age(person, birth_ref.ref)) ages.append(self.estimate_age(person, birth_ref.ref))
else: else:
errors.append(_("Birth missing")) errors.append(_T_("Birth missing"))
continue continue
ages.sort() ages.sort()
return (ages, errors) return (ages, errors)
@@ -517,7 +522,7 @@ class Extract(object):
age = estimate_age(self.db, person, end, begin) age = estimate_age(self.db, person, end, begin)
if age[0] < 0 or age[1] < 0: if age[0] < 0 or age[1] < 0:
# inadequate information # inadequate information
return _("Date(s) missing") return _T_("Date(s) missing")
if age[0] == age[1]: if age[0] == age[1]:
# exact year # exact year
return "%3d" % age[0] return "%3d" % age[0]
@@ -597,7 +602,7 @@ class Extract(object):
def get_person_data(self, person, collect): def get_person_data(self, person, collect):
"""Add data from the database to 'collect' for the given person, """Add data from the database to 'collect' for the given person,
using methods rom the 'collect' data dict tuple using methods from the 'collect' data dict tuple
""" """
for chart in collect: for chart in collect:
# get the information # get the information
@@ -607,7 +612,7 @@ class Extract(object):
if obj: if obj:
value = data_func(obj) # e.g. get_year() value = data_func(obj) # e.g. get_year()
else: else:
value = [_("Personal information missing")] value = [_T_("Personal information missing")]
# list of information found # list of information found
for key in value: for key in value:
if key in chart[1]: if key in chart[1]:
@@ -617,7 +622,7 @@ class Extract(object):
def collect_data(self, db, filter_func, menu, genders, def collect_data(self, db, filter_func, menu, genders,
year_from, year_to, no_years, cb_progress): year_from, year_to, no_years, cb_progress, rlocale):
"""goes through the database and collects the selected personal """goes through the database and collects the selected personal
data persons fitting the filter and birth year criteria. The data persons fitting the filter and birth year criteria. The
arguments are: arguments are:
@@ -629,6 +634,7 @@ class Extract(object):
year_to - use only persons who've born this year or before year_to - use only persons who've born this year or before
no_years - use also people without known birth year no_years - use also people without known birth year
cb_progress - callback to indicate progress cb_progress - callback to indicate progress
rlocale - a GrampsLocale instance
Returns an array of tuple of: Returns an array of tuple of:
- Extraction method title - Extraction method title
@@ -636,6 +642,9 @@ class Extract(object):
(- Method) (- Method)
""" """
self.db = db # store for use by methods self.db = db # store for use by methods
self._locale = rlocale
self._ = rlocale.translation.sgettext
self._get_type = rlocale.get_type
data = [] data = []
ext = self.extractors ext = self.extractors
@@ -733,12 +742,18 @@ class StatisticsChart(Report):
'year_to': year_to 'year_to': year_to
} }
lang = menu.get_option_by_name('trans').get_value()
rlocale = self.set_locale(lang)
# override default gettext, or English output will have "person|Title"
self._ = rlocale.translation.sgettext
# extract requested items from the database and count them # extract requested items from the database and count them
self._user.begin_progress(_('Statistics Charts'), self._user.begin_progress(_('Statistics Charts'),
_('Collecting data...'), 0) _('Collecting data...'), 0)
tables = _Extract.collect_data(database, self.filter, menu, tables = _Extract.collect_data(database, self.filter, menu,
gender, year_from, year_to, gender, year_from, year_to,
get_value('no_years'), self._user.step_progress) get_value('no_years'), self._user.step_progress,
rlocale)
self._user.end_progress() self._user.end_progress()
self._user.begin_progress(_('Statistics Charts'), self._user.begin_progress(_('Statistics Charts'),
@@ -750,11 +765,15 @@ class StatisticsChart(Report):
# generate sorted item lookup index index # generate sorted item lookup index index
lookup = self.index_items(table[1], sortby, reverse) lookup = self.index_items(table[1], sortby, reverse)
# document heading # document heading
mapping['chart_title'] = table[0] mapping['chart_title'] = self._(table[0])
if genders: if genders:
heading = _("%(genders)s born %(year_from)04d-%(year_to)04d: %(chart_title)s") % mapping heading = self._("%(genders)s born "
"%(year_from)04d-%(year_to)04d: "
"%(chart_title)s") % mapping
else: else:
heading = _("Persons born %(year_from)04d-%(year_to)04d: %(chart_title)s") % mapping heading = self._("Persons born "
"%(year_from)04d-%(year_to)04d: "
"%(chart_title)s") % mapping
self.data.append((heading, table[0], table[1], lookup)) self.data.append((heading, table[0], table[1], lookup))
self._user.step_progress() self._user.step_progress()
self._user.end_progress() self._user.end_progress()
@@ -781,7 +800,7 @@ class StatisticsChart(Report):
def write_report(self): def write_report(self):
"output the selected statistics..." "output the selected statistics..."
mark = IndexMark(_('Statistics Charts'), INDEX_TYPE_TOC, 1) mark = IndexMark(self._('Statistics Charts'), INDEX_TYPE_TOC, 1)
self._user.begin_progress(_('Statistics Charts'), self._user.begin_progress(_('Statistics Charts'),
_('Saving charts...'), len(self.data)) _('Saving charts...'), len(self.data))
for data in self.data: for data in self.data:
@@ -817,7 +836,7 @@ class StatisticsChart(Report):
chart_data = [] chart_data = []
for key in lookup: for key in lookup:
style = "SC-color-%d" % color style = "SC-color-%d" % color
text = "%s (%d)" % (key, data[key]) text = "%s (%d)" % (self._(key), data[key])
# graphics style, value, and it's label # graphics style, value, and it's label
chart_data.append((style, data[key], text)) chart_data.append((style, data[key], text))
color = (color+1) % 7 # There are only 7 color styles defined color = (color+1) % 7 # There are only 7 color styles defined
@@ -834,7 +853,7 @@ class StatisticsChart(Report):
legendx = 1.0 legendx = 1.0
yoffset = margin yoffset = margin
text = _("%s (persons):") % typename text = self._("%s (persons):") % self._(typename)
draw_legend(self.doc, legendx, yoffset, chart_data, text,'SC-legend') draw_legend(self.doc, legendx, yoffset, chart_data, text,'SC-legend')
@@ -869,7 +888,7 @@ class StatisticsChart(Report):
# header # header
yoffset += (row_h + pad) yoffset += (row_h + pad)
text = _("%s (persons):") % typename text = self._("%s (persons):") % self._(typename)
self.doc.draw_text('SC-text', text, textx, yoffset) self.doc.draw_text('SC-text', text, textx, yoffset)
for key in lookup: for key in lookup:
@@ -885,7 +904,7 @@ class StatisticsChart(Report):
startx = stopx - (maxsize * value / max_value) startx = stopx - (maxsize * value / max_value)
self.doc.draw_box('SC-bar',"",startx,yoffset,stopx-startx,row_h) self.doc.draw_box('SC-bar',"",startx,yoffset,stopx-startx,row_h)
# text after bar # text after bar
text = "%s (%d)" % (key, data[key]) text = "%s (%d)" % (self._(key), data[key])
self.doc.draw_text('SC-text', text, textx, yoffset) self.doc.draw_text('SC-text', text, textx, yoffset)
#print key + ":", #print key + ":",
@@ -910,12 +929,13 @@ class StatisticsChartOptions(MenuReportOptions):
""" """
################################ ################################
add_option = partial(menu.add_option, _("Report Options")) category_name = _("Report Options")
add_option = partial(menu.add_option, category_name)
################################ ################################
self.__filter = FilterOption(_("Filter"), 0) self.__filter = FilterOption(_("Filter"), 0)
self.__filter.set_help( self.__filter.set_help(
_("Determines what people are included in the report.")) _("Determines what people are included in the report."))
add_option("filter", self.__filter) add_option("filter", self.__filter)
self.__filter.connect('value-changed', self.__filter_changed) self.__filter.connect('value-changed', self.__filter_changed)
@@ -928,8 +948,8 @@ class StatisticsChartOptions(MenuReportOptions):
sortby = EnumeratedListOption(_('Sort chart items by'), sortby = EnumeratedListOption(_('Sort chart items by'),
_options.SORT_VALUE ) _options.SORT_VALUE )
for item_idx in range(len(_options.sorts)): for item_idx in range(len(_options.opt_sorts)):
item = _options.sorts[item_idx] item = _options.opt_sorts[item_idx]
sortby.add_item(item_idx,item[2]) sortby.add_item(item_idx,item[2])
sortby.set_help( _("Select how the statistical data is sorted.")) sortby.set_help( _("Select how the statistical data is sorted."))
add_option("sortby",sortby) add_option("sortby",sortby)
@@ -957,8 +977,8 @@ class StatisticsChartOptions(MenuReportOptions):
gender = EnumeratedListOption(_('Genders included'), gender = EnumeratedListOption(_('Genders included'),
Person.UNKNOWN ) Person.UNKNOWN )
for item_idx in range(len(_options.genders)): for item_idx in range(len(_options.opt_genders)):
item = _options.genders[item_idx] item = _options.opt_genders[item_idx]
gender.add_item(item[0],item[2]) gender.add_item(item[0],item[2])
gender.set_help( _("Select which genders are included into " gender.set_help( _("Select which genders are included into "
"statistics.")) "statistics."))
@@ -969,20 +989,24 @@ class StatisticsChartOptions(MenuReportOptions):
"used instead of a bar chart.")) "used instead of a bar chart."))
add_option("bar_items", bar_items) add_option("bar_items", bar_items)
stdoptions.add_localization_option(menu, category_name)
# ------------------------------------------------- # -------------------------------------------------
# List of available charts on separate option tabs # List of available charts on separate option tabs
idx = 0 idx = 0
half = (len(_Extract.extractors))/2 half = len(_Extract.extractors) // 2
self.charts = {} chart_types = []
for key in _Extract.extractors: for (chart_opt, tuple) in _Extract.extractors.items():
if idx < half: chart_types.append((_(tuple[1]), chart_opt, tuple))
sorted_chart_types = sorted(chart_types)
for (translated_option_name, opt_name, tuple) in sorted_chart_types:
if idx <= half:
category_name = _("Charts 1") category_name = _("Charts 1")
else: else:
category_name = _("Charts 2") category_name = _("Charts 2")
opt = BooleanOption(translated_option_name, False)
opt = BooleanOption(_Extract.extractors[key][1], False)
opt.set_help(_("Include charts with indicated data.")) opt.set_help(_("Include charts with indicated data."))
menu.add_option(category_name,key, opt) menu.add_option(category_name,opt_name,opt)
idx += 1 idx += 1
# Enable a couple of charts by default # Enable a couple of charts by default