Some fixes
svn: r3892
This commit is contained in:
		| @@ -1,7 +1,7 @@ | |||||||
| # | # | ||||||
| # Gramps - a GTK+/GNOME based genealogy program | # Gramps - a GTK+/GNOME based genealogy program | ||||||
| # | # | ||||||
| # Copyright (C) 2003-2004  Donald N. Allingham | # Copyright (C) 2003-2005  Donald N. Allingham | ||||||
| # | # | ||||||
| # 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 | ||||||
| @@ -31,7 +31,6 @@ Statistics Chart report | |||||||
| # python modules | # python modules | ||||||
| # | # | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
| import os |  | ||||||
| import time | import time | ||||||
| from gettext import gettext as _ | from gettext import gettext as _ | ||||||
|  |  | ||||||
| @@ -48,8 +47,8 @@ import gtk | |||||||
| # | # | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
| from Utils import pt2cm | from Utils import pt2cm | ||||||
| import const	# gender and report type names | import const    # gender and report type names | ||||||
| import RelLib	# need Person internals for getting gender / gender name | from RelLib import Person   # need Person internals for getting gender / gender name | ||||||
| import Utils | import Utils | ||||||
| import Report | import Report | ||||||
| import BaseDoc | import BaseDoc | ||||||
| @@ -74,9 +73,9 @@ _lookup_items = {} | |||||||
| def lookup_value_compare(a, b): | def lookup_value_compare(a, b): | ||||||
|     "compare given keys according to corresponding _lookup_items values" |     "compare given keys according to corresponding _lookup_items values" | ||||||
|     if _lookup_items[a] < _lookup_items[b]: |     if _lookup_items[a] < _lookup_items[b]: | ||||||
| 	return -1 |         return -1 | ||||||
|     if _lookup_items[a] == _lookup_items[b]: |     if _lookup_items[a] == _lookup_items[b]: | ||||||
| 	return 0 |         return 0 | ||||||
|     return 1 |     return 1 | ||||||
|  |  | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
| @@ -89,165 +88,183 @@ class Extract: | |||||||
|  |  | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         """Methods for extracting statistical data from the database""" |         """Methods for extracting statistical data from the database""" | ||||||
| 	self.extractors = [ |         self.extractors = [ | ||||||
| 	    (_("Titles"), self.title), |             (_("Titles"), self.title), | ||||||
| 	    (_("Forenames"), self.forename), |             (_("Forenames"), self.forename), | ||||||
| 	    (_("Birth years"), self.birth_year), |             (_("Birth years"), self.birth_year), | ||||||
| 	    (_("Death years"), self.death_year), |             (_("Death years"), self.death_year), | ||||||
| 	    (_("Birth months"), self.birth_month), |             (_("Birth months"), self.birth_month), | ||||||
| 	    (_("Death months"), self.death_month), |             (_("Death months"), self.death_month), | ||||||
| 	    (_("Estimated ages at death"), self.death_age), |             (_("Estimated ages at death"), self.death_age), | ||||||
| 	    #(_("TODO: Estimated (first) marriage ages"), self.marriage_age), |             #(_("TODO: Estimated (first) marriage ages"), self.marriage_age), | ||||||
| 	    #(_("TODO: Estimated ages for bearing the first child"), self.first_child_age), |             #(_("TODO: Estimated ages for bearing the first child"), self.first_child_age), | ||||||
| 	    #(_("TODO: Estimated Ages for bearing the last child"), self.last_child_age), |             #(_("TODO: Estimated Ages for bearing the last child"), self.last_child_age), | ||||||
| 	    #(_("TODO: Number of children"), self.child_count), |             #(_("TODO: Number of children"), self.child_count), | ||||||
| 	    #(_("TODO: Cause of death"), self.death_cause), |             #(_("TODO: Cause of death"), self.death_cause), | ||||||
| 	    (_("Genders"), self.gender) |             (_("Genders"), self.gender) | ||||||
| 	] |         ] | ||||||
|  |  | ||||||
|     def estimate_age(self, person, date): |     def estimate_age(self, db, person, date): | ||||||
| 	"""Utility method to estimate person's age at given date: |         """Utility method to estimate person's age at given date: | ||||||
| 	person -- person whose age is to be estimated |         person -- person whose age is to be estimated | ||||||
| 	date -- date at which the age should be estimated |         date -- date at which the age should be estimated | ||||||
| 	This expects that Person's birth and the date argument are |         This expects that Person's birth and the date argument are | ||||||
| 	using the same calendar and that between those two dates |         using the same calendar and that between those two dates | ||||||
| 	there haven't been any calendar discontinuations.""" |         there haven't been any calendar discontinuations.""" | ||||||
| 	birth = person.getBirth().getDateObj() |         birth_handle = person.get_birth_handle() | ||||||
| 	if not (date.getYearValid() and birth.getYearValid()): |         if birth_handle: | ||||||
| 	    return _("Missing date(s)") |             birth = db.get_event_from_handle(birth_handle).get_date_object() | ||||||
| 	age = date.getYear() - birth.getYear() |             if not (date.get_year_valid() and birth.get_year_valid()): | ||||||
| 	if date.getMonthValid() and birth.getMonthValid(): |                 return _("Missing date(s)") | ||||||
| 	    if date.getMonth() < birth.getMonth(): |         else: | ||||||
| 		age -= 1 |             return _("Missing date(s)") | ||||||
| 	    else: |  | ||||||
| 		if (date.getMonth() == birth.getMonth() and |  | ||||||
| 		date.getDayValid() and birth.getDayValid() and |  | ||||||
| 		date.getDay() < birth.getDay()): |  | ||||||
| 		    age -= 1 |  | ||||||
| 	if age >= 0: |  | ||||||
| 	    return str(age) |  | ||||||
| 	else: |  | ||||||
| 	    return _("Invalid date(s)") |  | ||||||
|  |  | ||||||
|     def title(self, person): |         age = date.get_year() - birth.get_year() | ||||||
| 	title = person.getPrimaryName().getTitle() |         if date.get_month_valid() and birth.get_month_valid(): | ||||||
| 	if title: |             if date.get_month() < birth.get_month(): | ||||||
| 	    return [title] |                 age -= 1 | ||||||
| 	else: |             elif (date.get_month() == birth.get_month() and | ||||||
| 	    return [_("Person's missing (preferred) title")] |                             date.get_day_valid() and birth.get_day_valid() and | ||||||
| 	 |                             date.get_day() < birth.get_day()): | ||||||
|     def forename(self, person): |                     age -= 1 | ||||||
| 	# because this returns list, other methods return list too |         if age >= 0: | ||||||
| 	firstnames = person.getPrimaryName().getFirstName().strip() |             return str(age) | ||||||
| 	if firstnames: |         else: | ||||||
| 	    return [name.capitalize() for name in firstnames.split()] |             return _("Invalid date(s)") | ||||||
| 	else: |  | ||||||
| 	    return [_("Person's missing (preferred) forename")] |  | ||||||
|  |  | ||||||
|     def birth_year(self, person): |     def title(self, db, person): | ||||||
| 	year = person.getBirth().getDateObj().getYear() |         title = person.get_primary_name().get_title() | ||||||
| 	if year != Date.UNDEF: |         if title: | ||||||
| 	    return [str(year)] |             return [title] | ||||||
| 	else: |         else: | ||||||
| 	    return [_("Person's missing birth year")] |             return [_("Person's missing (preferred) title")] | ||||||
|  |      | ||||||
|  |     def forename(self, db, person): | ||||||
|  |         # because this returns list, other methods return list too | ||||||
|  |         firstnames = person.get_primary_name().get_first_name().strip() | ||||||
|  |         if firstnames: | ||||||
|  |             return [name.capitalize() for name in firstnames.split()] | ||||||
|  |         else: | ||||||
|  |             return [_("Person's missing (preferred) forename")] | ||||||
|  |  | ||||||
|     def death_year(self, person): |     def birth_year(self, db, person): | ||||||
| 	year = person.getDeath().getDateObj().getYear() |         birth_handle = person.get_birth_handle() | ||||||
| 	if year != Date.UNDEF: |         if birth_handle: | ||||||
| 	    return [str(year)] |             birth = db.get_event_from_handle(birth_handle).get_date_object() | ||||||
| 	else: |             year = birth.get_year() | ||||||
| 	    return [_("Person's missing death year")] |             if year: | ||||||
|  |                 return [str(year)] | ||||||
|  |         return [_("Person's missing birth year")] | ||||||
|  |  | ||||||
|  |     def death_year(self, db, person): | ||||||
|  |         death_handle = person.get_death_handle() | ||||||
|  |         if death_handle: | ||||||
|  |             death = db.get_event_from_handle(death_handle).get_date_object() | ||||||
|  |             year = death.get_year() | ||||||
|  |             if year: | ||||||
|  |                 return [str(year)] | ||||||
|  |         return [_("Person's missing death year")] | ||||||
|          |          | ||||||
|     def birth_month(self, person): |     def birth_month(self, db, person): | ||||||
| 	month = person.getBirth().getDateObj().start |         birth_handle = person.get_birth_handle() | ||||||
| 	if month.getMonthValid(): |         if birth_handle: | ||||||
| 	    return [month.getMonthStr()] |             birth = db.get_event_from_handle(birth_handle).get_date_object() | ||||||
| 	else: |             month = birth.get_month() | ||||||
| 	    return [_("Person's missing birth month")] |             if month: | ||||||
|  |                 return ["Month text here"]#month.getMonthStr()] | ||||||
|  |         return [_("Person's missing birth month")] | ||||||
|  |  | ||||||
|     def death_month(self, person): |     def death_month(self, db, person): | ||||||
| 	month = person.getDeath().getDateObj().start |         death_handle = person.get_death_handle() | ||||||
| 	if month.getMonthValid(): |         if death_handle: | ||||||
| 	    return [month.getMonthStr()] |             death = db.get_event_from_handle(death_handle).get_date_object() | ||||||
| 	else: |             month = death.get_month() | ||||||
| 	    return [_("Person's missing death month")] |             if month: | ||||||
|  |                 return ["Month text here"]#[month.getMonthStr()] | ||||||
|  |         return [_("Person's missing death month")] | ||||||
|  |  | ||||||
|     def death_age(self, person): |     def death_age(self, db, person): | ||||||
| 	return [self.estimate_age(person, person.getDeath().getDateObj())] |         birth_handle = person.get_birth_handle() | ||||||
|  |         if birth_handle: | ||||||
|  |             birth = db.get_event_from_handle(birth_handle).get_date_object() | ||||||
|  |             return [self.estimate_age(person, person.getDeath().getDateObj())] | ||||||
|  |  | ||||||
|     def marriage_age(self, person): |     def marriage_age(self, db, person): | ||||||
| 	return "Marriage age stat unimplemented" |         return "Marriage age stat unimplemented" | ||||||
|  |  | ||||||
|     def first_child_age(self, person): |     def first_child_age(self, db, person): | ||||||
| 	return "First child bearing age stat unimplemented" |         return "First child bearing age stat unimplemented" | ||||||
|  |  | ||||||
|     def last_child_age(self, person): |     def last_child_age(self, db, person): | ||||||
| 	return "Last child bearing age stat unimplemented" |         return "Last child bearing age stat unimplemented" | ||||||
|  |  | ||||||
|     def child_count(self, person): |     def child_count(self, db, person): | ||||||
| 	return "Child count stat unimplemented" |         return "Child count stat unimplemented" | ||||||
|  |  | ||||||
|     def death_cause(self, person): |     def death_cause(self, db, person): | ||||||
| 	return "Death cause stat unimplemented" |         return "Death cause stat unimplemented" | ||||||
| 	 |      | ||||||
|     def gender(self, person): |     def gender(self, db, 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... | ||||||
| 	Person = RelLib.Person |         if person.gender == Person.male: | ||||||
| 	if person.gender == Person.male: |             gender = const.male | ||||||
| 	    gender = const.male |         elif person.gender == Person.female: | ||||||
| 	elif person.gender == Person.female: |             gender = const.female | ||||||
| 	    gender = const.female |         else: | ||||||
| 	else: |             gender = const.unknown | ||||||
| 	    gender = const.unknown |         return [gender] | ||||||
| 	return [gender] |  | ||||||
|      |      | ||||||
|     def collect_data(self, db, filter_func, extract_func, genders, |     def collect_data(self, db, filter_func, extract_func, genders, | ||||||
|                      year_from, year_to, no_years): |                      year_from, year_to, no_years): | ||||||
|         """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: | ||||||
| 	db           - the GRAMPS database |         db           - the GRAMPS database | ||||||
|         filter_func  - filtering function selected by the StatisticsDialog |         filter_func  - filtering function selected by the StatisticsDialog | ||||||
| 	extract_func - extraction method selected by the StatisticsDialog |         extract_func - extraction method selected by the StatisticsDialog | ||||||
| 	genders      - which gender(s) to include into statistics |         genders      - which gender(s) to include into statistics | ||||||
| 	year_from    - use only persons who've born this year of after |         year_from    - use only persons who've born this year of after | ||||||
| 	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 any birth year |         no_years     - use also people without any birth year | ||||||
| 	""" |         """ | ||||||
| 	Person = RelLib.Person |         items = {} | ||||||
| 	items = {} |         # go through the people and collect data | ||||||
| 	# go through the people and collect data |         for person_handle in filter_func.apply(db, db.get_person_handles(sort_handles=False)): | ||||||
| 	for person in filter_func.apply(db, db.getPersonMap().values()): |  | ||||||
|  |  | ||||||
| 	    # check whether person has suitable gender |             person = db.get_person_from_handle(person_handle) | ||||||
| 	    if person.gender != genders and genders != Person.unknown: |             # check whether person has suitable gender | ||||||
| 		continue |             if person.gender != genders and genders != Person.unknown: | ||||||
| 	     |                 continue | ||||||
| 	    # check whether birth year is within required range |          | ||||||
| 	    birth = person.getBirth().getDateObj() |             # check whether birth year is within required range | ||||||
| 	    if birth.getYearValid(): |             birth_handle = person.get_birth_handle() | ||||||
| 		year = birth.getYear() |             if birth_handle: | ||||||
| 		if not (year >= year_from and year <= year_to): |                 birth = db.get_event_from_handle(birth_handle).get_date_object() | ||||||
| 		    continue |                 if birth.get_year_valid(): | ||||||
| 	    else: |                     year = birth.get_year() | ||||||
| 		# if death before range, person's out of range too... |                     if not (year >= year_from and year <= year_to): | ||||||
| 		death = person.getDeath().getDateObj() |                         continue | ||||||
| 		if death.getYearValid() and death.getYear() < year_from: |                 else: | ||||||
| 		    continue |                     # if death before range, person's out of range too... | ||||||
| 		if not no_years: |                     death_handle = person.get_death_handle() | ||||||
| 		    # do not accept people who are not known to be in range |                     if death_handle: | ||||||
| 		    continue |                         death = db.get_event_from_handle(death_handle).get_date_object() | ||||||
|  |                         if death.get_year_valid() and death.get_year() < year_from: | ||||||
|  |                             continue | ||||||
|  |                         if not no_years: | ||||||
|  |                             # do not accept people who are not known to be in range | ||||||
|  |                             continue | ||||||
|  |  | ||||||
| 	    # get the information |             # get the information | ||||||
| 	    value = extract_func(person) |             value = extract_func(db,person) | ||||||
| 	    # list of information found |             # list of information found | ||||||
| 	    for key in value: |             for key in value: | ||||||
| 		if key in items.keys(): |                 if key in items.keys(): | ||||||
| 		    items[key] += 1 |                     items[key] += 1 | ||||||
| 		else: |                 else: | ||||||
| 		    items[key] = 1 |                     items[key] = 1 | ||||||
| 	return items |         return items | ||||||
|  |  | ||||||
| # GLOBAL: ready instance for others to use | # GLOBAL: ready instance for others to use | ||||||
| _Extract = Extract() | _Extract = Extract() | ||||||
| @@ -262,7 +279,7 @@ class StatisticsChart(Report.Report): | |||||||
|     def __init__(self, database, person, options_class): |     def __init__(self, database, person, options_class): | ||||||
|         """ |         """ | ||||||
|         Creates the Statistics object that produces the report. |         Creates the Statistics object that produces the report. | ||||||
| 	Uses the Extractor class to extract the data from the database. |         Uses the Extractor class to extract the data from the database. | ||||||
|  |  | ||||||
|         The arguments are: |         The arguments are: | ||||||
|  |  | ||||||
| @@ -270,65 +287,66 @@ class StatisticsChart(Report.Report): | |||||||
|         person          - currently selected person |         person          - currently selected person | ||||||
|         options_class   - instance of the Options class for this report |         options_class   - instance of the Options class for this report | ||||||
|  |  | ||||||
| 	To see what the options are, check the options help in the options class. |         To see what the options are, check the options help in the options class. | ||||||
|         """ |         """ | ||||||
|         Report.Report.__init__(self,database,person,options_class) |         Report.Report.__init__(self,database,person,options_class) | ||||||
| 	 |      | ||||||
|         filter_num = options_class.get_filter_number() |         filter_num = options_class.get_filter_number() | ||||||
|         filters = options_class.get_report_filters(person) |         filters = options_class.get_report_filters(person) | ||||||
|         filters.extend(GenericFilter.CustomFilters.get_filters()) |         filters.extend(GenericFilter.CustomFilters.get_filters()) | ||||||
|         filterfun = filters[filter_num] |         filterfun = filters[filter_num] | ||||||
|  |  | ||||||
| 	year_from = options_dict['year_from'] |         year_from = options_class.handler.options_dict['year_from'] | ||||||
| 	year_to = options_dict['year_to'] |         year_to = options_class.handler.options_dict['year_to'] | ||||||
| 	gender = options_dict['gender'] |         gender = options_class.handler.options_dict['gender'] | ||||||
|  |  | ||||||
| 	extract = _Extract.extractors[options_dict['extract']] |         extract = _Extract.extractors[options_class.handler.options_dict['extract']] | ||||||
| 	# extract requested items from the database and count them |         # extract requested items from the database and count them | ||||||
| 	self.items = extractor.collect_data(self.db, filterfun, extract[1], gender, |         self.items = _Extract.collect_data(database, filterfun, extract[1], | ||||||
| 		year_from, year_to, options_dict['no_years']) |                         gender, year_from, year_to,  | ||||||
| 	# generate sorted item lookup index index |                         options_class.handler.options_dict['no_years']) | ||||||
| 	self.index_items(options_dict['sort'], options_dict['reverse']) |         # generate sorted item lookup index index | ||||||
|  |         self.index_items(options_class.handler.options_dict['sort'],  | ||||||
|  |                         options_class.handler.options_dict['reverse']) | ||||||
|  |  | ||||||
| 	# title needs both data extraction method name + gender name |         # title needs both data extraction method name + gender name | ||||||
| 	Person = RelLib.Person |         if gender == Person.male: | ||||||
| 	if gender == Person.male: |             genderstr = _("men") | ||||||
| 	    genderstr = _("men") |         elif gender == Person.female: | ||||||
| 	elif gender == Person.female: |             genderstr = _("women") | ||||||
| 	    genderstr = _("women") |         else: | ||||||
| 	else: |             genderstr = None | ||||||
| 	    genderstr = None |  | ||||||
|  |  | ||||||
| 	if genderstr: |         if genderstr: | ||||||
| 	    self.title = "%s (%s): %04d-%04d" % (extract[0], genderstr, year_from, year_to) |             self.title = "%s (%s): %04d-%04d" % (extract[0], genderstr, year_from, year_to) | ||||||
| 	else: |         else: | ||||||
| 	    self.title = "%s: %04d-%04d" % (extract[0], year_from, year_to) |             self.title = "%s: %04d-%04d" % (extract[0], year_from, year_to) | ||||||
|  |  | ||||||
| 	self.setup() |         self.setup() | ||||||
|  |  | ||||||
| 	     |          | ||||||
|     def index_items(self, sort, reverse): |     def index_items(self, sort, reverse): | ||||||
| 	"""creates & stores a sorted index for the items""" |         """creates & stores a sorted index for the items""" | ||||||
| 	global _lookup_items |         global _lookup_items | ||||||
|  |  | ||||||
| 	# sort by item keys |         # sort by item keys | ||||||
| 	index = self.items.keys() |         index = self.items.keys() | ||||||
| 	index.sort() |         index.sort() | ||||||
| 	if reverse: |         if reverse: | ||||||
| 	    index.reverse() |             index.reverse() | ||||||
|  |  | ||||||
| 	if sort == _SORT_VALUE: |         if sort == _SORT_VALUE: | ||||||
| 	    # set for the sorting function |             # set for the sorting function | ||||||
| 	    _lookup_items = self.items |             _lookup_items = self.items | ||||||
| 	     |          | ||||||
| 	    # then sort by value |             # then sort by value | ||||||
| 	    index.sort(lookup_value_compare) |             index.sort(lookup_value_compare) | ||||||
| 	    if reverse: |             if reverse: | ||||||
| 		index.reverse() |                 index.reverse() | ||||||
|  |  | ||||||
| 	self.index = index |         self.index = index | ||||||
|  |  | ||||||
| 	 |      | ||||||
|     def setup(self): |     def setup(self): | ||||||
|         """ |         """ | ||||||
|         Define the graphics styles used by the report. Paragraph definitions |         Define the graphics styles used by the report. Paragraph definitions | ||||||
| @@ -340,7 +358,7 @@ class StatisticsChart(Report.Report): | |||||||
|         SC-title - Contains the SC-Title paragraph style used for |         SC-title - Contains the SC-Title paragraph style used for | ||||||
|                 the title of the document |                 the title of the document | ||||||
|         """ |         """ | ||||||
| 	g = BaseDoc.GraphicsStyle() |         g = BaseDoc.GraphicsStyle() | ||||||
|         g.set_line_width(0.8) |         g.set_line_width(0.8) | ||||||
|         g.set_color((0,0,0)) |         g.set_color((0,0,0)) | ||||||
|         g.set_fill_color((255,0,0)) |         g.set_fill_color((255,0,0)) | ||||||
| @@ -361,62 +379,62 @@ class StatisticsChart(Report.Report): | |||||||
|         g.set_width(self.doc.get_usable_width()) |         g.set_width(self.doc.get_usable_width()) | ||||||
|         self.doc.add_draw_style("SC-title",g) |         self.doc.add_draw_style("SC-title",g) | ||||||
|  |  | ||||||
| 	 |      | ||||||
|     def write_report(self): |     def write_report(self): | ||||||
| 	"output the selected statistics..." |         "output the selected statistics..." | ||||||
|  |  | ||||||
|         font = self.doc.style_list['SC-Text'].get_font() |         font = self.doc.style_list['SC-Text'].get_font() | ||||||
|  |  | ||||||
| 	# set layout variables |         # set layout variables | ||||||
| 	width = self.doc.get_usable_width() |         width = self.doc.get_usable_width() | ||||||
|         row_h = pt2cm(font.get_size()) |         row_h = pt2cm(font.get_size()) | ||||||
| 	max_y = self.doc.get_usable_height() - row_h |         max_y = self.doc.get_usable_height() - row_h | ||||||
|         pad =  row_h * 0.5 |         pad =  row_h * 0.5 | ||||||
|          |          | ||||||
| 	# calculate maximum key string size |         # calculate maximum key string size | ||||||
|         max_size = 0 |         max_size = 0 | ||||||
| 	max_value = 0 |         max_value = 0 | ||||||
|         for key in self.index: |         for key in self.index: | ||||||
|             max_size = max(self.doc.string_width(font, key), max_size) |             max_size = max(self.doc.string_width(font, key), max_size) | ||||||
| 	    max_value = max(self.items[key], max_value) |             max_value = max(self.items[key], max_value) | ||||||
| 	# horizontal area for the gfx bars |         # horizontal area for the gfx bars | ||||||
|         start = pt2cm(max_size) + 1.0 |         start = pt2cm(max_size) + 1.0 | ||||||
|         size = width - 1.5 - start |         size = width - 1.5 - start | ||||||
|  |  | ||||||
| 	# start page |         # start page | ||||||
|         self.doc.start_page() |         self.doc.start_page() | ||||||
|  |  | ||||||
| 	# start output |         # start output | ||||||
| 	self.doc.center_text('SC-title', self.title, width/2, 0) |         self.doc.center_text('SC-title', self.title, width/2, 0) | ||||||
| 	#print self.title |         #print self.title | ||||||
|  |  | ||||||
| 	yoffset = pt2cm(self.doc.style_list['SC-Title'].get_font().get_size()) |         yoffset = pt2cm(self.doc.style_list['SC-Title'].get_font().get_size()) | ||||||
| 	for key in self.index: |         for key in self.index: | ||||||
| 	    yoffset += (row_h + pad) |             yoffset += (row_h + pad) | ||||||
| 	    if yoffset > max_y: |             if yoffset > max_y: | ||||||
| 		# for graphical report, page_break() doesn't seem to work |             # for graphical report, page_break() doesn't seem to work | ||||||
| 		self.doc.end_page() |                 self.doc.end_page() | ||||||
| 		self.doc.start_page() |                 self.doc.start_page() | ||||||
| 		yoffset = 0 |                 yoffset = 0 | ||||||
|  |  | ||||||
| 	    # right align the text to the value |             # right align the text to the value | ||||||
| 	    x = start - pt2cm(self.doc.string_width(font, key)) - 1.0 |             x = start - pt2cm(self.doc.string_width(font, key)) - 1.0 | ||||||
|             self.doc.draw_text('SC-text', key, x, yoffset) |             self.doc.draw_text('SC-text', key, x, yoffset) | ||||||
| 	    #print key + ":", |             #print key + ":", | ||||||
| 	     |          | ||||||
| 	    value = self.items[key] |             value = self.items[key] | ||||||
| 	    stop = start + (size * value / max_value) |             stop = start + (size * value / max_value) | ||||||
| 	    path = ((start, yoffset), |             path = ((start, yoffset), | ||||||
| 		    (stop, yoffset), |                     (stop, yoffset), | ||||||
| 		    (stop, yoffset + row_h), |                     (stop, yoffset + row_h), | ||||||
| 		    (start, yoffset + row_h)) |                     (start, yoffset + row_h)) | ||||||
| 	    self.doc.draw_path('SC-bar', path) |             self.doc.draw_path('SC-bar', path) | ||||||
|             self.doc.draw_text('SC-text', str(value), stop + 0.5, yoffset) |             self.doc.draw_text('SC-text', str(value), stop + 0.5, yoffset) | ||||||
| 	    #print "%d/%d" % (value, max_value) |             #print "%d/%d" % (value, max_value) | ||||||
|              |              | ||||||
|         self.doc.end_page()     |         self.doc.end_page()     | ||||||
|  |  | ||||||
| 	return |         return | ||||||
|  |  | ||||||
|  |  | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
| @@ -429,39 +447,39 @@ class StatisticsChartOptions(ReportOptions.ReportOptions): | |||||||
|     Defines options and provides their handling interface. |     Defines options and provides their handling interface. | ||||||
|     """ |     """ | ||||||
|     _sorts = [ |     _sorts = [ | ||||||
|     	(_SORT_VALUE, _("Item count")), |         (_SORT_VALUE, _("Item count")), | ||||||
| 	(_SORT_KEY, _("Item name")) |         (_SORT_KEY, _("Item name")) | ||||||
|     ] |     ] | ||||||
|     _genders = [ |     _genders = [ | ||||||
|     	(RelLib.Person.unknown, _("Both")), |         (Person.unknown, _("Both")), | ||||||
| 	(RelLib.Person.male, _("Men")), |         (Person.male, _("Men")), | ||||||
| 	(RelLib.Person.female, _("Women")) |         (Person.female, _("Women")) | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     def __init__(self,name, person_id=None): |     def __init__(self,name, person_id=None): | ||||||
|         ReportOptions.ReportOptions.__init__(self, name, person_id) |         ReportOptions.ReportOptions.__init__(self, name, person_id) | ||||||
|  |  | ||||||
|     def set_new_options(self): |     def set_new_options(self): | ||||||
| 	# Options specific for this report |     # Options specific for this report | ||||||
|         self.options_dict = { |         self.options_dict = { | ||||||
|             'year_to'   : time.localtime()[0], |             'year_to'   : time.localtime()[0], | ||||||
|             'year_from' : 1700, |             'year_from' : 1700, | ||||||
| 	    'no_years'  : 0, |             'no_years'  : 0, | ||||||
| 	    'extract'   : 0, |             'extract'   : 0, | ||||||
| 	    'gender'    : 0, |             'gender'    : 0, | ||||||
| 	    'sort'      : _SORT_VALUE, |             'sort'      : _SORT_VALUE, | ||||||
| 	    'reverse'   : 0 |             'reverse'   : 0 | ||||||
|         } |         } | ||||||
|         self.options_help = { |         self.options_help = { | ||||||
|             'year_to'   : ("=num", _("Birth year until which to include people"), |             'year_to'   : ("=num", _("Birth year until which to include people"), | ||||||
| 	    			   _("smaller than %d") % self.options_dict['year_to']), |                                 _("smaller than %d") % self.options_dict['year_to']), | ||||||
|             'year_from' : ("=num", _("Birth year from which to include people"), |             'year_from' : ("=num", _("Birth year from which to include people"), | ||||||
| 	    			   _("earlier than 'year_to' value")), |                                 _("earlier than 'year_to' value")), | ||||||
| 	    'no_years'  : ("=num", _("Include people without birth years"), [_("No"), _("Yes")]), |             'no_years'  : ("=num", _("Include people without birth years"), [_("No"), _("Yes")]), | ||||||
| 	    'gender'    : ("=num", _('Genders included'), self._genders), |             'gender'    : ("=num", _('Genders included'), self._genders), | ||||||
| 	    'extract'   : ("=num", _('Data to show'), [item[0] for item in _Extract.extractors]), |             'extract'   : ("=num", _('Data to show'), [item[0] for item in _Extract.extractors]), | ||||||
| 	    'sort'      : ("=num", _('Sorted by'), self._sorts), |             'sort'      : ("=num", _('Sorted by'), self._sorts), | ||||||
| 	    'reverse'   : ("=num", _("Sort in reverse order"), [_("Yes"), _("No")]) |             'reverse'   : ("=num", _("Sort in reverse order"), [_("Yes"), _("No")]) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     def enable_options(self): |     def enable_options(self): | ||||||
| @@ -469,122 +487,126 @@ class StatisticsChartOptions(ReportOptions.ReportOptions): | |||||||
|         self.enable_dict = { |         self.enable_dict = { | ||||||
|             'filter'    : 0, |             'filter'    : 0, | ||||||
|         } |         } | ||||||
| 	 |      | ||||||
|     def make_default_style(self, default_style): |     def make_default_style(self, default_style): | ||||||
| 	"""Make the default output style for the Statistics report.""" |         """Make the default output style for the Statistics report.""" | ||||||
| 	f = BaseDoc.FontStyle() |         f = BaseDoc.FontStyle() | ||||||
| 	f.set_size(10) |         f.set_size(10) | ||||||
| 	f.set_type_face(BaseDoc.FONT_SERIF) |         f.set_type_face(BaseDoc.FONT_SERIF) | ||||||
| 	p = BaseDoc.ParagraphStyle() |         p = BaseDoc.ParagraphStyle() | ||||||
| 	p.set_font(f) |         p.set_font(f) | ||||||
| 	p.set_alignment(BaseDoc.PARA_ALIGN_RIGHT) |         p.set_alignment(BaseDoc.PARA_ALIGN_RIGHT) | ||||||
| 	p.set_description(_("The style used for the items and values.")) |         p.set_description(_("The style used for the items and values.")) | ||||||
| 	default_style.add_style("SC-Text",p) |         default_style.add_style("SC-Text",p) | ||||||
| 	 |  | ||||||
| 	f = BaseDoc.FontStyle() |         f = BaseDoc.FontStyle() | ||||||
| 	f.set_size(14) |         f.set_size(14) | ||||||
| 	f.set_type_face(BaseDoc.FONT_SANS_SERIF) |         f.set_type_face(BaseDoc.FONT_SANS_SERIF) | ||||||
| 	p = BaseDoc.ParagraphStyle() |         p = BaseDoc.ParagraphStyle() | ||||||
| 	p.set_font(f) |         p.set_font(f) | ||||||
| 	p.set_alignment(BaseDoc.PARA_ALIGN_CENTER) |         p.set_alignment(BaseDoc.PARA_ALIGN_CENTER) | ||||||
| 	p.set_description(_("The style used for the title of the page.")) |         p.set_description(_("The style used for the title of the page.")) | ||||||
| 	default_style.add_style("SC-Title",p) |         default_style.add_style("SC-Title",p) | ||||||
|  |  | ||||||
|     def get_report_filters(self, person): |     def get_report_filters(self, person): | ||||||
| 	"""Set up the list of possible content filters.""" |         """Set up the list of possible content filters.""" | ||||||
| 	 |      | ||||||
| 	name = person.getPrimaryName().getName() |         if person: | ||||||
| 	 |             name = person.get_primary_name().get_name() | ||||||
| 	all = GenericFilter.GenericFilter() |             handle = person.get_handle() | ||||||
| 	all.set_name(_("Entire Database")) |         else: | ||||||
| 	all.add_rule(GenericFilter.Everyone([])) |             name = 'PERSON' | ||||||
| 	 |             handle = '' | ||||||
| 	des = GenericFilter.GenericFilter() |      | ||||||
| 	des.set_name(_("Descendants of %s") % name) |         all = GenericFilter.GenericFilter() | ||||||
| 	des.add_rule(GenericFilter.IsDescendantOf([person.getId(), 1])) |         all.set_name(_("Entire Database")) | ||||||
| 	 |         all.add_rule(GenericFilter.Everyone([])) | ||||||
| 	ans = GenericFilter.GenericFilter() |  | ||||||
| 	ans.set_name(_("Ancestors of %s") % name) |         des = GenericFilter.GenericFilter() | ||||||
| 	ans.add_rule(GenericFilter.IsAncestorOf([person.getId(), 1])) |         des.set_name(_("Descendants of %s") % name) | ||||||
| 	 |         des.add_rule(GenericFilter.IsDescendantOf([handle, 1])) | ||||||
| 	com = GenericFilter.GenericFilter() |  | ||||||
| 	com.set_name(_("People with common ancestor with %s") % name) |         ans = GenericFilter.GenericFilter() | ||||||
| 	com.add_rule(GenericFilter.HasCommonAncestorWith([person.getId()])) |         ans.set_name(_("Ancestors of %s") % name) | ||||||
| 	 |         ans.add_rule(GenericFilter.IsAncestorOf([handle, 1])) | ||||||
| 	return [all, des, ans, com] |  | ||||||
|  |         com = GenericFilter.GenericFilter() | ||||||
|  |         com.set_name(_("People with common ancestor with %s") % name) | ||||||
|  |         com.add_rule(GenericFilter.HasCommonAncestorWith([handle])) | ||||||
|  |  | ||||||
|  |         return [all, des, ans, com] | ||||||
|  |  | ||||||
|     def add_user_options(self, dialog): |     def add_user_options(self, dialog): | ||||||
|         """ |         """ | ||||||
|         Override the base class add_user_options task to add |         Override the base class add_user_options task to add | ||||||
| 	report specific options |         report specific options | ||||||
|         """ |         """ | ||||||
| 	# what data to extract from database |         # what data to extract from database | ||||||
|         self.extract_menu = gtk.Menu() |         self.extract_menu = gtk.Menu() | ||||||
| 	idx = 0 |         idx = 0 | ||||||
| 	for item in _Extract.extractors: |         for item in _Extract.extractors: | ||||||
|             menuitem = gtk.MenuItem(item[0]) |             menuitem = gtk.MenuItem(item[0]) | ||||||
|             menuitem.set_data('extract', idx) |             menuitem.set_data('extract', idx) | ||||||
|             self.extract_menu.append(menuitem) |             self.extract_menu.append(menuitem) | ||||||
| 	    idx += 1 |             idx += 1 | ||||||
| 	self.extract_menu.show_all() |         self.extract_menu.show_all() | ||||||
|  |  | ||||||
| 	tip = _("Select which data is collected and which statistics is shown.") |         tip = _("Select which data is collected and which statistics is shown.") | ||||||
| 	extract_style = gtk.OptionMenu() |         extract_style = gtk.OptionMenu() | ||||||
|         extract_style.set_menu(self.extract_menu) |         extract_style.set_menu(self.extract_menu) | ||||||
|         dialog.add_option(self.options_help['extract'][1], extract_style, tip) |         dialog.add_option(self.options_help['extract'][1], extract_style, tip) | ||||||
|  |  | ||||||
| 	# how to sort the data |         # how to sort the data | ||||||
|         self.sort_menu = gtk.Menu() |         self.sort_menu = gtk.Menu() | ||||||
| 	for item in self._sorts: |         for item in self._sorts: | ||||||
|             menuitem = gtk.MenuItem(item[1]) |             menuitem = gtk.MenuItem(item[1]) | ||||||
|             menuitem.set_data('sort', item[0]) |             menuitem.set_data('sort', item[0]) | ||||||
|             self.sort_menu.append(menuitem) |             self.sort_menu.append(menuitem) | ||||||
| 	self.sort_menu.show_all() |         self.sort_menu.show_all() | ||||||
|  |  | ||||||
| 	tip = _("Select how the statistical data is sorted.") |         tip = _("Select how the statistical data is sorted.") | ||||||
| 	sort_style = gtk.OptionMenu() |         sort_style = gtk.OptionMenu() | ||||||
|         sort_style.set_menu(self.sort_menu) |         sort_style.set_menu(self.sort_menu) | ||||||
|         dialog.add_option(self.options_help['sort'][1], sort_style, tip) |         dialog.add_option(self.options_help['sort'][1], sort_style, tip) | ||||||
|  |  | ||||||
| 	# sorting order |         # sorting order | ||||||
| 	tip = _("Check to reverse the sorting order.") |         tip = _("Check to reverse the sorting order.") | ||||||
|         self.reverse = gtk.CheckButton(self.options_help['reverse'][1]) |         self.reverse = gtk.CheckButton(self.options_help['reverse'][1]) | ||||||
|         self.reverse.set_active(0) |         self.reverse.set_active(0) | ||||||
|         dialog.add_option(None, self.reverse, tip) |         dialog.add_option(None, self.reverse, tip) | ||||||
|         self.reverse.show() |         self.reverse.show() | ||||||
|  |  | ||||||
| 	# year range |         # year range | ||||||
|         self.from_box = gtk.Entry(4) |         self.from_box = gtk.Entry(4) | ||||||
|         self.from_box.set_text(str(self.options_dict['year_from'])) |         self.from_box.set_text(str(self.options_dict['year_from'])) | ||||||
|         self.to_box = gtk.Entry(4) |         self.to_box = gtk.Entry(4) | ||||||
|         self.to_box.set_text(str(self.options_dict['year_to'])) |         self.to_box.set_text(str(self.options_dict['year_to'])) | ||||||
|  |  | ||||||
| 	box = gtk.HBox() |         box = gtk.HBox() | ||||||
| 	box.add(self.from_box) |         box.add(self.from_box) | ||||||
| 	box.add(gtk.Label("-")) |         box.add(gtk.Label("-")) | ||||||
| 	box.add(self.to_box) |         box.add(self.to_box) | ||||||
| 	tip = _("Select year range within which people need to be born to be selected for statistics.") |         tip = _("Select year range within which people need to be born to be selected for statistics.") | ||||||
|         dialog.add_option(_('People born between'), box, tip) |         dialog.add_option(_('People born between'), box, tip) | ||||||
|         box.show_all() |         box.show_all() | ||||||
|  |  | ||||||
| 	# include people without birth year? |         # include people without birth year? | ||||||
| 	tip = _("Check this if you want people who have no birth date or year to be accounted also in the statistics.") |         tip = _("Check this if you want people who have no birth date or year to be accounted also in the statistics.") | ||||||
|         self.no_years = gtk.CheckButton(self.options_help['no_years'][1]) |         self.no_years = gtk.CheckButton(self.options_help['no_years'][1]) | ||||||
|         self.no_years.set_active(0) |         self.no_years.set_active(0) | ||||||
|         dialog.add_option(None, self.no_years, tip) |         dialog.add_option(None, self.no_years, tip) | ||||||
|         self.no_years.show() |         self.no_years.show() | ||||||
|  |  | ||||||
| 	# gender selection |         # gender selection | ||||||
| 	Person = RelLib.Person |  | ||||||
|         self.gender_menu = gtk.Menu() |         self.gender_menu = gtk.Menu() | ||||||
| 	for item in self._genders: |         for item in self._genders: | ||||||
|             menuitem = gtk.MenuItem(item[1]) |             menuitem = gtk.MenuItem(item[1]) | ||||||
|             menuitem.set_data('gender', item[0]) |             menuitem.set_data('gender', item[0]) | ||||||
|             self.gender_menu.append(menuitem) |             self.gender_menu.append(menuitem) | ||||||
| 	self.gender_menu.show_all() |         self.gender_menu.show_all() | ||||||
|  |  | ||||||
| 	tip = _("Select which genders are included into statistics.") |         tip = _("Select which genders are included into statistics.") | ||||||
| 	genders = gtk.OptionMenu() |         genders = gtk.OptionMenu() | ||||||
|         genders.set_menu(self.gender_menu) |         genders.set_menu(self.gender_menu) | ||||||
|         dialog.add_option(self.options_help['gender'][1], genders, tip) |         dialog.add_option(self.options_help['gender'][1], genders, tip) | ||||||
|  |  | ||||||
| @@ -592,13 +614,13 @@ class StatisticsChartOptions(ReportOptions.ReportOptions): | |||||||
|         """ |         """ | ||||||
|         Parses the custom options that we have added. |         Parses the custom options that we have added. | ||||||
|         """ |         """ | ||||||
| 	self.options_dict['year_to'] = int(self.to_box.get_text()) |         self.options_dict['year_to'] = int(self.to_box.get_text()) | ||||||
|         self.options_dict['year_from'] = int(self.from_box.get_text()) |         self.options_dict['year_from'] = int(self.from_box.get_text()) | ||||||
| 	self.options_dict['no_years'] = self.no_years.get_active() |         self.options_dict['no_years'] = int(self.no_years.get_active()) | ||||||
|         self.options_dict['gender'] = self.gender_menu.get_active().get_data('gender') |         self.options_dict['gender'] = self.gender_menu.get_active().get_data('gender') | ||||||
|         self.options_dict['extract'] = self.extract_menu.get_active().get_data('extract') |         self.options_dict['extract'] = self.extract_menu.get_active().get_data('extract') | ||||||
| 	self.options_dict['sort'] = self.sort_menu.get_active().get_data('sort') |         self.options_dict['sort'] = self.sort_menu.get_active().get_data('sort') | ||||||
| 	self.options_dict['reverse'] = self.reverse.get_active() |         self.options_dict['reverse'] = int(self.reverse.get_active()) | ||||||
|  |  | ||||||
|  |  | ||||||
| #------------------------------------------------------------------------ | #------------------------------------------------------------------------ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user