6
6
# Copyright (C) 2009 Gary Burton
7
7
# Copyright (C) 2010 Craig J. Anderson
8
8
# Copyright (C) 2010 Jakim Friant
9
# Copyright (C) 2011 Matt Keenan (matt.keenan@gmail.com)
10
11
# This program is free software; you can redistribute it and/or modify
11
12
# it under the terms of the GNU General Public License as published by
22
23
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
# $Id: DescendReport.py 16979 2011-03-30 01:50:08Z pez4brian $
26
# $Id: DescendReport.py 18915 2012-02-17 16:51:40Z romjerome $
28
29
Reports/Text Reports/Descendant Report.
42
44
#------------------------------------------------------------------------
43
45
from gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle,
44
46
FONT_SANS_SERIF, INDEX_TYPE_TOC, PARA_ALIGN_CENTER)
45
from gen.plug.menu import NumberOption, PersonOption, BooleanOption, EnumeratedListOption
46
from gen.display.name import displayer as _nd
47
from gen.plug.menu import (NumberOption, PersonOption, BooleanOption,
49
from gen.display.name import displayer as global_name_display
47
50
from Errors import ReportError
48
51
from gen.plug.report import Report
49
52
from gen.plug.report import utils as ReportUtils
50
from gui.plug.report import MenuReportOptions
53
from gen.plug.report import MenuReportOptions
53
56
from gen.utils import (get_birth_or_fallback, get_death_or_fallback,
62
65
#------------------------------------------------------------------------
63
66
class PrintSimple():
67
def __init__(self, showdups):
68
self.showdups = showdups
64
71
def number(self, level):
73
# Just show original simple numbering
74
to_return = "%d." % level
76
to_return = str(level)
78
to_return += "-" + str(self.num[level-1])
82
self.num[level-1] = self.num[level-1] + 1
68
87
#------------------------------------------------------------------------
125
144
A base class used to help make the individual numbering system classes.
126
145
This class must first be initialized with set_class_vars
128
def __init__(self, doc, database, numbering, showmarriage, showdivorce):
147
def __init__(self, doc, database, numbering, showmarriage, showdivorce,\
150
self._name_display = name_display
131
152
self.database = database
132
153
self.numbering = numbering
184
205
display_num = self.numbering.number(level)
185
206
self.doc.start_paragraph("DR-Level%d" % min(level, 32), display_num)
186
207
mark = ReportUtils.get_person_mark(self.database, person)
187
self.doc.write_text(_nd.display(person), mark)
208
self.doc.write_text(self._name_display.display(person), mark)
188
209
self.dump_string(person)
189
210
self.doc.end_paragraph()
191
213
def print_spouse(self, level, spouse_handle, family_handle):
192
214
#Currently print_spouses is the same for all numbering systems.
194
216
spouse = self.database.get_person_from_handle(spouse_handle)
195
217
mark = ReportUtils.get_person_mark(self.database, spouse)
196
218
self.doc.start_paragraph("DR-Spouse%d" % min(level, 32))
197
name = _nd.display(spouse)
219
name = self._name_display.display(spouse)
198
220
self.doc.write_text(_("sp. %(spouse)s") % {'spouse':name}, mark)
199
221
self.dump_string(spouse, family_handle)
200
222
self.doc.end_paragraph()
224
self.doc.start_paragraph("DR-Spouse%d" % min(level, 32))
225
self.doc.write_text(_("sp. %(spouse)s") % {'spouse':'Unknown'})
226
self.doc.end_paragraph()
228
def print_reference(self, level, person, display_num):
229
#Person and their family have already been printed so
230
#print reference here
232
mark = ReportUtils.get_person_mark(self.database, person)
233
self.doc.start_paragraph("DR-Spouse%d" % min(level, 32))
234
name = self._name_display.display(person)
235
self.doc.write_text(_("sp. see %(reference)s : %(spouse)s") %
236
{'reference':display_num, 'spouse':name}, mark)
237
self.doc.end_paragraph()
203
240
#------------------------------------------------------------------------
216
253
objPrint: A Printinfo derived class that prints person
217
254
information on the report
219
def __init__(self, max_generations, database, objPrint):
256
def __init__(self, max_generations, database, objPrint, showdups):
220
257
self.max_generations = max_generations
221
258
self.database = database
222
259
self.objPrint = objPrint
260
self.showdups = showdups
261
self.person_printed = {}
224
def recurse(self, level, person):
226
self.objPrint.print_person(level, person)
263
def recurse(self, level, person, curdepth):
265
person_handle = person.get_handle()
266
display_num = self.objPrint.print_person(level, person)
269
ref_str = display_num
271
ref_str = curdepth + " " + display_num
273
if person_handle not in self.person_printed:
274
self.person_printed[person_handle] = ref_str
228
276
for family_handle in person.get_family_handle_list():
229
277
family = self.database.get_family_from_handle(family_handle)
231
279
spouse_handle = ReportUtils.find_spouse(person, family)
232
self.objPrint.print_spouse(level, spouse_handle, family)
234
if level >= self.max_generations:
237
childlist = family.get_child_ref_list()[:]
238
for child_ref in childlist:
239
child = self.database.get_person_from_handle(child_ref.ref)
240
self.recurse(level+1, child)
281
if not self.showdups and spouse_handle in self.person_printed:
282
# Just print a reference
283
spouse = self.database.get_person_from_handle(spouse_handle)
284
self.objPrint.print_reference(level, spouse,
285
self.person_printed[person_handle])
287
self.objPrint.print_spouse(level, spouse_handle, family)
290
spouse_num = _("%s sp." % (ref_str))
291
self.person_printed[spouse_handle] = spouse_num
293
if level >= self.max_generations:
296
childlist = family.get_child_ref_list()[:]
297
for child_ref in childlist:
298
child = self.database.get_person_from_handle(child_ref.ref)
299
self.recurse(level+1, child, ref_str)
243
302
#------------------------------------------------------------------------
247
306
#------------------------------------------------------------------------
248
307
class DescendantReport(Report):
250
def __init__(self, database, options_class):
309
def __init__(self, database, options, user):
252
311
Create the DescendantReport object that produces the report.
254
313
The arguments are:
256
315
database - the GRAMPS database instance
257
options_class - instance of the Options class for this report
316
options - instance of the Options class for this report
317
user - a gen.user.User() instance
259
319
This report needs the following parameters (class variables)
260
320
that come in the options class.
262
322
gen - Maximum number of generations to include.
323
name_format - Preferred format to display names
324
dups - Whether to include duplicate descendant trees
265
Report.__init__(self, database, options_class)
327
Report.__init__(self, database, options, user)
267
menu = options_class.menu
268
330
self.max_generations = menu.get_option_by_name('gen').get_value()
269
331
pid = menu.get_option_by_name('pid').get_value()
270
332
self.center_person = database.get_person_from_gramps_id(pid)
275
337
self.by_birthdate = sort.by_birthdate
277
339
#Initialize the Printinfo class
340
self._showdups = menu.get_option_by_name('dups').get_value()
278
341
numbering = menu.get_option_by_name('numbering').get_value()
279
342
if numbering == "Simple":
343
obj = PrintSimple(self._showdups)
281
344
elif numbering == "de Villiers/Pama":
282
345
obj = PrintVilliers()
283
346
elif numbering == "Meurgey de Tupigny":
288
351
marrs = menu.get_option_by_name('marrs').get_value()
289
352
divs = menu.get_option_by_name('divs').get_value()
291
self.objPrint = Printinfo(self.doc, database, obj, marrs, divs)
354
# Copy the global NameDisplay so that we don't change application defaults.
355
self._name_display = copy.deepcopy(global_name_display)
356
name_format = menu.get_option_by_name("name_format").get_value()
358
self._name_display.set_default_format(name_format)
360
self.objPrint = Printinfo(self.doc, database, obj, marrs, divs,
293
363
def write_report(self):
294
364
self.doc.start_paragraph("DR-Title")
295
name = _nd.display(self.center_person)
365
name = self._name_display.display(self.center_person)
366
# feature request 2356: avoid genitive form
296
367
title = _("Descendants of %s") % name
297
368
mark = IndexMark(title, INDEX_TYPE_TOC, 1)
298
369
self.doc.write_text(title, mark)
299
370
self.doc.end_paragraph()
301
recurse = RecurseDown(self.max_generations, self.database, self.objPrint)
302
recurse.recurse(1, self.center_person)
372
recurse = RecurseDown(self.max_generations, self.database,
373
self.objPrint, self._showdups)
374
recurse.recurse(1, self.center_person, None)
304
376
#------------------------------------------------------------------------
308
380
#------------------------------------------------------------------------
309
381
class DescendantOptions(MenuReportOptions):
322
394
pid.set_help(_("The center person for the report"))
323
395
menu.add_option(category_name, "pid", pid)
397
# We must figure out the value of the first option before we can
398
# create the EnumeratedListOption
399
fmt_list = global_name_display.get_name_format()
400
name_format = EnumeratedListOption(_("Name format"), 0)
401
name_format.add_item(0, _("Default"))
402
for num, name, fmt_str, act in fmt_list:
403
name_format.add_item(num, name)
404
name_format.set_help(_("Select the format to display names"))
405
menu.add_option(category_name, "name_format", name_format)
325
407
numbering = EnumeratedListOption(_("Numbering system"), "Simple")
326
408
numbering.set_items([
327
409
("Simple", _("Simple numbering")),
342
424
divs.set_help(_("Whether to show divorce information in the report."))
343
425
menu.add_option(category_name, "divs", divs)
427
dups = BooleanOption(_('Show duplicate trees'), True)
428
dups.set_help(_("Whether to show duplicate family trees in the report."))
429
menu.add_option(category_name, "dups", dups)
345
431
def make_default_style(self, default_style):
346
432
"""Make the default output style for the Descendant Report."""